linux kernel 內(nèi)存管理-頁錯誤異常處理

在取指令或者數(shù)據(jù)的時候,處理器的MMU單元需要把虛擬地址轉(zhuǎn)換成物理地址漓滔。如果虛擬頁沒有映射到物理頁编饺,或者沒有訪問權(quán)限,處理器將生成頁錯誤異常响驴。
缺頁異常透且,虛擬頁沒有映射到物理頁,有以下幾種情況:
(1)訪問用戶棧的時候豁鲤,超出了當(dāng)前用戶棧的范圍秽誊,需要擴(kuò)大用戶棧。
(2)當(dāng)進(jìn)程申請?zhí)摂M內(nèi)區(qū)域的時候琳骡,通常是沒有分配物理頁锅论,進(jìn)程第一次訪問的時候觸發(fā)頁錯誤異常。
(3)內(nèi)存不足的時候楣号,內(nèi)核把進(jìn)程的匿名頁換出到交換區(qū)最易。
(4)一個文件頁被映射到進(jìn)程的虛擬地址空間,內(nèi)存不足的時候炫狱,內(nèi)核回收這個文件頁藻懒,在進(jìn)程的頁表中刪除這個文件頁的映射。
(5)程序錯誤视译,訪問沒有分配給進(jìn)程的虛擬內(nèi)存區(qū)域嬉荆。
針對前四種情況,如果頁錯誤異常處理程序成功地把虛擬頁映射到物理頁酷含,處理程序返回后鄙早,處理器重新執(zhí)行觸發(fā)異常的指令。第五種異常椅亚,發(fā)送段違法信號(SIGSEGV)殺死進(jìn)程限番。

沒有訪問權(quán)限,有以下兩種情況:
(1)可能是軟件有意造成的什往,典型的例子是寫時復(fù)制:進(jìn)程分叉成子進(jìn)程的時候扳缕,為了避免復(fù)制物理頁,子進(jìn)程和父進(jìn)程以只讀的方式共享所有私有的匿名頁和文件頁别威。當(dāng)其中一個進(jìn)程試圖寫只讀頁時躯舔,觸發(fā)頁錯誤異常 ,頁錯誤異常處理程序分配新的物理頁省古,把舊的物理頁的數(shù)據(jù)復(fù)制到新的物理頁粥庄,然后把虛擬頁映射到新的物理頁。
(2)程序錯誤豺妓,例如試圖寫只讀的代碼段所在的物理頁惜互。
第一種情況布讹,如果頁錯誤異常處理程序成功地把虛擬頁映射到物理頁,處理程序返回后训堆,處理器重新執(zhí)行觸發(fā)異常的指令描验。第二種情況,頁錯誤異常處理程序?qū)l(fā)送段違法(SIGSEGV)信號殺死進(jìn)程坑鱼。

不同處理器架構(gòu)實現(xiàn)的頁錯誤異常不同膘流,頁錯誤異常處理程序的前面一部分是各種處理器架構(gòu)自定義的部分,后面從函數(shù)handle_mm_fault開始的部分是所有處理器架構(gòu)共用的部分鲁沥。

1 處理器架構(gòu)特定部分

1.1 處理頁異常錯誤

