?

基于動態二進制翻譯和插樁的函數調用跟蹤

2019-02-20 08:34盧帥兵林哲超況曉輝
計算機研究與發展 2019年2期
關鍵詞:指令集二進制寄存器

盧帥兵 張 明 林哲超 李 虎 況曉輝 趙 剛

(信息系統安全技術國家重點實驗室(軍事科學院) 北京 100101)

函數調用分析在軟件安全[1]、程序邏輯[2]、漏洞挖掘[3]等領域有著廣泛的應用.特別是Linux內核的開發與調試需要處理大量復雜的函數,其調用關系對內核分析與調試有很大幫助[4].函數調用分析包括靜態分析與動態分析2種方法:

1) 靜態分析.根據源代碼進行代碼審計,得到從入口函數到退出函數的整個執行路徑.靜態分析面向特定的編程語言源碼,進行詞法語法分析,技術成熟.但是間接分支指令、間接函數調用和動態生成代碼在靜態條件下很難獲取執行路徑,因此靜態調用關系并不能反映出真實的調用序列信息.

2) 動態分析.為了能獲取程序執行時真實的函數調用關系,需要在程序運行時記錄函數調用信息,動態跟蹤函數執行路徑.動態分析方法解決了間接分支目標地址的不確定性問題,可得到軟件實時調用序列、各函數的運行時間、調用次數、前后依賴等信息.

現有函數調用動態分析工具包括GNU binutils工具集的gprof[5],ftrace,systemtap,dtrace等.上述工具需要特定的使用條件,不能完全滿足當前的開發調試需要.gprof僅支持啟動用戶態可執行程序,不能用于內核分析;ftrace需要編譯內核時打開編譯選項,造成多種編譯優化手段無法進行;systemtap與dtrace需要操作系統運行時提供接口,操作系統啟動階段無法使用.

為彌補上述工具的不足,基于模擬器的函數跟蹤技術直接分析二進制鏡像,不需額外的編譯選項,成為內核分析技術的重要方面.使用模擬器對函數調用關系進行動態跟蹤,避免對內核源碼的插樁和編譯過程,減少對內核的影響.S2E(selective symbolic execution)[6]基于QEMU[7]和符號執行技術,提供插件接口獲取操作系統運行時狀態、函數調用關系等,支持x86,x86-64,arm平臺.但是S2E運行速度慢,缺乏對其他平臺如MIPS,Alpha等的支持.向勇等人[8]提出基于QEMU的動態函數調用跟蹤框架,通過關閉基本塊鏈接功能,迫使每個基本塊代碼執行結束后進行基本塊切換操作,切換過程中統計函數信息,并寫入日志.相比S2E提高了分析性能和支持的CPU平臺種類,但是該方法依賴于QEMU的日志并必須關閉QEMU的基本塊鏈接功能,造成3.65倍的性能開銷.

上述工具基于QEMU模擬器進行函數調用跟蹤,并實現對系統狀態的監測與分析,但是監測數據獲得的方法破壞了QEMU的模擬和加速機制,造成較大的性能開銷.如何精確記錄系統的行為并且不破壞QEMU模擬器的加速機制是亟待解決的問題.

通過分析QEMU的運行機制,我們發現QEMU使用平臺無關的中間表示進行不同平臺指令集的支持,而源指令到中間表示的翻譯過程和中間表示到宿主機平臺指令的過程都可以在中間表示層進行插樁獲取翻譯記錄.據此,本文提出基于動態二進制翻譯和代碼插樁的函數調用跟蹤框架,在二進制翻譯的中間代碼階段,針對特定函數調用和返回指令進行特殊處理,插入性能分析和信息獲取樁指令塊,從而在運行時獲取系統啟動與函數調用順序.基于二進制翻譯技術,避免了對源碼的依賴,并提供跨平臺支持;在中間代碼階段的代碼插入技術,減少了對源平臺和目標平臺的依賴,降低了系統復雜度,性能開銷.

本文的主要貢獻如下:

1) 提出一種基于二進制翻譯的支持多平臺的內核函數調用跟蹤框架,在二進制翻譯的中間代碼階段,生成用于特定信息獲取的指令,而不需重編譯內核鏡像文件;

2) 基于二進制翻譯的方法,大大擴展了可支持平臺的種類,便于支持新型平臺;

3) 不影響二進制翻譯技術中基本塊鏈接、冗余代碼消除、熱路徑分析等優化技術,運行效率高.

