insmod過程

insmod過程

CSDN的一位不愿意透漏姓氏的底層搬磚人員不用了,后面看看慢慢把文章輸出到簡書上辛润。

模塊加載與卸載

眾所周知胆数,Linux下模塊加載可以用insmod命令來完成怒允,卸載模塊通過rmmod命令來完成砰嘁,比如下面,非常簡單:

insmod_hello_ko.png

那么第一個(gè)問題來了市殷,模塊是什么愕撰?

模塊文件

那么接下來,我們就可以通過file命令來查看一下這個(gè).ko文件到底是何方神圣醋寝,可以看到搞挣,此ko文件是一個(gè)ELF 32-bit LSB relocatable文件,ELF格式的音羞,32-bit的囱桨,LSB小端,relocatable可重定位文件嗅绰,此文件未stripped舍肠。

file_hello_ko.png

可以看到,file命令非常好用窘面,直接就知道了ko模塊文件是ELF relocatable文件翠语。

話說回來,編譯過程中產(chǎn)生的.o文件也是ELF relocatable文件财边,兩個(gè)看起來并沒有太大的差異肌括。

file_hello_o.png

所以模塊文件為什么以.ko結(jié)尾,就是因?yàn)槟K文件實(shí)際是一個(gè)和.o文件差不多的中間文件酣难,但又加入了內(nèi)核kernel特有的一些section们童,所以特此命名為.ko。(那么生成.ko的過程鲸鹦,可以參考一下我的另一篇==《模塊生成過程》==)

話又說回來,ELF文件是什么文件跷跪?

ELF文件

推薦大家去看ELF.pdf這個(gè)文檔馋嗜,我這里就選取部分可能用到的放這里。

首先吵瞻,我們看一下這個(gè)ELF的全稱是什么:Executable and Linkable Format葛菇,可執(zhí)行甘磨,可鏈接格式。

那么在模塊文件中眯停,這個(gè)文件的格式就是可鏈接格式济舆;對于普通的可執(zhí)行文件,就是可執(zhí)行格式莺债,比如下面這個(gè)busybox

file_busybox.png

ELF文檔中提到滋觉,Object File Format有兩個(gè)視角,一個(gè)是鏈接過程的視角齐邦,一個(gè)是執(zhí)行過程的視角椎侠。

Figure 1-1- Object File Format.png

目標(biāo)文件在鏈接時(shí),就是左邊的鏈接視角措拇;可執(zhí)行程序執(zhí)行時(shí)我纪,是右邊的執(zhí)行視角。鏈接時(shí)需要Section header table丐吓,執(zhí)行時(shí)則需要Program header table浅悉。

我們可以通過arm-linux-gnueabi-readelf -S命令來看一下鏈接過程的視角,即看一下這些section(在==《模塊生成過程》==中有提到券犁,.ko只是增加了一些section术健,比如gnu.linkonce.this_module.modinfo等):

readelf_ko.png
readelf_o.png

但執(zhí)行過程的視角族操,由于都在內(nèi)存中苛坚,目前就暫時(shí)不管了。

那么接下來就是看一下代碼的過程色难。

busybox的insmod過程

我們這里還是用的busybox做的根文件系統(tǒng)泼舱,insmod命令也是由busybox提供的,那么就直接在busybox里面找代碼:調(diào)用bb_init_module()枷莉。

insmod_main.png

bb_init_module()也比較簡單娇昙,目前內(nèi)核的版本是linux-4.0,不走下面的bb_init_module_24()笤妙,且定義了系統(tǒng)調(diào)用finit_module()冒掌,成果后直接返回。如果失敗了蹲盘,還有后面的init_module()系統(tǒng)調(diào)用股毫,這里還需要先將模塊文件映射到內(nèi)存上,結(jié)束后再取消映射整個(gè)模塊文件召衔。

bb_init_module-1.png
bb_init_module-2.png

