基于寄存器傳輸語言確定動(dòng)態(tài)函數(shù)調(diào)用關(guān)系的方法【專利摘要】本發(fā)明公開一種基于寄存器傳輸語言確定動(dòng)態(tài)函數(shù)調(diào)用關(guān)系的方法,主要針對(duì)靜態(tài)函數(shù)調(diào)用關(guān)系無法分析函數(shù)指針調(diào)用和可加載模塊函數(shù)調(diào)用關(guān)系的問題而設(shè)計(jì)。本發(fā)明在系統(tǒng)運(yùn)行過程中檢測函數(shù)調(diào)用執(zhí)行事件,若檢測到調(diào)用指令后,解析該指令調(diào)用的函數(shù)入口地址對(duì)應(yīng)的函數(shù)名,統(tǒng)計(jì)指令次數(shù),輸出函數(shù)名、調(diào)用發(fā)生時(shí)間、所屬進(jìn)程號(hào)、所屬線程號(hào)、所屬棧頂指針以及模塊號(hào),并保存到跟蹤數(shù)據(jù)文件;若檢測的指令是返回指令后,輸出時(shí)間、所屬進(jìn)程號(hào)、所屬線程號(hào)以及所屬棧頂指針到跟蹤數(shù)據(jù)文件;對(duì)所述跟蹤數(shù)據(jù)文件進(jìn)行處理獲得預(yù)定標(biāo)準(zhǔn)的數(shù)據(jù)格式,將所述跟蹤數(shù)據(jù)文件傳輸至靜態(tài)函數(shù)調(diào)用關(guān)系生成裝置中,生成描述函數(shù)調(diào)用關(guān)系的動(dòng)態(tài)函數(shù)調(diào)用圖?!緦@f明】基于寄存器傳輸語言確定動(dòng)態(tài)函數(shù)調(diào)用關(guān)系的方法【
技術(shù)領(lǐng)域:
】[0001]本發(fā)明涉及函數(shù)調(diào)用關(guān)系【
技術(shù)領(lǐng)域:
】,具體涉及一種基于寄存器傳輸語言確定動(dòng)態(tài)函數(shù)調(diào)用關(guān)系的方法?!?br>背景技術(shù):
】[0002]對(duì)源代碼的閱讀分析可以通過函數(shù)調(diào)用圖來實(shí)現(xiàn),函數(shù)調(diào)用圖可以是宏觀的(源碼模塊間調(diào)用關(guān)系),也可以是微觀的(具體到某一個(gè)函數(shù)的調(diào)入和調(diào)出關(guān)系)。函數(shù)調(diào)用圖可以展現(xiàn)源代碼靜態(tài)的一種函數(shù)調(diào)用走向,也可以用來展示系統(tǒng)或程序運(yùn)行時(shí)函數(shù)調(diào)用狀態(tài)。為了分析的精確、方便以及高效,研究者開發(fā)許多函數(shù)調(diào)用圖的生成工具。[0003]靜態(tài)函數(shù)調(diào)用圖生成工具是指建立在已知源碼的基礎(chǔ)上,根據(jù)不同的分析需要開發(fā)的工具,這些工具中有些作用對(duì)象僅為源碼如SourceInsight、Understand等,有些作用對(duì)象是編譯過程生成的中間結(jié)果如Codeviz、Egypt、LLVM以及0pen64等。[0004]動(dòng)態(tài)函數(shù)調(diào)用圖生成工具是建立在獲取系統(tǒng)或軟件在運(yùn)行過程中發(fā)生的函數(shù)調(diào)用關(guān)系并繪制成調(diào)用圖的工具,為了獲取運(yùn)行時(shí)的函數(shù)調(diào)用情況也開發(fā)了一些工具如Systemtap>gprof、KCachegrincUftrace、pproftool等,它們有些是針對(duì)于內(nèi)核有些事針對(duì)有軟件的,其基于的目的也各不相同,但它們都是基于函數(shù)調(diào)用關(guān)系分析。[0005]Gprof是在編譯時(shí)讓每個(gè)函數(shù)均調(diào)用mcount函數(shù),同時(shí)會(huì)在內(nèi)存中保存函數(shù)調(diào)用圖,這樣做會(huì)降低系統(tǒng)的性能,如果對(duì)系統(tǒng)全部函數(shù)調(diào)用跟蹤的話,會(huì)造成內(nèi)存使用不足。Ftrace的原理類似于gprof的原理,只是它不會(huì)在內(nèi)存中保存函數(shù)調(diào)用圖,而且mcount的使用也是動(dòng)態(tài)的,可以根據(jù)用戶的要求在需要時(shí)替換nop為mcount指令。SystemTap是監(jiān)控和跟蹤運(yùn)行中的Linux內(nèi)核的操作的動(dòng)態(tài)方法,SystemTap沒有使用工具構(gòu)建一個(gè)特殊的內(nèi)核,而是允許您在運(yùn)行時(shí)動(dòng)態(tài)地安裝該工具,它通過一個(gè)名為KpiObes的應(yīng)用編程接口(API)來實(shí)現(xiàn)該目的。pproftool主要用于分析cpu運(yùn)行瓶頸需要對(duì)應(yīng)用軟件產(chǎn)生中斷后記錄相關(guān)信息。Gprof、ftrace以及KCachegrind都是基于靜態(tài)的插樁技術(shù),ftrace其本質(zhì)也是靜態(tài)的插樁技術(shù)只是實(shí)現(xiàn)上有所不同。而本文將要采用的跟蹤工具是建立在虛擬機(jī)之上的,不會(huì)對(duì)源代碼插入代碼,因此不會(huì)影響系統(tǒng)執(zhí)行本身的性能。[0006]KCachegrind無法跟蹤到系統(tǒng)調(diào)用,而gprof、ftrace等可以跟蹤到系統(tǒng)調(diào)用但無法跟蹤到系統(tǒng)啟動(dòng)過程,這些問題都將在本文的工具中得到解決。SimSight基于Simics的動(dòng)態(tài)跟蹤工具,與本文設(shè)計(jì)理念最為接近,但SimSight無法給出靜態(tài)與動(dòng)態(tài)相結(jié)合的函數(shù)調(diào)用圖。【
發(fā)明內(nèi)容】[0007]針對(duì)上述問題,本發(fā)明提供一種能夠清楚描述指針函數(shù)以及可加載模塊的調(diào)用關(guān)系的基于寄存器傳輸語言確定動(dòng)態(tài)函數(shù)調(diào)用關(guān)系的方法。[0008]為達(dá)到上述目的,本發(fā)明基于寄存器傳輸語言確定動(dòng)態(tài)函數(shù)調(diào)用關(guān)系的方法,所述方法包括:[0009]在系統(tǒng)運(yùn)行過程中檢測函數(shù)調(diào)用執(zhí)行事件,[0010]若檢測到調(diào)用指令后,解析該指令調(diào)用的函數(shù)入口地址對(duì)應(yīng)的函數(shù)名,統(tǒng)計(jì)指令次數(shù),輸出函數(shù)名、調(diào)用發(fā)生時(shí)間、所屬進(jìn)程號(hào)、所屬線程號(hào)、所屬棧頂指針以及模塊號(hào),并保存到跟蹤數(shù)據(jù)文件;[0011]若檢測的指令是返回指令后,輸出時(shí)間、所屬進(jìn)程號(hào)、所屬線程號(hào)以及所屬棧頂指針到跟蹤數(shù)據(jù)文件;[0012]對(duì)所述跟蹤數(shù)據(jù)文件進(jìn)行處理獲得預(yù)定標(biāo)準(zhǔn)的數(shù)據(jù)格式,將所述跟蹤數(shù)據(jù)文件傳輸至靜態(tài)函數(shù)調(diào)用關(guān)系生成裝置中,生成描述函數(shù)調(diào)用關(guān)系的動(dòng)態(tài)函數(shù)調(diào)用圖。[0013]進(jìn)一步地,所述跟蹤數(shù)據(jù)文件的生成方法包括:[0014]通過對(duì)目標(biāo)文件的解析獲取函數(shù)入口地址對(duì)應(yīng)的函數(shù)名、函數(shù)所在文件及行號(hào)的列表;[0015]解析操作系統(tǒng)內(nèi)核符號(hào)表,獲取函數(shù)入口地址和函數(shù)名,根據(jù)地址和函數(shù)名查找獲取的函數(shù)所在文件及行號(hào)補(bǔ)全函數(shù)信息,并記錄到函數(shù)列表數(shù)組中;[0016]讀取模塊符號(hào)表,獲取模塊的函數(shù)符號(hào)表,并記錄到模塊函數(shù)列表數(shù)組中;[0017]若給定的地址在函數(shù)列表數(shù)組中找到,則返回模塊名和函數(shù)名;[0018]若給定的地址在模塊函數(shù)列表數(shù)組中找到,則返回系統(tǒng)的模塊名和函數(shù)名;[0019]若給定的地址在所述函數(shù)列表數(shù)組和所述模塊函數(shù)列表數(shù)組均找不到,則判斷函數(shù)是否在內(nèi)存中存在,[0020]若在內(nèi)存中存在,則從內(nèi)存中讀取內(nèi)存地址,內(nèi)存的內(nèi)存地址之后一次讀取符號(hào)地址判斷與需查詢地址是否一致,并記錄內(nèi)存位置,從記錄位置讀取內(nèi)存信息為函數(shù)名索引地址,若查到則根據(jù)索引地址和符號(hào)地址起始地址讀取符號(hào)名長度,計(jì)算出所查地址的偏移,獲取函數(shù)名長度,進(jìn)而返回函數(shù)名;[0021]若在內(nèi)存中不存在,則在加載模塊的符號(hào)表中讀取相應(yīng)的函數(shù)名,從模塊中讀取內(nèi)存地址,通過模塊地址獲取模塊的函數(shù)名。[0022]進(jìn)一步地,對(duì)記錄的跟蹤數(shù)據(jù)文件的處理方法包括:補(bǔ)充函數(shù)調(diào)用關(guān)系并轉(zhuǎn)化標(biāo)準(zhǔn)格式和數(shù)據(jù)上傳至靜態(tài)函數(shù)調(diào)用圖生成裝置,[0023]其中所述補(bǔ)充函數(shù)調(diào)用關(guān)系包括:根據(jù)調(diào)用和返回的進(jìn)程號(hào)、線程號(hào)以及棧頂指針來把函數(shù)的調(diào)用和返回進(jìn)行配對(duì),同時(shí)獲取函數(shù)的執(zhí)行時(shí)間,同時(shí)把數(shù)據(jù)轉(zhuǎn)化為標(biāo)準(zhǔn)格式;[0024]所述數(shù)據(jù)上傳至靜態(tài)函數(shù)調(diào)用圖生成裝置包括:[0025]按FROM字段提供的目錄和文件名,把記錄分別復(fù)制到相應(yīng)源代碼文件的動(dòng)態(tài)函數(shù)調(diào)用關(guān)系文件中;[0026]按照每個(gè)動(dòng)態(tài)函數(shù)調(diào)用關(guān)系文件中的TO字段判斷該函數(shù)調(diào)用是否源自該文件,[0027]若不是該文件的則寫入到對(duì)應(yīng)源代碼文件的動(dòng)態(tài)函數(shù)對(duì)外調(diào)用關(guān)系文件,同時(shí)判斷該文件是否源自該目錄,若不是寫入到對(duì)應(yīng)目錄的動(dòng)態(tài)函數(shù)對(duì)外調(diào)用關(guān)系文件;[0028]根據(jù)最后一層目錄的外調(diào)用關(guān)系文件逐層返回上一級(jí)目錄填寫上一級(jí)目錄的外調(diào)用關(guān)系文件。[0029]進(jìn)一步地,所述方法還包括顯示所述函數(shù)調(diào)用關(guān)系圖的步驟,以及對(duì)已生成的函數(shù)調(diào)用關(guān)系圖和列表進(jìn)行緩存的步驟。[0030]本發(fā)明,結(jié)合了函數(shù)調(diào)用圖工具的動(dòng)態(tài)工具能夠?qū)⒅付〞r(shí)間內(nèi)的文件間、模塊間調(diào)用關(guān)系通過連線的形式表示,能夠發(fā)現(xiàn)運(yùn)行時(shí)綁定的指針型函數(shù)調(diào)用以及可加載模塊的函數(shù)調(diào)用。而且由于動(dòng)態(tài)跟蹤的方法給予調(diào)用與返回指令,能夠跟蹤系統(tǒng)啟動(dòng)一部分時(shí)間的函數(shù)調(diào)用關(guān)系,并且該工具還可以和其他動(dòng)態(tài)函數(shù)跟蹤工具結(jié)合,將其他工具的結(jié)果顯/Jnο【專利附圖】【附圖說明】[0031]圖1是本發(fā)明基于寄存器傳輸語言確定動(dòng)態(tài)函數(shù)調(diào)用關(guān)系的方法獲取函數(shù)名和模塊名的流程圖。[0032]圖2是本發(fā)明基于寄存器傳輸語言確定動(dòng)態(tài)函數(shù)調(diào)用關(guān)系的方法的數(shù)據(jù)獲取算法流程圖?!揪唧w實(shí)施方式】[0033]下面結(jié)合說明書附圖對(duì)本發(fā)明做進(jìn)一步的描述。[0034]本實(shí)施例基于寄存器傳輸語言確定動(dòng)態(tài)函數(shù)調(diào)用關(guān)系的方法,所述方法包括:[0035]在系統(tǒng)運(yùn)行過程中檢測函數(shù)調(diào)用執(zhí)行事件,[0036]若檢測到調(diào)用指令后,解析該指令調(diào)用的函數(shù)入口地址對(duì)應(yīng)的函數(shù)名,統(tǒng)計(jì)指令次數(shù),輸出函數(shù)名、調(diào)用發(fā)生時(shí)間、所屬進(jìn)程號(hào)、所屬線程號(hào)、所屬棧頂指針以及模塊號(hào),并保存到跟蹤數(shù)據(jù)文件;[0037]若檢測的指令是返回指令后,輸出時(shí)間、所屬進(jìn)程號(hào)、所屬線程號(hào)以及所屬棧頂指針到跟蹤數(shù)據(jù)文件;[0038]對(duì)所述跟蹤數(shù)據(jù)文件進(jìn)行處理獲得預(yù)定標(biāo)準(zhǔn)的數(shù)據(jù)格式,將所述跟蹤數(shù)據(jù)文件傳輸至靜態(tài)函數(shù)調(diào)用關(guān)系生成裝置中,生成描述函數(shù)調(diào)用關(guān)系的動(dòng)態(tài)函數(shù)調(diào)用圖。[0039]所述跟蹤數(shù)據(jù)文件的生成方法包括:[0040]通過對(duì)目標(biāo)文件的解析獲取函數(shù)入口地址對(duì)應(yīng)的函數(shù)名、函數(shù)所在文件及行號(hào)的列表;[0041]解析操作系統(tǒng)內(nèi)核(system,map)符號(hào)表,獲取函數(shù)入口地址和函數(shù)名,根據(jù)地址和函數(shù)名查找獲取的函數(shù)所在文件及行號(hào)補(bǔ)全函數(shù)信息,并記錄到函數(shù)列表數(shù)組中;[0042]讀取模塊符號(hào)表,獲取模塊的函數(shù)符號(hào)表,并記錄到模塊函數(shù)列表數(shù)組中;[0043]若給定的地址在函數(shù)列表數(shù)組中找到,則返回模塊名和函數(shù)名;[0044]若給定的地址在模塊函數(shù)列表數(shù)組中找到,則返回系統(tǒng)的模塊名(kernel)和函數(shù)名,函數(shù)名通過查表得到;[0045]若給定的地址在所述函數(shù)列表數(shù)組和所述模塊函數(shù)列表數(shù)組均找不到,則判斷函數(shù)是否在內(nèi)存中存在,[0046]若在內(nèi)存中存在,則從內(nèi)存中讀取內(nèi)存地址,內(nèi)存的內(nèi)存地址之后一次讀取符號(hào)地址判斷與需查詢地址是否一致,并記錄內(nèi)存位置,從記錄位置讀取內(nèi)存信息為函數(shù)名索引地址,若查到則根據(jù)索引地址和符號(hào)地址起始地址讀取符號(hào)名長度,計(jì)算出所查地址的偏移,獲取函數(shù)名長度,進(jìn)而返回函數(shù)名;[0047]若在內(nèi)存中不存在,則在加載模塊的符號(hào)表中讀取相應(yīng)的函數(shù)名,從模塊中讀取內(nèi)存地址,通過模塊地址獲取模塊的函數(shù)名。[0048]本實(shí)施例,利用內(nèi)核函數(shù)調(diào)用檢測插件(LinuxCallMonitor)獲取函數(shù)調(diào)用過程中產(chǎn)生的調(diào)用和返回指令,然后通過獲取的內(nèi)核符號(hào)和解析elf文件得到的函數(shù)路徑和行號(hào)信息與指令信息對(duì)應(yīng),獲得更新后的記錄。LinuxCallMonitor插件功能的實(shí)現(xiàn)依賴于內(nèi)核符號(hào)表解析插件(SymbolResolver^PFunctionMonitor插件(虛擬機(jī)-S2E里提供了用于獲取系統(tǒng)內(nèi)函數(shù)調(diào)用指令的探測),通過注冊(cè)塊翻譯事件之后可以使用CallSignal來檢測函數(shù)調(diào)用執(zhí)行事件,檢測到調(diào)用指令后對(duì)該指令調(diào)用的函數(shù)入口地址解析出地址對(duì)應(yīng)的函數(shù)名,統(tǒng)計(jì)指令次數(shù),輸出函數(shù)名、調(diào)用發(fā)生時(shí)間、所屬進(jìn)程號(hào)、所屬線程號(hào)、所屬棧頂指針以及模塊號(hào),并保存到跟蹤數(shù)據(jù)文件。當(dāng)檢測的指令是返回指令時(shí)僅輸出時(shí)間、所屬進(jìn)程號(hào)、所屬線程號(hào)以及所屬棧頂指針到跟蹤數(shù)據(jù)文件[0049]利用SymbolResovler插件與內(nèi)核編譯時(shí)提供的模塊符號(hào)表及解析操作系統(tǒng)可執(zhí)行文件(vmlinux)elf格式獲取函數(shù)名和函數(shù)所在文件行號(hào),獲得包含函數(shù)入口地址、函數(shù)名以及行號(hào)的符號(hào)表。虛擬機(jī)-S2E獲取函數(shù)調(diào)用僅是函數(shù)入口地址,如何正確解析出地址對(duì)應(yīng)的函數(shù)名是動(dòng)態(tài)跟蹤的關(guān)鍵問題。獲取符號(hào)表的方式主要可以分為兩種目標(biāo)文件中的符號(hào)表和系統(tǒng)運(yùn)行時(shí)內(nèi)存中的符號(hào)表。目標(biāo)文件中的符號(hào)表可分為三類:本文件中的全局符號(hào)、本文件引用了的其它文件中的全區(qū)符號(hào)以及本文件中的本地符號(hào),對(duì)于這些符號(hào)表可以使用GNUbinutils提供的nm獲取,但只能獲取內(nèi)核自身的符號(hào)表,對(duì)內(nèi)核運(yùn)行時(shí)加載的模塊內(nèi)的符號(hào)則無能為力,而S2E作為運(yùn)行在主機(jī)上的虛擬機(jī),我們可以通過從客戶機(jī)的內(nèi)存里直接獲取和查找符號(hào)表。[0050]Linux2.6以后的版本引入了kallsyms功能,kallsyms是把內(nèi)核中所用到的所有符號(hào)地址和名稱連接進(jìn)了內(nèi)核文件,從而使得內(nèi)核啟動(dòng)后會(huì)把kallsyms的信息加載到內(nèi)存中方便內(nèi)核調(diào)試。因此通過kallsyms機(jī)制的實(shí)現(xiàn)使得內(nèi)存也存有一份System,map,因而可以利用kallsyms機(jī)制的原理來提取內(nèi)核中的符號(hào)表,并且此表包含了系統(tǒng)啟動(dòng)后加載模塊的符號(hào)信息。`[0051]對(duì)記錄的跟蹤數(shù)據(jù)文件的處理方法包括:補(bǔ)充函數(shù)調(diào)用關(guān)系并轉(zhuǎn)化標(biāo)準(zhǔn)格式和數(shù)據(jù)上傳至靜態(tài)函數(shù)調(diào)用圖生成裝置,[0052]其中所述補(bǔ)充函數(shù)調(diào)用關(guān)系包括:根據(jù)調(diào)用和返回的進(jìn)程號(hào)、線程號(hào)以及棧頂指針來把函數(shù)的調(diào)用和返回進(jìn)行配對(duì),同時(shí)獲取函數(shù)的執(zhí)行時(shí)間,同時(shí)把數(shù)據(jù)轉(zhuǎn)化為標(biāo)準(zhǔn)格式;[0053]所述數(shù)據(jù)上傳至靜態(tài)函數(shù)調(diào)用圖生成裝置包括:[0054]按FROM字段提供的目錄和文件名,把記錄分別復(fù)制到相應(yīng)源代碼文件的動(dòng)態(tài)函數(shù)調(diào)用關(guān)系文件dynfctrlt)中;[0055]按照每個(gè)動(dòng)態(tài)函數(shù)調(diào)用關(guān)系文件(.dynfctrlt)文件中的TO字段函數(shù)是否源自該文件,[0056]若不是該文件的則寫入到相應(yīng)源代碼文件的動(dòng)態(tài)函數(shù)對(duì)外調(diào)用關(guān)系文件(.dynoutlst),同時(shí)判斷該文件是否源自該目錄,若不是寫入到對(duì)應(yīng)目錄的動(dòng)態(tài)函數(shù)對(duì)外調(diào)用關(guān)系文件CdynDoutlst);[0057]根據(jù)最后一層目錄的動(dòng)態(tài)函數(shù)對(duì)外調(diào)用關(guān)系文件(.dynDoutlst)文件逐層返回上一級(jí)目錄填寫上一級(jí)目錄的.dynDoutlst文件。[0058]進(jìn)一步地,所述方法還包括顯示所述函數(shù)調(diào)用關(guān)系圖的步驟,以及對(duì)已生成的函數(shù)調(diào)用關(guān)系圖和列表進(jìn)行緩存的步驟,該步驟通過瀏覽器實(shí)現(xiàn)。[0059]所述方法具體運(yùn)行過程如下:[0060]第一步,環(huán)境要求以及必要的軟件包的安裝:[0061]1、主機(jī)環(huán)境ubuntu6412.0464位[0062]2、需要安裝的包:[0063]$sudoapt-getinstallbuild-essential[0064]$sudoapt-getinstallsubversion[0065]$sudoapt-getinstallgit[0066]$sudoapt-getinstallgettext[0067]$sudoapt-getinstallliblua5.l_dev[0068]$sudoapt-getinstalllibsdll.2~dev[0069]$sudoapt-getinstalllibsigc++_2.0_dev[0070]$sudoapt-getinstallbinutils-dev[0071]$sudoapt-getinstallpython-docutils[0072]$sudoapt-getinstallpython-pygments[0073]$sudoapt-getinstallnasm[0074]$sudoapt-getbuild-depllvm-3.0[0075]$sudoapt-getbuild-depqemu[0076]3、下載s2e的安裝包并安裝s2e[0077]$mkdirS2EDIR[0078]$cd$S2EDIR[0079]$gitclonehttps://github.com/dslab_epfl/s2e.git[0080]$mkdirbuild[0081]$cdbuild[0082]$make-f/s2e/Makefile[0083]第二步,環(huán)境要求以及必要的軟件包的安裝:[0084]1、LinuxCallMonitor插件[0085]A、注冊(cè)onTranslateBlockStart事件[0086]B、獲取調(diào)用和返回指令[0087]C、調(diào)用符號(hào)表獲取函數(shù)名、模塊名[0088]D、輸出調(diào)用事件包含函數(shù)名、模塊名、事件發(fā)生時(shí)間、當(dāng)前進(jìn)程號(hào)、當(dāng)前線程號(hào)以及當(dāng)前棧頂指針[0089]具體內(nèi)容如下:[0090]1.1初始化initialize[0091]裝載SymbolResolver,F(xiàn)unctionMonitor:(s2e()->getPlugin(“,,));[0092]打開第一個(gè)寫文件XXX-FuncTracer—00000.dat[0093]注冊(cè)塊翻譯事件(onTranslateBlockStart)[0094]1.2s1tTransIateBlockStart事件[0095]通過CallSignal檢測call執(zhí)行事件,[0096]檢測到call事件通過calIHandler處理該事件[0097]1.3calIHandler[0098]通過地址獲取相應(yīng)函數(shù)名:SymbolResolver中的symtab_search函數(shù)實(shí)現(xiàn);[0099]同時(shí)計(jì)算call和ret事件的次數(shù),如果次數(shù)超過20000000,則打開一個(gè)新的寫文件,同時(shí)計(jì)數(shù)清零;[0100]注冊(cè)ret執(zhí)行的回調(diào)函數(shù),檢測函數(shù)的返回并處理返回信息retHandler;[0101]輸出事件發(fā)生時(shí)間、進(jìn)程號(hào)、線程號(hào)、棧頂指針、模塊名、函數(shù)名。[0102]1.4retHandler[0103]計(jì)算calI和ret的次數(shù),如果次數(shù)超過20000000,則打開一個(gè)新的寫文件,同時(shí)計(jì)數(shù)清零;[0104]輸出事件發(fā)生時(shí)間、進(jìn)程號(hào)、線程號(hào)、棧頂指針。[0105]2、SymbolResolver插件[0106]A、獲取內(nèi)核、模塊符號(hào)表[0107]B、解析vmlinux文件elf格式獲取函數(shù)名和函數(shù)所在行號(hào)[0108]C、形成符號(hào)列表:地址,函數(shù)名,函數(shù)所在行號(hào)[0109]2.1初始化initialize[0110]加載system,map、vmlinux;[0111]調(diào)用reacLvmO獲取函數(shù)入口地址對(duì)應(yīng)的函數(shù)名、函數(shù)所在文件及行號(hào)的列表;[0112]讀取system,map,解析該符號(hào)表,根據(jù)地址和函數(shù)名以及read_vm()獲取的函數(shù)所在文件及行號(hào),補(bǔ)全函數(shù)信息,并記錄到函數(shù)列表數(shù)組中addrsym_tab[];根據(jù)符號(hào)信息記錄符號(hào)表開始結(jié)束以及其它地址信息,主要有:—start—ksymtab、—stop—ksmtab、kallsyms_addresses(所有符號(hào)地址)、kallsyms_num_syms(符號(hào)總數(shù))、kallsyms_names、kalIsyms_markers、kailsyms_token_table、kailsyms_token_index、modules,它們對(duì)應(yīng)的地址信息。[0113]讀取模塊符號(hào)表,獲取模塊的函數(shù)符號(hào)表,并記錄到數(shù)組中addrmod_tab[]。[0114]2.2symtab_search[0115]根據(jù)地址返回函數(shù)名、函數(shù)所在文件及行號(hào)。[0116]如果給定的地址在addrsym_tab[]找到,則返回kernel(模塊名)和函數(shù)名;[0117]如果給定的地址在addrmod_tab[]找到,則返回模塊名(系統(tǒng))和函數(shù)名;[0118]否則:[0119]從內(nèi)存中讀取kallsyms_num_syms(符號(hào)總數(shù));從存中kallsyms_addresses之后一次讀取符號(hào)地址判斷與需查詢地址是否一致,并記錄內(nèi)存位置;從記錄位置讀取內(nèi)存信息為函數(shù)名索引地址,如果查到則根據(jù)索引地址和符號(hào)地址起始地址讀取符號(hào)名長度,計(jì)算出所查地址的偏移,獲取函數(shù)名長度,進(jìn)而返回函數(shù)名;否則在加載模塊的符號(hào)表中讀取相應(yīng)的函數(shù)名[0120]2.3search_func_line、read_vm、describe_elf_hdr>dir_file_table>describe_one_section、describe_elf_sections>dwarf_tag_name>dwarf_attr_name>is_compile_unit、output_compiIation_unit_header>read_l_byte、read_signed_lebl28、describe_one—compile—unit等是解析vmlinux文件的elf格式獲取函數(shù)入口地址以及對(duì)應(yīng)函數(shù)名及函數(shù)所在文件行號(hào)的函數(shù)和依賴函數(shù),這里不在敘述其原理和過程。[0121]第三步,編譯s2e、運(yùn)行s2e:[0122]1、修改Makefile,target[0123]2、修改s2e/qemu/Makefile.target文件:[0124]在s2eobj-y+=s2e/Plugins/ConsistencyModels.ο之后添加兩行:[0125]s2eobj-y+=s2e/Plugins/LinuxCalIMonitor.ο[0126]s2eobj-y+=s2e/Plugins/SymboIeResoIver.ο[0127]3、編譯s2e[0128]4、編譯對(duì)應(yīng)版本的內(nèi)核,本項(xiàng)目的是linux-3.5.4,cpu是32位:即makei386—defconfig0[0129]為了獲取函數(shù)定義行號(hào),因而在編譯內(nèi)核時(shí)需要勾選debug信息:menuconfig中Kernelhacking選項(xiàng),選中kerneldebugging和Compilekernelwithdebuginfo。[0130]編譯完成后arch/x86/boot/bzIamge,vmliux,System,map,在s2e運(yùn)行中需要用到的。[0131]5、配置config.1ua[0132]【權(quán)利要求】1.一種基于寄存器傳輸語言確定動(dòng)態(tài)函數(shù)調(diào)用關(guān)系的方法,其特征在于:所述方法包括:在系統(tǒng)運(yùn)行過程中檢測函數(shù)調(diào)用執(zhí)行事件,若檢測到調(diào)用指令后,解析該指令調(diào)用的函數(shù)入口地址對(duì)應(yīng)的函數(shù)名,統(tǒng)計(jì)指令次數(shù),輸出函數(shù)名、調(diào)用發(fā)生時(shí)間、所屬進(jìn)程號(hào)、所屬線程號(hào)、所屬棧頂指針以及模塊號(hào),并保存到跟蹤數(shù)據(jù)文件;若檢測的指令是返回指令后,輸出時(shí)間、所屬進(jìn)程號(hào)、所屬線程號(hào)以及所屬棧頂指針到跟蹤數(shù)據(jù)文件;對(duì)所述跟蹤數(shù)據(jù)文件進(jìn)行處理獲得預(yù)定標(biāo)準(zhǔn)的數(shù)據(jù)格式,將所述跟蹤數(shù)據(jù)文件傳輸至靜態(tài)函數(shù)調(diào)用關(guān)系生成裝置中,生成描述函數(shù)調(diào)用關(guān)系的動(dòng)態(tài)函數(shù)調(diào)用圖。2.根據(jù)權(quán)利要求1所述的基于寄存器傳輸語言確定動(dòng)態(tài)函數(shù)調(diào)用關(guān)系的方法,其特征在于:所述跟蹤數(shù)據(jù)文件的生成方法包括:通過對(duì)目標(biāo)文件的解析獲取函數(shù)入口地址對(duì)應(yīng)的函數(shù)名、函數(shù)所在文件及行號(hào)的列表;解析操作系統(tǒng)內(nèi)核符號(hào)表,獲取函數(shù)入口地址和函數(shù)名,根據(jù)地址和函數(shù)名查找獲取的函數(shù)所在文件及行號(hào)補(bǔ)全函數(shù)信息,并記錄到函數(shù)列表數(shù)組中;讀取模塊符號(hào)表,獲取模塊的函數(shù)符號(hào)表,并記錄到模塊函數(shù)列表數(shù)組中;若給定的地址在函數(shù)列表數(shù)組中找到,則返回模塊名和函數(shù)名;若給定的地址在模塊函數(shù)列表數(shù)組中找到,則返回系統(tǒng)的模塊名和函數(shù)名;若給定的地址在所述函數(shù)列表數(shù)組和所述模塊函數(shù)列表數(shù)組均找不到,則判斷函數(shù)是否在內(nèi)存中存在,若在內(nèi)存中存在,則從內(nèi)存中讀取內(nèi)存地址,內(nèi)存的內(nèi)存地址之后一次讀取符號(hào)地址判斷與需查詢地址是否一致,并記錄內(nèi)存位置,從記錄位置讀取內(nèi)存信息為函數(shù)名索引地址,若查到則根據(jù)索引地址和符號(hào)地址起始地址讀取符號(hào)名長度,計(jì)算出所查地址的偏移,獲取函數(shù)名長度,進(jìn)而返回函數(shù)名;若在內(nèi)存中不存在,則在加載模塊的符號(hào)表中讀取相應(yīng)的函數(shù)名,從模塊中讀取內(nèi)存地址,通過模塊地址獲取模塊的函數(shù)名。3.根據(jù)權(quán)利要求1所述的基于寄存器傳輸語言確定動(dòng)態(tài)函數(shù)調(diào)用關(guān)系的方法,其特征在于:對(duì)記錄的跟蹤數(shù)據(jù)文件的處理方法包括:補(bǔ)充函數(shù)調(diào)用關(guān)系并轉(zhuǎn)化標(biāo)準(zhǔn)格式和數(shù)據(jù)上傳至靜態(tài)函數(shù)調(diào)用圖生成裝置,其中所述補(bǔ)充函數(shù)調(diào)用關(guān)系包括:根據(jù)調(diào)用和返回的進(jìn)程號(hào)、線程號(hào)以及棧頂指針來把函數(shù)的調(diào)用和返回進(jìn)行配對(duì),同時(shí)獲取函數(shù)的執(zhí)行時(shí)間,同時(shí)把數(shù)據(jù)轉(zhuǎn)化為標(biāo)準(zhǔn)格式;所述數(shù)據(jù)上傳至靜態(tài)函數(shù)調(diào)用圖生成裝置包括:按FROM字段提供的目錄和文件名,把記錄分別復(fù)制到相應(yīng)源代碼文件的動(dòng)態(tài)函數(shù)調(diào)用關(guān)系文件中;按照每個(gè)動(dòng)態(tài)函數(shù)調(diào)用關(guān)系文件文件中的TO字段判斷該函數(shù)調(diào)用是否源自該文件,若不是該文件的則寫入到對(duì)應(yīng)源代碼文件的動(dòng)態(tài)函數(shù)對(duì)外調(diào)用關(guān)系文件,同時(shí)判斷該文件是否源自該目錄,若不是寫入到對(duì)應(yīng)目錄的動(dòng)態(tài)函數(shù)對(duì)外調(diào)用關(guān)系文件;根據(jù)最后一層目錄的動(dòng)態(tài)函數(shù)對(duì)外調(diào)用關(guān)系文件逐層返回上一級(jí)目錄填寫上一級(jí)目錄的動(dòng)態(tài)函數(shù)對(duì)外調(diào)用關(guān)系文件。4.根據(jù)權(quán)利要求1所述的基于寄存器傳輸語言確定動(dòng)態(tài)函數(shù)調(diào)用關(guān)系的方法,其特征在于:所述方法還包括顯示所述函數(shù)調(diào)用關(guān)系圖的步驟,以及對(duì)已生成的函數(shù)調(diào)用關(guān)系圖和列表進(jìn)行緩存的步驟?!疚臋n編號(hào)】G06F9/44GK103761089SQ201410015881【公開日】2014年4月30日申請(qǐng)日期:2014年1月14日優(yōu)先權(quán)日:2014年1月14日【發(fā)明者】向勇,湯衛(wèi)東,杜香燕,孫衛(wèi)真,馬東超,鄧雪峰申請(qǐng)人:清華大學(xué)