1 基于動態二進制翻譯和代碼插樁的函數調用跟蹤框架

1.1 動態二進制翻譯

二進制翻譯是軟件安全分析[9]、系統分析[10]、軟件優化[11]等領域的關鍵技術.主流的二進制翻譯分為靜態二進制翻譯和動態二進制翻譯.動態二進制翻譯在執行時根據程序執行路徑以基本塊為單位進行實時加載、翻譯、生成目標代碼、執行、緩存管理、代碼優化等任務,解決了間接分支指令目的地址不確定性、動態生成代碼的翻譯問題,具有較好的完備性,是二進制翻譯的主流技術,其工作原理如圖1所示:

Fig. 1 Dynamic binary translation圖1 動態二進制翻譯

Fig. 2 Dynamic binary translation and code instrumentation based function call tracing framework圖2 基于動態二進制翻譯和代碼插樁的函數調用跟蹤框架

首先,加載二進制鏡像文件,二進制文件通常為ELF,PE或者Linux內核格式,分析指令入口點PC(program counter),完成內存映射、CPU初始化、虛擬設備創建等工作,并進入翻譯過程.由于程序運行的局部性,對已翻譯的基本塊進行緩存可大大節省翻譯開銷.動態二進制翻譯在執行某一基本塊前,首先從緩存中查找,若該基本塊已經翻譯,則切換環境后進入執行階段;否則,需要根據當前指令基本塊首地址讀取指令直到下一條分支指令,轉化為中間代碼(intermediate representation, IR),最后生成目標指令集(instruction set architecture, ISA)代碼并執行.執行完當前基本塊后進入下一個基本塊并重復上述查找、翻譯、執行過程,直到程序結束.從動態二進制翻譯的翻譯執行流程可以看出,以基本塊為單位,翻譯過程與執行過程交替進行,能夠對不同平臺的代碼進行翻譯轉換,解決了多平臺指令集支持的問題,極大地增大了軟件的適用性.

本文基于動態二進制翻譯的系統調用跟蹤,方便地支持多種指令集,并提供了指令和基本塊粒度的信息統計和代碼插入方法,可獲取的信息量大大增加.

1.2 代碼插樁

代碼插樁技術是軟件調試中采用的代碼修改機值,包括目標代碼插樁和源代碼插樁,通過插樁點實時獲取程序狀態,廣泛應用于性能分析、覆蓋測試、軟件調試等領域[12-13].

源代碼插樁技術通過對程序源代碼的詞法分析、語法分析、語義分析等,確定插樁位置,依賴于特定的編程語言,工作量大.例如gprof,ftrace,systemtap都使用到了源代碼插樁技術.

目標代碼插樁技術通過對目標代碼進行相應的分析,分析確定插樁點,與具體的指令集相關,不依賴程序源碼,與具體的編程語言和版本無關.本文針對目標代碼,在指令粒度進行插樁,提升了檢測信息的精確度.

1.3 框架設計思路

為支持多種平臺二進制鏡像,實現指令粒度的代碼插樁,實時獲取執行信息、內核加載過程信息、函數調用關系信息等,提出基于動態二進制翻譯和代碼插樁的函數調用跟蹤框架,框架模塊如圖2所示.

1) 通過二進制翻譯系統,載入內核鏡像;

2) 對操作系統內核進行分析并確定指令集類型、入口點;

3) 對需要執行的基本塊進行二進制翻譯,在中間代碼階段,針對特殊的函數調用與返回指令插入樁指令;

4) 最后在執行階段,每次執行函數調用和返回指令,都會執行插入的樁代碼,獲取模擬時鐘、進程地址、函數地址等.

該框架充分利用了動態二進制翻譯系統的整體流程,以指令粒度分析插樁點,動態將樁代碼插入到生成的目標碼中,實現了實時信息獲取功能.

2 基于QEMU和代碼插樁的函數調用跟蹤系統實現

根據第1節函數調用跟蹤框架的原理,基于開源的二進制翻譯系統QEMU,進行樁代碼設計、中間代碼樁標記碼和目標代碼的進入樁插入、監測信息處理等開發工作,實現了基于QEMU和代碼插樁的函數調用跟蹤系統.

2.1 快速的處理器模擬器QEMU

