Linux如何調試內存泄漏

內存泄漏是指由于疏忽或錯誤造成程序未能釋放已經(jīng)不再使用的內存秧了。內存泄漏并非指內存在物理上的消失具垫,而是應用程序分配某段內存后侣诵,由于設計錯誤殴穴,導致在釋放該段內存之前就失去了對該段內存的控制,從而造成了內存的浪費淮韭。

我們平時開發(fā)過程中不可避免的會遇到內存泄漏問題垢粮,你是如何排查的呢?估計你是使用下面這幾個工具吧靠粪?

  • valgrind
  • mtrace
  • dmalloc
  • ccmalloc
  • memwatch
  • debug_new

這里程序喵向大家推薦新的一個排查內存泄漏的工具:AddressSanitizer(ASan)蜡吧,該工具為gcc自帶毫蚓,4.8以上版本都可以使用,支持Linux昔善、OS元潘、Android等多種平臺,不止可以檢測內存泄漏君仆,它其實是一個內存錯誤檢測工具柬批,可以檢測的問題有:

  • 內存泄漏
  • 堆棧和全局內存越界訪問
  • free后繼續(xù)使用
  • 局部內存被外層使用
  • Initialization order bugs(中文不知道怎么翻譯才好,后面有代碼舉例袖订,重要)

使用方法直接看我下面的代碼:

檢測內存泄漏

內存泄漏代碼:

#include <stdlib.h>

void func1() { malloc(7); }

void func2() { malloc(5); }

int main() {
    func1();
    func2();
    return 0;
}

編譯and輸出:

g++ -fsanitize=address -g test_leak.cc && ./a.out

=================================================================
==103==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 7 byte(s) in 1 object(s) allocated from:
    #0 0x7f95b231eb40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40)
    #1 0x7f95b36007f7 in func1() /home/wangzhiqiang/test/test_leak.cc:3
    #2 0x7f95b3600814 in main /home/wangzhiqiang/test/test_leak.cc:8
    #3 0x7f95b1e61b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

Direct leak of 5 byte(s) in 1 object(s) allocated from:
    #0 0x7f95b231eb40 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb40)
    #1 0x7f95b3600808 in func2() /home/wangzhiqiang/test/test_leak.cc:5
    #2 0x7f95b3600819 in main /home/wangzhiqiang/test/test_leak.cc:9
    #3 0x7f95b1e61b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

SUMMARY: AddressSanitizer: 12 byte(s) leaked in 2 allocation(s).

編譯方式很簡單氮帐,只需要添加-fsanitize=address -g就可以檢測出具體產(chǎn)生內存泄漏的位置以及泄漏空間的大小。

檢測堆棧內存越界訪問

示例:

#include <iostream>

int main() {
    int *array = new int[100];
    array[0] = 0;
    int res = array[100];  // out of bounds
    delete[] array;
    return res;
}

編譯and輸出:

g++ -fsanitize=address -g test_leak.cc && ./a.out
    
=================================================================
==110==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6140000001d0 at pc 0x7f0e06400d2e bp 0x7ffff5963f10 sp 0x7ffff5963f00
READ of size 4 at 0x6140000001d0 thread T0
    #0 0x7f0e06400d2d in main /home/wangzhiqiang/test/test_leak.cc:6
    #1 0x7f0e048d1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #2 0x7f0e06400bb9 in _start (/mnt/d/wzq/wzq/util/test/a.out+0xbb9)

0x6140000001d0 is located 0 bytes to the right of 400-byte region [0x614000000040,0x6140000001d0)
allocated by thread T0 here:
    #0 0x7f0e05120608 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0608)
    #1 0x7f0e06400cab in main /home/wangzhiqiang/test/test_leak.cc:4
    #2 0x7f0e048d1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/wangzhiqiang/test/test_leak.cc:6 in main
Shadow bytes around the buggy address:
  0x0c287fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff8000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c287fff8010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff8020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c287fff8030: 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa
  0x0c287fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c287fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c287fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c287fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c287fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==110==ABORTING

可以方便定位到堆棧內存越界訪問的錯誤洛姑。

全局內存越界訪問

示例:

#include <iostream>

int global_array[100] = {0};

int main() {
    int res = global_array[100];  // out of bounds
    return 0;
}

編譯and輸出:

g++ -fsanitize=address -g test_leak.cc && ./a.out
=================================================================
==116==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7f42e6e02310 at pc 0x7f42e6c00c84 bp 0x7fffdda52780 sp 0x7fffdda52770
READ of size 4 at 0x7f42e6e02310 thread T0
    #0 0x7f42e6c00c83 in main /home/wangzhiqiang/test/test_leak.cc:6
    #1 0x7f42e50d1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #2 0x7f42e6c00b69 in _start (/mnt/d/wzq/wzq/util/test/a.out+0xb69)