接下來就是要看內(nèi)核系統(tǒng)調(diào)用的時(shí)候了铃诬。

內(nèi)核系統(tǒng)調(diào)用

當(dāng)前用到系統(tǒng)調(diào)用是finit_module(),系統(tǒng)調(diào)用里傳遞的fd是在busybox打開的,這里通過copy_module_from_fd()將打開的模塊文件讀到申請的內(nèi)核內(nèi)存中趣席,并交由load_module()處理兵志。

finit_module.png

copy_module_from_fd()這里只需要知道,load_info結(jié)構(gòu)體的hdr成員是指向內(nèi)核申請的內(nèi)存宣肚,即整個(gè)模塊文件的內(nèi)存起始地址想罕,len則是這個(gè)模塊文件的長度。

這里我們用qemu+gdb調(diào)試一下霉涨,并在load_module()打上斷點(diǎn)(關(guān)于qemu和gdb網(wǎng)上的教程比較多去參考):

# 網(wǎng)橋配置 -- 僅供參考
sudo brctl addbr br0
sudo ifconfig enp0s6 down
sudo brctl addif br0 enp0s6
sudo brctl stp br0 off
sudo ifconfig br0 10.37.129.17 netmask 255.255.255.0 promisc up
sudo ifconfig enp0s6 10.37.129.10 netmask 255.255.255.0 promisc up
sudo tunctl -t tap0
sudo ifconfig tap0 10.37.129.18 netmask 255.255.255.0 promisc up
sudo brctl addif br0 tap0

# 起 qemu -- 僅供參考
sudo qemu-system-arm -M vexpress-a9 -m 512M -kernel arch/arm/boot/zImage -nographic -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -net nic -net tap,ifname=tap0,script=no -append "init=/linuxrc root=/dev/nfs rw nfsroot=10.37.129.17:/home/mj/work/rootfs/,proto=tcp,nolock ip=10.37.129.20:10.37.129.17:10.37.129.1:255.255.255.0::eth0:off console=ttyAMA0,38400n" -S -s

# 起 gdb
arm-linux-gnueabi-gdb vmlinux
# 連接設(shè)備 
target remote localhost:1234
# 打斷點(diǎn)
b load_module
qemu.png
b_load_module.png

此時(shí)執(zhí)行模塊加載按价,gdb那邊就觸發(fā)了斷點(diǎn):

insmod.png

可以看到大小一致:

p*info.png

且。內(nèi)存上的與編譯出來的.ko一模一樣:

dump_hello_ko.png

Part1 模型信息校驗(yàn)與模塊重新布局

module_sig_check()需要開啟CONFIG_MODULE_SIG才會(huì)起作用嵌纲,這里忽略俘枫。elf_header_check()主要是檢查一下ELF文件頭信息,別忘了模塊文件.koELF relocatable文件逮走,所以需要檢查一下是否是正確的ELF文件格式鸠蚪。layout_and_allocate()獲取模塊的布局,重新申請一次內(nèi)存师溅,并對相關(guān)section對內(nèi)容進(jìn)行修改茅信。add_unformed_module()將模塊加入到內(nèi)核的模塊鏈表中。

load_module-1.png

Part1.1 ELF頭校驗(yàn)

elf_header_check()是根據(jù)規(guī)范來校驗(yàn)整個(gè)ELF文件頭的信息墓臭,比如ELF HeaderMagic蘸鲸,必須是 '0x7f' , 'E', 'L', 'F';ELF 的文件類型必須是 ET_REL (模塊文件是可重定位文件窿锉,不必多說了吧)酌摇;不同架構(gòu)芯片的編譯器編譯時(shí)會(huì)把 e_machine 設(shè)置為對應(yīng)的類型,這里是 EM_ARM嗡载。

elf_header_check.png

)

內(nèi)存上的數(shù)據(jù)如下所示:

p*info->hdr.png

可以參觀一下一個(gè)標(biāo)準(zhǔn)的ELF Header的內(nèi)容:

Figure 1-3- ELF Header.png

這里的e_type必須是ET_REL可重定位類型窑多,就不用多說了。

Elf32_Ehdr->etype.png

Part1.2 模塊內(nèi)存的申請與layout

看章節(jié)小標(biāo)題就大概可以知道洼滚,layout_and_allocate()函數(shù)所做的工作有:1埂息,記錄模塊信息與重寫模塊數(shù)據(jù);2遥巴,檢查模塊license千康;3,取消percpu section的內(nèi)存申請標(biāo)記铲掐,后續(xù)特殊處理拾弃;4,統(tǒng)計(jì)和預(yù)留需要layout數(shù)據(jù)空間摆霉;5砸彬,統(tǒng)計(jì)和預(yù)留模塊符號的空間颠毙;6,申請內(nèi)存并拷貝模塊數(shù)據(jù)到layout砂碉;7,將記錄的模塊信息指向layout的內(nèi)存刻两。

layout_and_allocate.png
Part1.2.1 記錄模塊信息與重寫模塊數(shù)據(jù)

setup_load_info()記錄節(jié)頭表位置增蹭,再根據(jù)節(jié)頭表找到節(jié)名字字符串表在內(nèi)存中位置。然后遍歷所有的節(jié)磅摹,保證相關(guān)節(jié)的偏移+長度不超過整個(gè)ELF文件的大小滋迈,把節(jié)的地址設(shè)在為當(dāng)前內(nèi)核內(nèi)存下的地址。并且要找到模塊特有的節(jié).gnu.linkonce.this_module户誓,表明是模塊的信息饼灿。并記錄當(dāng)前模塊的.data..percpu節(jié),方便后續(xù)對每CPU變特殊申請?zhí)幚怼?/p>

setup_load_info-1.png
setup_load_info-2.png

rewrite_section_headers()函數(shù)將內(nèi)存里的每一個(gè)sectionsh_addr節(jié)地址記錄為當(dāng)前內(nèi)核內(nèi)存上的地址帝美,并找到__versions節(jié)和.modinfo節(jié)碍彭,取消這兩個(gè)節(jié)的內(nèi)存申請標(biāo)記:

rewrite_section_headers.png

顯而易見,經(jīng)過rewrite_section_headers()之后悼潭,內(nèi)存上的數(shù)據(jù)肯定發(fā)生了變化庇忌,用通用的方法,導(dǎo)出內(nèi)存上的數(shù)據(jù):dump memory hello.ko-rewirte-section.dump 0xa0ab0000 0xa0ab0000+31476

dump_hello_ko_rewrite.png

比較一波舰褪,除去第0個(gè)section皆疹,后面每一個(gè)sectionsh_addr已經(jīng)被修改為當(dāng)前內(nèi)存的地址:

cmp dump&rewrite_dump.png

回頭看find_sec()也比較簡單,因?yàn)榍懊嬖?code>setup_load_info()中已經(jīng)獲取到每個(gè)section到描述頭以及section到名字字符串表的位置占拍,那么遍歷一下所有section略就,比對名字即可:

find_sec.png

查找當(dāng)前模塊的.data..percpu節(jié)也比較簡單:

find_pcpusec.png
Part1.2.2 檢查模塊license

check_modinfo()主要是檢查.modinfo節(jié)里面的一些包括license的信息,并記錄此模塊是否存在污染內(nèi)核的可能:

check_modinfo.png
Part1.2.3 統(tǒng)計(jì)和預(yù)留需要layout數(shù)據(jù)空間