QEMU是一個快速的處理器模擬器,支持多種源平臺和多種目標平臺[14].利用平臺無關的中間表示形式TCG(tiny code generator),實現將x86,arm,Alpha,PowerPC等指令集轉換為TCG中間表示,然后翻譯為宿主機的指令集,具備快速模擬和跨平臺支持特性.作為模擬器可模擬多種設備、硬件,支持全系統運行,可在宿主機運行不同指令集的客戶機.

QEMU以基本塊為單位對源指令進行翻譯,提供了代碼緩存管理、基本塊鏈接、冗余代碼消除等優化,提升了模擬器速度.QEMU的執行流程如圖3所示.首先,QEMU加載源指令集的可執行文件或者內核鏡像,完成空間申請、地址映射、入口點分析等工作后從第1條指令開始進入翻譯執行的過程.以基本塊為單位,讀取源指令集的指令序列,生成對應的TCG中間表示,然后分析優化后生產宿主機指令集的代碼,并將動態生成的代碼存入緩存,實現一次翻譯多次使用.在基本塊執行完畢后,模擬器試圖查找下一個基本塊對應的代碼,如果在緩存代碼區找到需要的代碼塊,則直接跳轉執行,否則需要啟動翻譯過程.由于每次基本塊執行完畢后進行查找下一個基本塊引起較大開銷,QEMU實現基本塊鏈接功能,把下一個基本塊和當前塊直接使用跳轉指令連接起來,避免了查找消耗.基本塊鏈接技術極大地提高了模擬器的運行效率,是QEMU模擬器的高效率關鍵技術.

Fig. 3 Framework of QEMU圖3 QEMU框架結構

從QEMU的運行原理可以看出,QEMU使用了平臺無關中間表示TCG,是典型的動態二進制翻譯系統.可在TCG階段對需要檢測的指令進行操作,插入所需統計信息樁代碼,在運行時獲取函數調用信息.

2.2 函數調用指令翻譯

QEMU進行二進制翻譯采用的平臺無關中間表示是TCG,曾作為支持多平臺的C語言交叉編譯器的后端,是一種類似于RISC的指令集.TCG僅支持32 b和64 b整型,指針類型是根據宿主機的位數按照32 b或64 b整型定義的.QEMU把源指令變換為TCG操作,進行活性分析、常量計算優化,然后變換為對應宿主機指令集的指令序列.例如指令add_i32t0,t1,t2表示t1+t2的和放到t0寄存器中,操作數t0,t1,t2都是32 b整型.

函數調用指令會更改程序執行順序,并修改棧內容,TCG針對函數調用遵循以下規則:

1) 參數和返回值的類型僅支持32 b,64 b整型和指針.

2) 棧向下填充.

3) 前N個參數通過寄存器傳遞,超過N個參數的以字為單位放入棧傳遞.N在文件中可根據具體平臺自定義.

4) 一些寄存器在函數調用過程中會被重復使用.

5) 函數可以使用寄存器返回0或1.在32 b宿主機上運行64 b系統時,為了能夠返回64 b值,必須使用寄存器返回2個32 b值.

這些規則限定了函數調用指令處理的方法,一條函數調用指令會被分解為參數傳遞操作、棧修改操作、分支跳轉操作3部分.

為了插入用于信息統計的樁代碼,添加新的TCG中間表示,在分支跳轉操作前插入gen_stubc TCG指令,用以生成調用樁代碼的指令序列.例如指令call 0x7fac6ee插入gen_stubc后的翻譯過程如圖4所示,可以看到生成了call stubc的中間代碼指令和對應的目標平臺指令“mov $0x56333978b660,%r10;callq*%r10”,其中地址$0x56333978b660為樁代碼helper_stubc在內存中的位置.

Fig. 4 Translation of call instruction with instrumentation code圖4 插樁后的call指令翻譯過程

2.3 樁代碼設計

樁代碼是在動態翻譯的過程中,插入到函數調用和返回指令對應目標代碼中,完成信息獲取的代碼段.樁代碼需要完成信息監測功能,同時不能對原有代碼的語義造成影響.

每次函數調用和函數返回都調用樁代碼,記錄實時操作信息,使得獲取從第1條指令到最后啟動完成全局的調用信息;需要完成信息監測功能,同時不能對原有代碼的語義造成影響;執行的次數非常多,盡量保持簡短.