0x7f42e6e02310 is located 0 bytes to the right of global variable 'global_array' defined in 'test_leak.cc:3:5' (0x7f42e6e02180) of size 400
SUMMARY: AddressSanitizer: global-buffer-overflow /home/wangzhiqiang/test/test_leak.cc:6 in main
Shadow bytes around the buggy address:
  0x0fe8dcdb8410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe8dcdb8420: 00 00 00 00 00 00 00 00 01 f9 f9 f9 f9 f9 f9 f9
  0x0fe8dcdb8430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe8dcdb8440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe8dcdb8450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0fe8dcdb8460: 00 00[f9]f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
  0x0fe8dcdb8470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe8dcdb8480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe8dcdb8490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe8dcdb84a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe8dcdb84b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==116==ABORTING

局部內存被外層使用

示例:

#include <iostream>

volatile int *p = 0;

int main() {
  {
    int x = 0;
    p = &x;
  }
  *p = 5;
  return 0;
}

編譯and輸出:

g++ -fsanitize=address -g test_leak.cc && ./a.out
=================================================================
==243==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7fffce12a4b0 at pc 0x7f3993e00e7e bp 0x7fffce12a480 sp 0x7fffce12a470
WRITE of size 4 at 0x7fffce12a4b0 thread T0
    #0 0x7f3993e00e7d in main /home/wangzhiqiang/test/test_leak.cc:10
    #1 0x7f39922d1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #2 0x7f3993e00c89 in _start (/mnt/d/wzq/wzq/util/test/a.out+0xc89)

Address 0x7fffce12a4b0 is located in stack of thread T0 at offset 32 in frame
    #0 0x7f3993e00d79 in main /home/wangzhiqiang/test/test_leak.cc:5

  This frame has 1 object(s):
    [32, 36) 'x' <== Memory access at offset 32 is inside this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-scope /home/wangzhiqiang/test/test_leak.cc:10 in main
Shadow bytes around the buggy address:
  0x100079c1d440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079c1d450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079c1d460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079c1d470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079c1d480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x100079c1d490: 00 00 f1 f1 f1 f1[f8]f2 f2 f2 00 00 00 00 00 00
  0x100079c1d4a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079c1d4b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079c1d4c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079c1d4d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x100079c1d4e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==243==ABORTING

free后被使用

示例:

#include <iostream>

int main() {
    int *array = new int[100];
    delete[] array;
    int a = array[0];  // error
    return 0;
}

編譯and輸出:

g++ -fsanitize=address -g test_leak.cc && ./a.out
=================================================================
==282==ERROR: AddressSanitizer: heap-use-after-free on address 0x614000000040 at pc 0x7f209fa00caa bp 0x7ffff2a15020 sp 0x7ffff2a15010
READ of size 4 at 0x614000000040 thread T0
    #0 0x7f209fa00ca9 in main /home/wangzhiqiang/test/test_leak.cc:6
    #1 0x7f209ded1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #2 0x7f209fa00b69 in _start (/mnt/d/wzq/wzq/util/test/a.out+0xb69)

0x614000000040 is located 0 bytes inside of 400-byte region [0x614000000040,0x6140000001d0)
freed by thread T0 here:
    #0 0x7f209e721480 in operator delete[](void*) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe1480)
    #1 0x7f209fa00c72 in main /home/wangzhiqiang/test/test_leak.cc:5
    #2 0x7f209ded1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

previously allocated by thread T0 here:
    #0 0x7f209e720608 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0608)
    #1 0x7f209fa00c5b in main /home/wangzhiqiang/test/test_leak.cc:4
    #2 0x7f209ded1b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

SUMMARY: AddressSanitizer: heap-use-after-free /home/wangzhiqiang/test/test_leak.cc:6 in main
Shadow bytes around the buggy address:
  0x0c287fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c287fff8000: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd
  0x0c287fff8010: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c287fff8020: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c287fff8030: fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa fa
  0x0c287fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c287fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==282==ABORTING

Initialization order bugs

示例上沐,這里有兩個文件:

// test_memory1.cc
#include <stdio.h>

extern int extern_global;
int read_extern_global() { return extern_global; }

int x = read_extern_global() + 1;

int main() {
    printf("%d\n", x);
    return 0;
}
// test_memory2.cc

int foo() { return 123; }
int extern_global = foo();

第一種編譯方式輸出如下:

g++ test_memory1.cc test_memory2.cc && ./a.out
1

第二種編譯方式輸出如下:

g++ test_memory2.cc test_memory1.cc && ./a.out
124

這種問題我們平時編程過程中可以都不會太注意,然而通過ASan可以檢測出這種潛在的bug:

編譯and輸出:

g++ -fsanitize=address -g test_memory1.cc test_memory2.cc