layout_sections()函數(shù)開頭的注釋可以得知晃酒,這里其實(shí)是為后續(xù)執(zhí)行類似ld的操作做準(zhǔn)備表牢,計(jì)算代碼、只讀數(shù)據(jù)掖疮、小數(shù)據(jù)的大小以及總的大小初茶。對于部分存在架構(gòu)額外內(nèi)存的或者地址對齊限制的,在get_offset()函數(shù)中體現(xiàn)浊闪。這里主要是分兩個(gè)部分恼布,一開始先統(tǒng)計(jì)模塊的core_layout部分,然后再統(tǒng)計(jì)init_layout部分的數(shù)據(jù)搁宾。這里的masks也注釋得很清楚折汞,0AX可執(zhí)行的非小數(shù)據(jù),1A只需申請內(nèi)存的不可寫的非小數(shù)據(jù)盖腿,3是小數(shù)據(jù)申請內(nèi)存的爽待。

layout_sections-1.png
layout_sections-2.png
layout_sections-3.png
Part1.2.4 統(tǒng)計(jì)和預(yù)留模塊符號的空間

layout_symtab()這里一開始在init layout里面預(yù)留空間损同,用于存放模塊的符號表。緊接著遍歷模塊的符號鸟款,找出哪些屬于內(nèi)核的符號膏燃,然后在core layout中預(yù)留出內(nèi)核符號的符號表和字符串表空間。最后在init layout后面預(yù)留模塊字符串表的空間何什。

layout_symtab.png

判斷是否是內(nèi)核的符號组哩,可以根據(jù)符號的st_shndx是否是為定義的SHN_UNDEF,未定義的符號肯定不是內(nèi)核符號处渣;符號的名字是否存在等:

is_core_symbol.png
Part1.2.5 申請內(nèi)存并拷貝模塊數(shù)據(jù)到layout

move_module()主要的工作就是把模塊信息移到新申請的可執(zhí)行的內(nèi)存中去伶贰。layout_sections()layout_symtab()統(tǒng)計(jì)了要申請的內(nèi)存大小,設(shè)定了布局罐栈,所以在move_module()中申請完內(nèi)存后黍衙,就需要將相關(guān)的數(shù)據(jù)拷貝到對應(yīng)的布局中,數(shù)據(jù)來源自然是前面經(jīng)過修正后的模塊信息荠诬,修改完后琅翻,還需要再次修正每個(gè)sectionlayout內(nèi)存中的位置。

move_module-1.png

move_module-2.png

申請內(nèi)存的過程調(diào)用的是vmalloc_exec()申請?zhí)摂M連續(xù)的可執(zhí)行內(nèi)存浅妆,并更新模塊地址的邊界信息:

module_alloc_update_bounds.png

這里本來想dump出當(dāng)前layout的內(nèi)存數(shù)據(jù)的望迎,但由于內(nèi)核是-O2編譯的,局部變量已經(jīng)被優(yōu)化了凌外,所以暫時(shí)沒有辦法dump出內(nèi)存數(shù)據(jù)辩尊。

在Part2.7部分的apply_relocate()斷點(diǎn)時(shí),發(fā)現(xiàn)mod參數(shù)未被優(yōu)化康辑,那么就可以直接看一下在apply_relocate()時(shí)的struct module內(nèi)存數(shù)據(jù)摄欲,但會(huì)經(jīng)歷Part2.6部分的simplify_symbols()修改符號地址的。

p *(struct module *).png

這里稍微看一下就行了疮薇,后續(xù)如果再研究這個(gè)內(nèi)存的布局的話胸墙,可以再細(xì)看一下:

core_layout_dump.png
init_layout_dump.png

Part1.3 將模塊加入到內(nèi)核的模塊記錄鏈表中

add_unformed_module()主要就是將模塊加入到內(nèi)核的模塊鏈表中,保證模塊唯一按咒。

add_unformed_module.png

Part2 模塊的符號處理與重定位