考慮以上因素,結合QEMU具體實現,采用helper機制調用樁代碼.QEMU在進行指令翻譯的過程中,會遇到語義復雜的指令,例如,這類指令如果使用宿主平臺匯編指令實現其功能非常復雜,以至于生成的目標代碼極其龐大,易出錯.為了兼顧效率與靈活性,QEMU使用特定的helper函數實現此類功能復雜型指令的模擬操作.例如使用tcg_gen_helper_x_y可以生成調用參數為32 b,64 b或指針的函數.默認情況下,在調用helper函數時,所有的全局變量將會保存到對應env的位置,以防helper修改某些寄存器的值.一個helper函數是可以訪問模擬器CPU狀態變量env的.利用helper機制,可方便的在函數調用和返回處調用helper的stub樁代碼,訪問全局CPU狀態變量env,完成信息記錄功能.

2.4 針對x86指令集的樁代碼設計

使用QEMU的helper機制,針對x86指令集進行代碼插樁的方法如下,首先在targeti386helper.h中添加定義DEF_HELPER_2(stub_call,void,env,tl)其中stub_call是helper函數名,void是返回值,env,tl是參數類型,表示函數voidhelper_stub_call(CPUx86State*env,target_ulongval)的聲明,類似的DEF_HELPER_2(stub_ret,void,env,tl)表示ret指令的返回嵌入樁代碼.然后,在translate.c中對call,ret指令翻譯的響應位置,插入gen_helper生成調用helper_stub_call,helper_stub_ret的TCG指令,其中使用gen_helper在翻譯時首先會把模擬CPU的寄存器值保存到內存中,防止內部代碼執行影響寄存器內容;最后,在targeti386misc_helper.c中實現2個函數.樁代碼的功能如圖5所示,使用全局的信息結構體env保存包括時間戳、進程ID、調用地址、當前函數地址、函數名稱等信息,并使用全局的call_info_arr數組把所有函數調用和返回的信息進行保存.然后調用QEMU內置函數QEMU_clock_get_ns()獲取模擬時鐘,通過CPUx86State結構體的寄存器值,分別獲取ESP值、進程ID、調用函數地址、當前函數地址并存入全局數組;最后樁代碼執行完畢,回到基本塊,繼續執行后續代碼.

Fig. 5 Instrumentation code of x86
圖5 針對x86平臺的樁代碼

2.5 針對ARM指令集的樁代碼設計

ARM指令集是目前移動平臺使用最廣泛的指令集,ARM屬于精簡指令集,有31個32 b的通用寄存器,其中有3個寄存器SP(stack pointer)、LR(link register)、PC有特殊的用途.

通常R13作為棧指針寄存器存儲棧指針SP,pop和push指令使用R13的值訪問??臻g.

R14作為鏈接寄存器LR.當使用分支鏈接指令(BL,BLX)指令時,該寄存器保存當前分支鏈接指令的下一條指令的地址.在函數調用結束返回時,R14作為返回的地址,其他時候R14可作為通用寄存器使用.因此在進行函數調用跟蹤時,可通過訪問R14獲得返回地址.

R15作為程序計數器PC,由于ARM體系結構采用了多級流水線技術,對于ARM指令集而言,PC總是指向當前指令的下2條指令的地址,即PC的值為當前指令的地址值加8 B程序狀態寄存器.

頁表轉換基寄存器(TTBR),CP15的第2個寄存器存放當前進程的物理基地址,在QEMU模擬ARM類型的CPU時使用CP15.ttbr0_el[2]表示該值.

ARM指令集使用BL,BLX進行子程序調用時,把返回地址存儲到LR,但是沒有專門的返回指令,而是通過把LR的值傳入PC寄存器中的方法.通常使用如下4種函數返回方法:

MOV PC,LR或BX LR

該MOV指令直接把LR寄存器的值復制到PC寄存器,更改程序執行流程,使函數返回到LR存儲的地址處.同樣BX LR直接把LR寄存器中的返回地址作為無條件跳轉目的地址,完成函數返回操作.

或者stmfd與ldmfd,push,pop指令在函數入口處執行入棧并在函數結束時執行出棧操作來更改程序執行流程.使用在函數入口處使用如下指令保存寄存器狀態:

即保存通用寄存器和LR的值到棧中,函數體執行完畢需要返回時,恢復CPU狀態,

以上4種方式是常用的函數返回方法,在進行函數調用跟蹤時,需要在翻譯階段判斷這4種情況,并生成調用的樁代碼的TCG指令.

根據ARM指令的函數調用和返回方法以及特殊寄存器的使用方式,設計ARM平臺的樁代碼如圖6所示:

Fig. 6 Instrumentation code of ARM
圖6 針對ARM平臺的樁代碼

2.6 針對MIPS指令集的樁代碼設計

MIPS指令集廣泛應用在交換設備、移動設備、嵌入式微控制器等產品,屬于精簡指令集,有32個通用寄存器,其中寄存器$29用作棧寄存器$sp,$31寄存器用作返回地址寄存器$ra.函數調用指令使用Motorala命名法,子程序調用成為跳轉并鏈接,助記符以al結尾,例如jal imm或jalr $reg該指令首先把C寄存器保存到$ra,然后跳轉到立即數imm或$reg指向的指令塊.函數返回時,使用jr $ra跳轉到保存的指令地址$ra,完成函數返回操作.若被調用函數再次調用其他函數,那么$ra的值會先存入??臻g,子函數執行結束后,重新載入$ra的值,進行返回.類似的,使用bal,bgezal,bltzal進行相對PC偏移的函數調用,返回值會存儲到$ra中.在翻譯階段對上述子程序調用指令和函數返回指令生成調用樁代碼的TCG指令,實現函數調用跟蹤.

我們使用當前進程的物理地址作為唯一標識,以區分不同的進程.MIPS為每個進程分配了地址空間ID,稱為ASID(address space id),在進行TLB轉換時,使用ASID和虛擬頁號(virtual page number, VPN)拼接成唯一的頁地址,映射到物理地址,因此可以使用ASID拼接VPN作為當前進程的標識.QEMU實現了MIPS的ASID,VPN保存在env→CP0_EntryHi中.根據MIPS指令集和寄存器特點,針對MIPS指令集的樁代碼設計如圖7所示:

Fig. 7 Instrumentation code of MIPS
圖7 針對MIPS平臺的樁代碼

以上給出了x86,ARM,MIPS指令集的樁代碼設計方法,可以看出樁代碼從全局環境結構體env中直接讀取相應信息,代碼簡短、直接,可很快根據具體平臺要求,具有多平臺支持的特點,其他平臺可根據寄存器的使用特點,很方便地移植到需要支持的指令集構架平臺上.

2.7 日志記錄與函數調用圖

日志記錄包括call記錄和ret記錄,call記錄需保存調用時間、進程標識、線程標識、被調用函數地址、被調用函數名稱;而ret記錄包括調用時間、進程標識、線程標識即可.例如在時刻592092451ns函數start_kernel被調用,接著函數start_kernel調用了set_task_stack_end_magic,smp_setup_processor_id記錄如圖8所示:

Fig. 8 Example of the logs
圖8 日志記錄示例

通過樁代碼的統計,獲取了對應信息,需結合分析二進制鏡像獲取符號表中函數名稱,即可把call_info結構體中的function_name確定,從而形成完整的統計,按照相關工具進行輸出,生成函數調用圖,本文使用graphviz[15]工具生成函數調用圖,如圖9所示start_kernel執行時的函數調用關系.該可視化工作已有相關研究,可結合已有相關解析工具和算法[16],不作為本文的主要工作.

Fig. 9 Example of function call map of Linux 4.9 kernel圖9 函數調用跟蹤Linux 4.9內核繪圖示例

3 與現有工作的比較

現有的基于模擬器的函數調用跟蹤工具有S2E和向勇所提出的基于QEMU的動態函數調用跟蹤框架不妨記為QEMU-DFCT(QEMU-based dynamic function call tracing).下面將本文所提出的方案分別與S2E,QEMU-DFCT進行對比.

3.1 與S2E對比

3.1.1 功能性比較

S2E結合了符號執行和QEMU,并提供插件發布、訂閱、處理事件.可通過編寫回調函數,注冊某類型事件即可完成訂閱.當所注冊時間類型觸發如函數調用,則回調函數會接收到調用信息、執行回調函數定義的功能.

由于S2E對QEMU本身做了較大量的修改,目前可支持x86,ARM指令集,未能對QEMU所支持的多種平臺進行繼承,丟棄原始QEMU的諸多特性.

3.1.2 性能比較

S2E的符號執行模塊會對分析對象的每一個執行路徑進行分析,對指定模塊的路徑屬性、條件進行監測和操縱,功能復雜,導致性能很低.本文提出的方案直接對QEMU的中間表示TCG,helper機制進行利用,實現了函數調用與返回跟蹤技術,繼承了QEMU原生的多平臺、速度快的特性.

