舊資料整理 gcc獲取乙個動態庫的呼叫流程

2021-08-02 23:56:00 字數 1799 閱讀 3306

有的時候,我們需要關注一下乙個動態庫的呼叫流程,但我們並不想關注內部處理。目前,現在的分析工具,多數會得到乙份完整的、複雜的呼叫關係,這裡,給出乙個很簡單的處理辦法

以獲取apache對mod_ssl.so的呼叫為例

1、在mod_ssl.so的**中,接入兩個函式,用來輸出函式呼叫和函式返回時的日誌。下面是簡單的輸出到錯誤流的辦法。

1

2

3

4

5

6

7

8

9

10

11

12

void__cyg_profile_func_enter(void*funaddr,void*callsite)__attribute__((no_instrument_function));

void__cyg_profile_func_enter(void*funaddr,void*callsite)

void__cyg_profile_func_exit(void*funaddr,void*callsite)__attribute__((no_instrument_function));

void__cyg_profile_func_exit(void*funaddr,void*callsite)

2、將mod_ssl.so編譯成debug版本, 並且支援上面的修改,新增編譯引數make cflags='-g -o0 -finstrument-functions',將生成的新的庫新增到執行環境中。

3、測試,收集輸出的日誌,具體的輸出日誌與程式的配置有關。

4、處理日誌,當前的日誌只是列出了一些函式位址,需要將位址轉義為函式名。獲取當前模組的函式位址列表

readelf -s ./.libs/mod_ssl.so | grep -v und | awk '' > fun.list

這個位址列表,只是相對位址,並不是實際的位址,實際位址每個例項都不一樣。gdb -p ***除錯程序,檢視列表中任意乙個函式的真實位址

disassemble 函式名 看到的第一行就是了,根據匯出列表的函式位址值和獲取的值,可以算出乙個偏移,用這個偏移將輸出日誌中的位址全部轉換為相對位址。

5、獲取呼叫方位址的函式位址,日誌列印出來的呼叫位址是跳轉位址,並不是呼叫函式的位址,用命令來獲取對應的函式位址

addr2line 0001ec09 -e mod_ssl.so -f這是乙個示例,需要自己用指令碼批量處理。

6、處理之後,就獲取乙份由函式相對位址組成的日誌和乙份對應的函式名,將日誌進行指替換就可以了得到用函式名表示的呼叫關係了。將呼叫函式名無法獲取的行提取(grep '\?')即獲取了乙個完整的模組,不包含內部處理呼叫關係圖。

GCC靜態庫的另乙個問題

對於c 生成的靜態庫,按照一般的想法去鏈結,會出現所有的符號都無法找到的錯誤。這裡所謂的一般的想法就是把原始檔放在最後邊,如 g o test.exe l l t test.cpp,那麼得到的錯誤資訊為 test.cpp text 0x31 undefined reference to t test...

Linux第乙個動態庫

動態庫一般以.so結尾,就是shared object的意思.其基本生成步驟為 編寫函式 編譯生成動態庫檔案,要加上 shared 和 fpic 選項 庫檔名以lib開頭,以.so 結尾。fpic 使輸出的物件模組是按照可重定位位址方式生成的。shared指定把對應的原始檔生成對應的動態鏈結庫檔案l...

Linux第乙個動態庫

動態庫一般以.so結尾,就是shared object的意思.其基本生成步驟為 編寫函式 編譯生成動態庫檔案,要加上 shared 和 fpic 選項 庫檔名以lib開頭,以.so 結尾。fpic 使輸出的物件模組是按照可重定位位址方式生成的。shared指定把對應的原始檔生成對應的動態鏈結庫檔案l...