ASAN_OPTIONS=check_initialization_order=true:strict_init_order=true ./a.out
=================================================================
==419==ERROR: AddressSanitizer: initialization-order-fiasco on address 0x7f46c20021a0 at pc 0x7f46c1e00c28 bp 0x7fffe423d920 sp 0x7fffe423d910
READ of size 4 at 0x7f46c20021a0 thread T0
    #0 0x7f46c1e00c27 in read_extern_global() /home/wangzhiqiang/test/test_memory1.cc:3
    #1 0x7f46c1e00cb3 in __static_initialization_and_destruction_0 /home/wangzhiqiang/test/test_memory1.cc:4
    #2 0x7f46c1e00d0a in _GLOBAL__sub_I__Z18read_extern_globalv /home/wangzhiqiang/test/test_memory1.cc:8
    #3 0x7f46c1e00e5c in __libc_csu_init (/mnt/d/wzq/wzq/util/test/a.out+0xe5c)
    #4 0x7f46c0461b27 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b27)
    #5 0x7f46c1e00b09 in _start (/mnt/d/wzq/wzq/util/test/a.out+0xb09)

0x7f46c20021a0 is located 0 bytes inside of global variable 'extern_global' defined in 'test_memory2.cc:2:5' (0x7f46c20021a0) of size 4
  registered at:
    #0 0x7f46c08764a8  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x364a8)
    #1 0x7f46c1e00e0b in _GLOBAL__sub_I_00099_1__Z3foov (/mnt/d/wzq/wzq/util/test/a.out+0xe0b)
    #2 0x7f46c1e00e5c in __libc_csu_init (/mnt/d/wzq/wzq/util/test/a.out+0xe5c)

SUMMARY: AddressSanitizer: initialization-order-fiasco /home/wangzhiqiang/test/test_memory1.cc:3 in read_extern_global()
Shadow bytes around the buggy address:
  0x0fe9583f83e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe9583f83f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe9583f8400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe9583f8410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe9583f8420: 00 00 00 00 00 00 00 00 04 f9 f9 f9 f9 f9 f9 f9
=>0x0fe9583f8430: 00 00 00 00[f6]f6 f6 f6 f6 f6 f6 f6 00 00 00 00
  0x0fe9583f8440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe9583f8450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe9583f8460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe9583f8470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0fe9583f8480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==419==ABORTING

注意:這里在運行程序前需要添加環(huán)境變量:

ASAN_OPTIONS=check_initialization_order=true:strict_init_order=true

小總結

ASan是個很好的檢測內存問題的工具楞艾,不需要配置環(huán)境参咙,使用還方便,編譯時只需要-fsanitize=address -g就可以硫眯,運行程序時候可以選擇添加對應的ASAN_OPTIONS環(huán)境變量就可以檢測出很多內存問題蕴侧。它的錯誤信息也很有用,明確指出當前是什么類型的內存錯誤两入,如:

  • detected memory leaks
  • heap-buffer-overflow
  • stack-buffer-overflow
  • global-buffer-overflow
  • heap-use-after-free
  • initialization-order-fiasco

具體可以看google的官方文檔:https://github.com/google/sanitizers/wiki/AddressSanitizer
更多文章净宵,請關注我的V X 公 主 號:程序喵大人,歡迎交流裹纳。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末择葡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子剃氧,更是在濱河造成了極大的恐慌敏储,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朋鞍,死亡現(xiàn)場離奇詭異已添,居然都是意外死亡,警方通過查閱死者的電腦和手機滥酥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門更舞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人恨狈,你說我怎么就攤上這事疏哗∏航玻” “怎么了禾怠?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵返奉,是天一觀的道長。 經(jīng)常有香客問我吗氏,道長芽偏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任弦讽,我火速辦了婚禮污尉,結果婚禮上,老公的妹妹穿的比我還像新娘往产。我一直安慰自己被碗,他們只是感情好,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布仿村。 她就那樣靜靜地躺著锐朴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蔼囊。 梳的紋絲不亂的頭發(fā)上焚志,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音畏鼓,去河邊找鬼酱酬。 笑死,一個胖子當著我的面吹牛云矫,可吹牛的內容都是我干的膳沽。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼让禀,長吁一口氣:“原來是場噩夢啊……” “哼贵少!你這毒婦竟也來了?” 一聲冷哼從身側響起堆缘,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤滔灶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后吼肥,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體录平,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年缀皱,在試婚紗的時候發(fā)現(xiàn)自己被綠了斗这。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡啤斗,死狀恐怖表箭,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情钮莲,我是刑警寧澤免钻,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布彼水,位于F島的核電站,受9級特大地震影響极舔,放射性物質發(fā)生泄漏凤覆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一拆魏、第九天 我趴在偏房一處隱蔽的房頂上張望盯桦。 院中可真熱鬧,春花似錦渤刃、人聲如沸拥峦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽事镣。三九已至,卻和暖如春揪胃,著一層夾襖步出監(jiān)牢的瞬間璃哟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工喊递, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留随闪,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓骚勘,卻偏偏與公主長得像铐伴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子俏讹,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348