3.2 與QEMU-DFCT對比

本文提出的方法所實現的函數調用記錄的功能與QEMU-DFCT一致.

QEMU-DFCT繼承了原生QEMU的諸多優點,如跨平臺、易拓展,同時以很小的修改代碼實現了函數調用跟蹤技術.QEMU-DFCT直接讀取QEMU原始數據結構,并并行解析,提高了處理速度.

但是,QEMU-DFCT必須強制關閉基本塊鏈接功能,在每一個基本塊執行結束后進行基本塊切換操作,都必須檢查是否為函數調用或返回基本塊,造成了3.65倍的性能開銷.本文提出的方案不是在基本塊切換階段記錄信息,而是將以樁代碼的形式,插入到函數調用和返回指令生成的宿主機代碼中,支持基本塊鏈接功能,降低了性能開銷.

4 實 驗

本文在QEMU 2.9.92版本進行實驗,相關實驗環境如表1所示.其中Linux 內核是使用QEMU加載分析的內核,文件系統是使用QEMU加載時指定的文件系統.宿主機是指運行QEMU的計算機.

Table 1 Experiment Setup表1 實驗環境

本文實現了所提出的插樁算法(QEMU helper stub,QHS)和QEMU-DFCT算法的記錄函數調用信息和輸出部分,并在x86,ARM,MIPS平臺進行了性能對比實驗,實驗結果如圖10所示:

Fig. 10 Performance comparison of QHS and DFCT圖10 QHS,DFCT的性能比較

以QHS-x86為例,使用未修改的QEMU加載x86指令集Linux 4.9內核、busybox 1.27.0文件系統,從啟動到出現shell提示符時間消耗是4.33 s.使用修改后的用于函數調用跟蹤的版本,從啟動到出現shell提示符,同時完成函數調用信息記錄,并將信息處理并輸出到磁盤文件中,所用時間是12.16 s,其中,樁代碼執行總時間是0.66 s,信息處理并輸出使用時間是7.17 s.樁代碼執行信息記錄增加了15.24%的開銷,而信息處理并輸出到磁盤文件增加了165.59%的開銷;DFCT-x86信息記錄增加了210.62%的開銷,記錄輸出開銷是166.51%.由于ARM和MIPS平臺寄存器數目多,DFCT進行基本塊切換操作需要保存或恢復的寄存器數目多,造成調用記錄開銷高于x86平臺,而寄存器數目并不影響QHS算法的性能.

而使用S2E對x86指令集的內核進行加載分析,總時長達3 429.34 s,是因為S2E會對內核使用KLEE模塊進行符號分析,對內核的海量的執行路徑進行路徑屬性、執行條件分析,并在每個路徑和函數調用部分保存并檢查系統狀態、反饋插件調用等任務.所以造成內核啟動很慢.

從實驗結果可以看出,本文實現的基于動態二進制翻譯和代碼插樁的函數調用跟蹤工具的開銷要遠遠優于現有的S2E,QEMU-DFCT跟蹤工具.

5 總 結

本文提出了基于動態二進制翻譯和代碼插樁的函數調用跟蹤,給出了系統框架設計并基于QEMU開發了函數調用跟蹤系統,可針對Linux內核跟蹤所有函數調用,并在x86,ARM,MIPS平臺進行了實現,驗證了系統框架的有效性并評估了系統性能.針對QEMU二進制翻譯過程的中間表示進行設計,插入信息搜集樁代碼而不影響基本塊鏈接、活性分析、常量計算等優化技術,以盡可能小的性能開銷達到了動態函數跟蹤的目的.

本工作還有一些可改進的地方,例如樁代碼的實現可以使用嵌入式匯編或者不使用helper機制,直接生成完成信息記錄功能的宿主機指令,進一步提高速度,降低開銷.實現插件機制,例如注冊指定函數調用事件的回調函數,在樁代碼進行記錄時,若被調用函數是指定的監測函數,調用回調函數.

猜你喜歡
指令集二進制寄存器
基于Kubernetes的RISC-V異構集群云任務調度系統①
用二進制解一道高中數學聯賽數論題
3DNow指令集被Linux淘汰
有用的二進制
Lite寄存器模型的設計與實現
有趣的進度
二進制翻譯中動靜結合的寄存器分配優化方法
移位寄存器及算術運算應用
基于Dais—CMX模型機的斐波那契數列指令集設計
什么是AMD64
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合