ARM64架構(gòu)的內(nèi)核定義了一個異常向量表呼股,起始地址是vectors(arch/arm64/kernel/entry.S),每個異常向量的長度是128字節(jié)画恰,但是在Linux內(nèi)核的每個異常向量只有一條指令:跳轉(zhuǎn)到對應(yīng)的處理器程序彭谁。異常向量表的虛擬地址存放在異常級別1的向量基準(zhǔn)地址寄存器VBAR_EL1中
處理器生成頁錯誤異常允扇,頁錯誤異常屬于同步異常缠局,處理器立即處理,從向量基準(zhǔn)地址寄存器得到異常向量表的虛擬地址考润,然后根據(jù)異常類型選擇對應(yīng)的異常向量甩鳄。
(1)如果異常類型是異常級別1生成的同步異常,異常向量的偏移是0x200额划,跳轉(zhuǎn)到函數(shù)el1_sync
(2)如果異常類型是異常級別0的64bit用戶態(tài)程序生成的同步異常档泽,異常向量的偏移是0x400俊戳,跳轉(zhuǎn)到el0_sync
(3)如果異常類型是異常級別0的32bit用戶態(tài)程序生成的同步異常馆匿,異常向量的偏移是0x600抑胎,跳轉(zhuǎn)到el0_sync_compat
以el0_sync為例渐北,函數(shù)el0_sync根據(jù)異常級別1的異常癥狀寄存器的異常類別字段處理阿逃。
(1)如果異常類型是異常級別0生成的數(shù)據(jù)中止,即在異常級別0訪問數(shù)據(jù)時生成頁錯誤異常赃蛛,那么調(diào)用函數(shù)el0_da恃锉。
(2)如果異常類型是異常級別0生成的指令中止,即在異常級別0取指令時生成頁錯誤異常呕臂,那么調(diào)用函數(shù)el0_ia破托。
對于ARM64處理器,異常級別1的異常癥狀寄存器(ESR_EL1)用來存放異常的癥狀信息歧蒋。
EC:ESR_EL1[26:31]土砂,異常類別州既,指示引起異常的原因。
ISS:ESR_EL1[0:24]萝映,每種異常類別獨立定義這個字段吴叶。
頁錯誤異常處理程序最終都會執(zhí)行到函數(shù)do_mem_abort,該函數(shù)根據(jù)異常癥狀寄存器的指令特定癥狀字段的指令錯誤狀態(tài)碼(0~5)序臂,調(diào)用數(shù)組fault_info中的處理函數(shù)蚌卤。