percpu_modalloc()對模塊里面的percpu進(jìn)行特殊的內(nèi)存申請迟隅,這個(gè)percpu變量比較特殊,在每個(gè)CPU上都存在一份励七,所以用特殊的申請內(nèi)存函數(shù)去處理智袭。module_unload_init()為后續(xù)執(zhí)行rmmod卸載命令時(shí)初始化一些引用變量以及鏈表等。find_module_sections()找模塊里面的一些section掠抬,比如參數(shù)的__param節(jié)吼野,內(nèi)核符號表__ksymtab節(jié),GPL范圍協(xié)議的符號__ksymtab_gpl節(jié)两波,ftrace增加的_ftrace_events節(jié)等待瞳步。check_module_license_and_versions()主要是檢查模塊的license是否存在污染內(nèi)核的可能闷哆。setup_modinfo()是對sys屬性進(jìn)行一些預(yù)先setup處理。simplify_symbols()要修復(fù)加載模塊的符號单起,使符號指向內(nèi)核正確的運(yùn)行地址抱怔。apply_relocations()則是對.rel節(jié)和.rela節(jié)進(jìn)行重定位的一個(gè)過程。post_relocation()對重定位后的percpu變量重新賦值嘀倒,并將即將加載完成的模塊的符號加入到內(nèi)核模塊的符號鏈表中野蝇,如果成功加載此模塊且內(nèi)核配置了CONFIG_KALLSYMS,那么在/proc/kallsyms下可以看到此模塊的符號(我另有《kallsyms 內(nèi)核符號表》可以稍微瞄一眼)括儒。之后flush_module_icache()執(zhí)行刷新模塊的init_layoutcore_layout的cache。

load_module-2.png

Part2.1 申請percpu內(nèi)存

percpu_modalloc()這里重新為percpu section的數(shù)據(jù)申請內(nèi)存锐想,是補(bǔ)上Part1部分的去向了percpuSHF_ALLOC

percpu_modalloc.png

Part2.2 為后續(xù)模塊卸載做準(zhǔn)備

module_unload_init()這里主要是初始化了一個(gè)原子變量與兩個(gè)鏈表帮寻,鏈表分別用于存放哪些模塊依賴于我以及我依賴于哪些模塊的信息,主要是卸載掉時(shí)候會(huì)用赠摇。

module_unload_init.png

Part2.3 找模塊的參數(shù)固逗、內(nèi)核符號等節(jié)

find_module_sections()這里是找到模塊的一些節(jié)的地址,比如模塊參數(shù)__param藕帜,內(nèi)核符號__ksymtab烫罩,內(nèi)核GPL符號__ksymtab_gpl等:

find_module_sections.png

找節(jié)地址的函數(shù)如下,也比較簡單洽故,先獲取節(jié)的序號贝攒,之后再根據(jù)序號獲取地址:

section_objs.png

Part2.4 再次檢查GPL協(xié)議?

這里暫時(shí)沒有看懂為什么时甚。

check_module_license_and_versions.png

Part2.5 模塊sys參數(shù)setup

setup_modinfo()遍歷modinfo_attrs數(shù)組里面的屬性隘弊,如果有setup回調(diào),嘗試從模塊的.modinfo中獲取相關(guān)的setup參數(shù):

setup_modinfo.png

好像也沒有看到相關(guān)的參數(shù)出現(xiàn)荒适,所以就此作罷梨熙。

readelf -x modinfo.png

Part2.6 模塊符號處理

simplify_symbols()是對模塊的符號進(jìn)行處理,模塊節(jié)的獲取在前面已經(jīng)相當(dāng)?shù)亩嗔说段埽@里就不贅述了咽扇。對于SHN_COMMON符號,可能是模塊內(nèi)部自己定義的一些普通符號陕壹,可以不做處理质欲;SHN_ABS絕對地址,不需要做處理帐要;而SHN_UNDEF為定義符號把敞,則需要在當(dāng)前內(nèi)核以及已經(jīng)加載的模塊中找到,否則模塊加載失斦セ荨(鏈接的過程需要解決為定義的符號奋早,否則鏈接失斒Ⅵ;當(dāng)然弱符號另說)耽装;如果有一些類似于軟連接的符號或者perpcu的符號愤炸,要再進(jìn)行處理。

先看一下ELF的符號定義掉奄,可以看到代表符號的信息都是固定大小的:

Figure 1-16- Symbol Table Entry.png
simplify_symbols-1.png
simplify_symbols-2.png

resolve_symbol_wait()這里是一個(gè)等待超時(shí)的過程规个,超時(shí)時(shí)間最大是30s,這里還用了一個(gè)逗號表達(dá)式姓建,差點(diǎn)沒認(rèn)出來诞仓。最主要的函數(shù)還是resolve_symbol()查找符號的過程。

resolve_symbol_wait.png

resolve_symbol()主要是依賴與find_symbol()查找符號速兔,找到符號對檢查相關(guān)信息并記錄引用墅拭。

resolve_symbol.png

find_symbol()通過遍歷記錄內(nèi)核符號的地址以及已經(jīng)加載模塊的地址,嘗試找到此符號:

find_symbol.png

each_symbol_section()則是遍歷內(nèi)核與已加載模塊的過程:

each_symbol_section.png

each_symbol_in_section()則是遍歷具體地址調(diào)用回調(diào)的過程:

each_symbol_in_section.png

查找與比較函數(shù)是find_symbol_in_section()涣狗,用的是二分查找谍婉,因?yàn)榫幾g時(shí)的符號已經(jīng)是排序過的了:

find_symbol_in_section.png

Part2.7 節(jié)數(shù)據(jù)的重定位

apply_relocations()主要是對SHT_RELSHT_RELA類型的節(jié)進(jìn)行重定位操作,通過sh_info獲取到附加的重定位節(jié)數(shù)據(jù)镀钓,再根據(jù)要重定位的節(jié)的類型去調(diào)用具體的重定位函數(shù):

apply_relocations.png

sh_info類型穗熬,上面用到下面的SHT_RELSHT_RELA。關(guān)于這兩個(gè)的詳情可以看elf的文檔丁溅,我這里的理解是唤蔗,SHT_REL是表明需要重定位,SHT_RELA是需要重定位且附帶一個(gè)額外的地址偏移唧瘾。

Figure 1-10- Section Types, sh_type.png

先看一下這里Elf32_Rel類型和Elf32_Rela類型措译,

Figure 1-20- Relocation Entries.png

apply_relocate()是對應(yīng)架構(gòu)下的重定位函數(shù),主要是根據(jù)架構(gòu)提供的aaelf32.pdf文檔來對具體符號進(jìn)行重定位饰序,類型也比較多领虹,暫時(shí)就不細(xì)看了:

apply_relocate-1.png
apply_relocate-2.png
apply_relocate-3.png

比如打印第一個(gè)需要重定位對符號,r_info對值是0x162b,低8bit的值是0x2b求豫,即43塌衰,根據(jù)類型定義可以知道是#define R_ARM_MOVW_ABS_NC 43

p:x *(Elf32_Rel *).png

再去查看aaelf32.pdf文檔,可以看到這個(gè)就是arm規(guī)定的重定位類型怎么算:

R_ARM_MOVW_ABS_NC.png

Part2.8 結(jié)構(gòu)相關(guān)的模塊初始化

前面find_module_sections()里面有找__ex_table節(jié)蝠嘉,然后賦給mod->extable最疆,在post_relocation()里面就對里面的數(shù)據(jù)進(jìn)行排序,由于當(dāng)前沒有這個(gè)mod->extable成員蚤告,就略過了努酸。這里主要是拷貝了percpu數(shù)據(jù)以及拷貝符號到core_layout中。

post_relocation.png

add_kallsyms()這里對符號進(jìn)行一個(gè)字符的字符賦值杜恰,更直接地表明符號的類型获诈;然后拷貝符號數(shù)據(jù)到core_layout中仍源。

add_kallsyms.png

elf_type()判斷符號的類型,賦值給一個(gè)字符值:

elf_type.png

最后是架構(gòu)相關(guān)的初始化舔涎,主要是一個(gè)回溯信息的增加以及SMP初始化節(jié)等:

module_finalize-1.png
module_finalize-2.png

Part2.9 刷新layout的icache

flush_module_icache()刷新core_layoutinit_layouticache笼踩。

flush_module_icache.png

Part3 模塊init執(zhí)行

strndup_user()復(fù)制一下模塊的參數(shù);dynamic_debug_setup()需要開啟內(nèi)核CONFIG_DYNAMIC_DEBUG才會(huì)啟用亡嫌,這里先略過嚎于;ftrace_module_init()也是需要開啟相關(guān)的ftrace配置,略過挟冠。complete_formation()對模塊的內(nèi)存屬性進(jìn)行修改于购,比如.text的讀+執(zhí)行,.data的讀寫屬性知染。parse_args()是解析模塊參數(shù)价涝,mod_sysfs_setup()則是對sys進(jìn)行創(chuàng)建的過程。free_copy()釋放最初內(nèi)核申請的用于保存模塊原文件信息的內(nèi)存持舆。trace_module_load()也是trace相關(guān)的,略過伪窖。do_init_module()就是最后模塊執(zhí)行init函數(shù)的過程了逸寓。

load_module-3.png

Part3.1 模塊符號重名確認(rèn)、內(nèi)存屬性設(shè)置覆山、模塊上線通知

complete_formation()主要是最后的模塊符號重名確認(rèn)竹伸、內(nèi)存屬性設(shè)置、以及通知鏈通知一下模塊上線了簇宽。

complete_formation.png

verify_export_symbols()確認(rèn)一下模塊的符號是否會(huì)和內(nèi)核的符號或者已經(jīng)加載的模塊的符號重名勋篓。查找符號的函數(shù)看Part2.6的find_symbol()

verify_export_symbols.png

Part3.2 模塊init的執(zhí)行

do_init_module()主要是模塊init的執(zhí)行魏割,然后通知鏈通知一下模塊在線了譬嚣,前面是即將上線,這里是已經(jīng)上線了钞它。

do_init_module-1.png
do_init_module-2.png
do_init_module-3.png

do_one_initcall()這里就是調(diào)用模塊的初始化函數(shù)了拜银,到這里模塊加載基本已經(jīng)完成了。

do_one_initcall.png

Part4 錯(cuò)誤處理

至于最后的這里遭垛,都是上面出錯(cuò)時(shí)的異常處理尼桶,就不多看了。

load_module-4.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锯仪,一起剝皮案震驚了整個(gè)濱河市泵督,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌庶喜,老刑警劉巖小腊,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件救鲤,死亡現(xiàn)場離奇詭異,居然都是意外死亡溢豆,警方通過查閱死者的電腦和手機(jī)蜒简,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來漩仙,“玉大人搓茬,你說我怎么就攤上這事《铀” “怎么了卷仑?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長麸折。 經(jīng)常有香客問我锡凝,道長,這世上最難降的妖魔是什么垢啼? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任窜锯,我火速辦了婚禮,結(jié)果婚禮上芭析,老公的妹妹穿的比我還像新娘锚扎。我一直安慰自己,他們只是感情好馁启,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布驾孔。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惩猫,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天,我揣著相機(jī)與錄音对碌,去河邊找鬼。 笑死蒿偎,一個(gè)胖子當(dāng)著我的面吹牛俭缓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播酥郭,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼华坦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了不从?” 一聲冷哼從身側(cè)響起惜姐,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后歹袁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坷衍,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年条舔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了枫耳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡孟抗,死狀恐怖迁杨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情凄硼,我是刑警寧澤铅协,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站摊沉,受9級特大地震影響狐史,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜说墨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一骏全、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧尼斧,春花似錦吟温、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽潘悼。三九已至律秃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間治唤,已是汗流浹背棒动。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宾添,地道東北人船惨。 一個(gè)月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像缕陕,于是被迫代替她去往敵國和親粱锐。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

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