static struct fault_info {
    int (*fn)(unsigned long addr, unsigned int esr, struct pt_regs *regs);
    int sig;
    int code;
    const char *name;
} fault_info[] = {
    { do_bad,       SIGBUS,  0,     "ttbr address size fault"   },
    { do_bad,       SIGBUS,  0,     "level 1 address size fault"    },
    { do_bad,       SIGBUS,  0,     "level 2 address size fault"    },
    { do_bad,       SIGBUS,  0,     "level 3 address size fault"    },
    { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level 0 translation fault" },
    { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level 1 translation fault" },
    { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level 2 translation fault" },
    { do_translation_fault, SIGSEGV, SEGV_MAPERR,   "level 3 translation fault" },
    { do_bad,       SIGBUS,  0,     "unknown 8"         },
    { do_page_fault,    SIGSEGV, SEGV_ACCERR,   "level 1 access flag fault" },
    { do_page_fault,    SIGSEGV, SEGV_ACCERR,   "level 2 access flag fault" },
    { do_page_fault,    SIGSEGV, SEGV_ACCERR,   "level 3 access flag fault" },
    { do_bad,       SIGBUS,  0,     "unknown 12"            },
    { do_page_fault,    SIGSEGV, SEGV_ACCERR,   "level 1 permission fault"  },
    { do_page_fault,    SIGSEGV, SEGV_ACCERR,   "level 2 permission fault"  },
    { do_page_fault,    SIGSEGV, SEGV_ACCERR,   "level 3 permission fault"  },
    { do_bad,       SIGBUS,  0,     "synchronous external abort"    },
    { do_bad,       SIGBUS,  0,     "unknown 17"            },
    { do_bad,       SIGBUS,  0,     "unknown 18"            },
    { do_bad,       SIGBUS,  0,     "unknown 19"            },
    { do_bad,       SIGBUS,  0,     "synchronous abort (translation table walk)" },
    { do_bad,       SIGBUS,  0,     "synchronous abort (translation table walk)" },
    { do_bad,       SIGBUS,  0,     "synchronous abort (translation table walk)" },
    { do_bad,       SIGBUS,  0,     "synchronous abort (translation table walk)" },
    { do_bad,       SIGBUS,  0,     "synchronous parity error"  },
    { do_bad,       SIGBUS,  0,     "unknown 25"            },
    { do_bad,       SIGBUS,  0,     "unknown 26"            },
    { do_bad,       SIGBUS,  0,     "unknown 27"            },
    { do_bad,       SIGBUS,  0,     "synchronous parity error (translation table walk)" },
    { do_bad,       SIGBUS,  0,     "synchronous parity error (translation table walk)" },
    { do_bad,       SIGBUS,  0,     "synchronous parity error (translation table walk)" },
    { do_bad,       SIGBUS,  0,     "synchronous parity error (translation table walk)" },
    { do_bad,       SIGBUS,  0,     "unknown 32"            },
    { do_bad,       SIGBUS,  BUS_ADRALN,    "alignment fault"       },
    { do_bad,       SIGBUS,  0,     "unknown 34"            },
    { do_bad,       SIGBUS,  0,     "unknown 35"            },
    { do_bad,       SIGBUS,  0,     "unknown 36"            },
    { do_bad,       SIGBUS,  0,     "unknown 37"            },
    { do_bad,       SIGBUS,  0,     "unknown 38"            },
    { do_bad,       SIGBUS,  0,     "unknown 39"            },
    { do_bad,       SIGBUS,  0,     "unknown 40"            },
    { do_bad,       SIGBUS,  0,     "unknown 41"            },
    { do_bad,       SIGBUS,  0,     "unknown 42"            },
    { do_bad,       SIGBUS,  0,     "unknown 43"            },
    { do_bad,       SIGBUS,  0,     "unknown 44"            },
    { do_bad,       SIGBUS,  0,     "unknown 45"            },
    { do_bad,       SIGBUS,  0,     "unknown 46"            },
    { do_bad,       SIGBUS,  0,     "unknown 47"            },
    { do_bad,       SIGBUS,  0,     "TLB conflict abort"        },
    { do_bad,       SIGBUS,  0,     "unknown 49"            },
    { do_bad,       SIGBUS,  0,     "unknown 50"            },
    { do_bad,       SIGBUS,  0,     "unknown 51"            },
    { do_bad,       SIGBUS,  0,     "implementation fault (lockdown abort)" },
    { do_bad,       SIGBUS,  0,     "implementation fault (unsupported exclusive)" },
    { do_bad,       SIGBUS,  0,     "unknown 54"            },
    { do_bad,       SIGBUS,  0,     "unknown 55"            },
    { do_bad,       SIGBUS,  0,     "unknown 56"            },
    { do_bad,       SIGBUS,  0,     "unknown 57"            },
    { do_bad,       SIGBUS,  0,     "unknown 58"            },
    { do_bad,       SIGBUS,  0,     "unknown 59"            },
    { do_bad,       SIGBUS,  0,     "unknown 60"            },
    { do_bad,       SIGBUS,  0,     "section domain fault"      },
    { do_bad,       SIGBUS,  0,     "page domain fault"     },
    { do_bad,       SIGBUS,  0,     "unknown 63"            },
};

虛擬頁沒有映射到物理頁的情況
(1)如果在0級、1級或2級轉(zhuǎn)換表中的匹配的表項是無效描述符贸宏,調(diào)用函數(shù)do_translation_fault來處理造寝;如果是在3級轉(zhuǎn)換表中匹配的表項是無效描述符,調(diào)用函數(shù)do_page_fault來處理吭练。
(2)如果在1級诫龙、2級或3級轉(zhuǎn)換表中匹配的表項是塊描述符或頁描述符,但是沒有設(shè)置訪問標(biāo)志鲫咽,那么調(diào)用函數(shù)do_page_fault將會為頁表項設(shè)置訪問標(biāo)志签赃。頁回收算法需要根據(jù)頁表項的訪問標(biāo)志判斷物理頁是不是剛剛被訪問過。
(3)如果是權(quán)限錯誤在1級分尸,2級或3級轉(zhuǎn)換表中匹配的表項是塊描述符或頁描述符锦聊,但是沒有訪問權(quán)限,那么調(diào)用do_page_fault箩绍。
do_translation_fault判斷是如果觸發(fā)異常的虛擬地址是用戶虛擬地址孔庭,調(diào)用函數(shù)do_page_fault來處理;如果觸發(fā)異常的虛擬地址是內(nèi)核虛擬地址或不規(guī)范地址材蛛,調(diào)用函數(shù)do_bad_area來處理圆到。
do_page_fault中檢查不同是否在原子上下文中,以及觸發(fā)地址的權(quán)限問題卑吭。正常情況下芽淡,通過__do_page_fault處理頁錯誤異常。
禁止執(zhí)行頁錯誤異常處理程序的情況:有些系統(tǒng)調(diào)用傳入用戶空間的緩沖區(qū)豆赏,內(nèi)核使用用戶虛擬地址訪問緩沖區(qū)挣菲,可能生成頁錯誤異常;然而頁錯誤異常處理程序可能睡眠掷邦,但內(nèi)核在原子上下文中白胀,并不能睡眠;所以在原子上下文中抚岗,使用用戶虛擬地址訪問緩沖區(qū)之前纹笼,調(diào)用函數(shù)pagefault_disable禁止執(zhí)行頁錯誤異常處理程序
__do_page_fault根據(jù)觸發(fā)異常的虛擬地址在進(jìn)程的虛擬內(nèi)存區(qū)域的紅黑樹中查找一個滿足條件的虛擬內(nèi)存區(qū)域:觸發(fā)異常的虛擬地址小于虛擬內(nèi)存區(qū)域的結(jié)束地址苟跪;沒找到虛擬內(nèi)存區(qū)域說明虛擬地址是非法的廷痘,返回VM_FAULT_BADMAP蔓涧;判斷這個區(qū)域是否是棧,是棧的話調(diào)用expand_stack笋额,擴(kuò)大棧的虛擬內(nèi)存區(qū)域元暴,擴(kuò)大成功,檢測權(quán)限兄猩,然后調(diào)用函數(shù)handle_mm_fault處理頁錯誤異常茉盏;非棧的情況下,檢查訪問權(quán)限枢冤,如果虛擬內(nèi)存區(qū)域沒有授予觸發(fā)頁錯誤異常的訪問權(quán)限鸠姨,然后調(diào)用handle_mm_fault。
最終在虛擬地址合法淹真,權(quán)限正常的情況下都會調(diào)用到handle_mm_fault函數(shù)處理頁錯誤異常讶迁。

2 用戶空間頁錯誤異常

從函數(shù)handle_mm_fault開始的部分是所有處理器架構(gòu)共用的部分,函數(shù)handle_mm_fault負(fù)責(zé)處理用戶空間的頁錯誤異常核蘸。用戶空間頁錯誤異常是指進(jìn)程訪問用戶虛擬地址生成的頁錯誤異常巍糯,分兩種情況:
(1)進(jìn)程在用戶模式下訪問用戶虛擬地址,生成頁錯誤異常客扎。
(2)進(jìn)程在內(nèi)核模式下訪問用戶虛擬地址祟峦,生成頁錯誤異常。
handle_mm_fault主要流程:創(chuàng)建觸發(fā)異常的虛擬地址對應(yīng)的各級頁表的頁表項徙鱼,然后調(diào)用handle_pte_fault宅楞。

2.1 handle_pte_fault

handle_pte_fault執(zhí)行流程如下:

handle_pte_fault
  -->頁表項無效的情況下:處理頁表項無效
      -->私有匿名映射 -->do_anonymous_page
      -->文件映射/共享匿名映射 -->do_fault
  -->頁不在內(nèi)存中-->do_swap_page
  -->頁在內(nèi)存中:處理頁在內(nèi)存中的情況
      -->處理寫訪問的情況
          -->頁表項沒有設(shè)置寫權(quán)限位-->執(zhí)行寫時復(fù)制(do_wp_page)
          -->pte_mkdirty
      -->pte_mkyoung
      -->ptep_set_access_flags
          -->頁表項是否變化
              -->是:update_mmu_cache
              -->否:flush_tlb_fix_spurious_fault

2.2 匿名頁的缺頁異常

以下三種情況下會觸發(fā)匿名頁的缺頁異常:
(1)函數(shù)的局部變量比較大,或者函數(shù)調(diào)用的層次比較深袱吆,導(dǎo)致當(dāng)前棧不夠用咱筛,需要擴(kuò)大棧。
(2)進(jìn)程調(diào)用malloc杆故,從堆申請了內(nèi)存塊,只分配虛擬內(nèi)存區(qū)域溉愁,還沒有映射到物理頁处铛,第一次訪問時觸發(fā)缺頁異常。
(3)進(jìn)程直接調(diào)用mmap拐揭,創(chuàng)建匿名的內(nèi)存映射撤蟆,只分配了虛擬內(nèi)存區(qū)域,還沒映射到物理頁堂污,第一次訪問時觸發(fā)缺頁異常家肯。

2.3 文件頁的缺頁異常

以下兩種情況下會觸發(fā)文件頁的缺頁異常:
(1)啟動程序的時候,內(nèi)核為程序的代碼段和數(shù)據(jù)段創(chuàng)建私有的文件映射盟猖,映射到進(jìn)程的虛擬地址空間讨衣,第一次訪問時换棚,觸發(fā)文件頁的缺頁異常。
(2)進(jìn)程使用mmap創(chuàng)建文件映射反镇,把文件的一個區(qū)間映射到進(jìn)程的虛擬地址空間固蚤,第一次訪問時,觸發(fā)文件的缺頁異常歹茶。
do_fault的執(zhí)行流程:

do_fault
  -->沒有提供vma->vm_ops->fault夕玩,返回VM_FAULT_SIGBUS
  -->讀文件頁錯誤,do_read_fault
  -->寫私有文件頁錯誤惊豺,do_cow_fault
  -->寫共享文件頁錯誤燎孟,do_shared_fault

2.3.1處理讀文件頁錯誤

(1)把文件頁從存儲設(shè)備上的文件系統(tǒng)讀到文件的頁緩存(每個文件有一個緩存,因為以頁為單位尸昧,所以稱為頁緩存)揩页。
(2)設(shè)置進(jìn)程的頁表項彻磁,把虛擬頁映射到文件的頁緩存中的物理頁碍沐。

2.3.2處理寫私有文件錯誤

(1)把文件從存儲設(shè)備上的文件系統(tǒng)讀到文件的頁緩存中。
(2)執(zhí)行寫時復(fù)制衷蜓,為文件的頁緩存中的物理頁創(chuàng)建一個副本斋陪,這個副本是進(jìn)程的私有匿名頁无虚,和文件脫離關(guān)系友题,修改副本不會導(dǎo)致文件變化度宦。
(3)設(shè)備進(jìn)程的頁表項,把虛擬頁映射到副本告匠。

2.3.3處理寫共享文件錯誤

(1)把文件頁從存儲設(shè)備上的文件系統(tǒng)讀到文件的頁緩存中戈抄。
(2)設(shè)置進(jìn)程的頁表項,把虛擬頁映射到文件的頁緩存中的物理頁后专。

2.3.4 寫時復(fù)制

寫時復(fù)制的兩個場景:
(1)進(jìn)程分叉成子進(jìn)程的時候划鸽,為了避免復(fù)制物理頁,子進(jìn)程和父進(jìn)程以只讀的方式共享所有私有的匿名頁和文件頁。當(dāng)其中一個進(jìn)程試圖寫只讀頁時裸诽,觸發(fā)頁錯誤異常嫂用,頁錯誤異常處理程序分配新的物理頁,把舊的物理頁的數(shù)據(jù)復(fù)制到新的物理頁崭捍,然后把虛擬頁映射到新的物理頁上尸折。
(2)進(jìn)程創(chuàng)建私有的文件映射,然后讀訪問殷蛇,觸發(fā)頁錯誤異常实夹,異常處理程序把文件讀到頁緩存,然后以只讀模式把虛擬頁映射到文件的頁緩存中的物理頁粒梦。接著執(zhí)行寫訪問亮航,觸發(fā)頁錯誤異常,異常處理程序執(zhí)行寫時復(fù)制匀们,為文件的頁緩存中的物理頁創(chuàng)建一個副本缴淋,把虛擬頁映射到副本。這個副本是進(jìn)程的私有匿名頁泄朴,和文件脫離關(guān)系重抖,修改副本不會導(dǎo)致文件變化。

3 內(nèi)核模式頁錯誤異常

內(nèi)核訪問內(nèi)核虛擬地址祖灰,正常情況下不會出現(xiàn)虛擬頁沒有映射到物理頁的狀況钟沛,內(nèi)核使用線性映射區(qū)域的虛擬地址,在內(nèi)存管理子系統(tǒng)初始化的時候就會把虛擬地址映射到物理地址局扶;運行過程中恨统,可能使用vmalloc函數(shù)從vmalloc區(qū)域分配虛擬內(nèi)存區(qū)域,vmalloc函數(shù)會分配并且映射到物理頁三妈。如果出現(xiàn)虛擬頁沒有映射到物理頁的情況畜埋,一定是程序錯誤,內(nèi)核將會崩潰畴蒲。
內(nèi)核可能訪問用戶虛擬地址悠鞍,進(jìn)程通過系統(tǒng)調(diào)用進(jìn)入內(nèi)核模式,有些系統(tǒng)調(diào)用會傳入用戶空間的緩沖區(qū)模燥,內(nèi)核必須使用頭文件uaccess.h定義的專用函數(shù)訪問用戶空間的緩沖區(qū)咖祭,這些專用函數(shù)在異常表中添加了可能觸發(fā)異常的指令地址和異常修正程序的地址
在內(nèi)核模式下執(zhí)行時觸發(fā)頁錯誤異常涧窒,ARM64架構(gòu)內(nèi)核的處理流程如下:
(1)如果不允許內(nèi)核執(zhí)行用戶空間的指令,那么進(jìn)程在內(nèi)核模式下試圖執(zhí)行用戶空間的指令時锭亏,內(nèi)核崩潰纠吴。
(2)如果進(jìn)程在內(nèi)核模式下訪問用戶虛擬地址,那么先使用函數(shù)__do_page_fault處理慧瘤;如果處理失敗戴已,最后通過__do_kernel_fault處理固该。
(3)其他情況使用函數(shù)__do_kernel_fault處理。
__do_kernel_fault針對數(shù)據(jù)的訪問觸發(fā)的異常糖儡,嘗試在異常表中查找異常修成程序伐坏。如果找到異常修正程序,把保存在內(nèi)核棧中的異常鏈接寄存器(ELR_EL1)的值改為異常修正程序的虛擬地址握联。當(dāng)異常處理程序返回時桦沉,處理器把程序計數(shù)器設(shè)置成異常鏈接寄存器的值,執(zhí)行異常修正程序金闽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末纯露,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子代芜,更是在濱河造成了極大的恐慌埠褪,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挤庇,死亡現(xiàn)場離奇詭異钞速,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嫡秕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進(jìn)店門渴语,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人淘菩,你說我怎么就攤上這事遵班。” “怎么了潮改?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵狭郑,是天一觀的道長。 經(jīng)常有香客問我汇在,道長翰萨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任糕殉,我火速辦了婚禮亩鬼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘阿蝶。我一直安慰自己雳锋,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布羡洁。 她就那樣靜靜地躺著玷过,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辛蚊,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天粤蝎,我揣著相機(jī)與錄音,去河邊找鬼袋马。 笑死初澎,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的虑凛。 我是一名探鬼主播碑宴,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼卧檐!你這毒婦竟也來了墓懂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤霉囚,失蹤者是張志新(化名)和其女友劉穎捕仔,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盈罐,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡榜跌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了盅粪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钓葫。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖票顾,靈堂內(nèi)的尸體忽然破棺而出础浮,到底是詐尸還是另有隱情,我是刑警寧澤奠骄,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布豆同,位于F島的核電站,受9級特大地震影響含鳞,放射性物質(zhì)發(fā)生泄漏影锈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一蝉绷、第九天 我趴在偏房一處隱蔽的房頂上張望鸭廷。 院中可真熱鬧,春花似錦熔吗、人聲如沸辆床。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽讼载。三九已至宵晚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間维雇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工晒他, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留吱型,地道東北人。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓陨仅,卻偏偏與公主長得像津滞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子灼伤,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容