使用backtrace獲得動態鏈結庫的呼叫位址

2021-06-19 23:16:38 字數 1297 閱讀 8593

呼叫backtrace的時候,動態鏈結庫(.so)的呼叫位址不能直接呼叫addr2line得到**行數,stackoverflow上的方法比較麻煩

可以通過讀取/proc/pid/maps獲得動態能鏈結庫載入路徑。

int get_backtrace_string(void* bt,char* buff,int buff_size)

; char property[256]=;

char not_care1[128]=,not_care2[128]=,not_care3[128]=;

char library_path[256]=;

char exe_path[256],function_name[256];

char maps_line[1024]=;

void* offset_start,*offset_end;

int maps_column_num=0;

file* fd_maps=null;

fd_maps=fopen("/proc/self/maps","r");

unsigned long exe_symbol_offset=0;

char* unknow_position="??:0\n";

if(fd_maps==null)

while(null!=fgets(maps_line,sizeof(maps_line),fd_maps))

} fclose(fd_maps);

readlink("/proc/self/exe", exe_path, sizeof(exe_path));

if(exe_path[strlen(exe_path)-1]=='\n')

if(0==strcmp(exe_path,library_path))

else

snprintf(cmd,sizeof(cmd),"addr2line -c -e %s 0x%lx",library_path,exe_symbol_offset);

exec_shell(cmd, buff, buff_size);

if(0==strcmp(buff,unknow_position))

return 0;

}

2014-11-15補充:

gcc的backtrace函式在多執行緒呼叫時,有鎖衝突,效率比較低,libunwind似乎是乙個更好的選擇。

這篇文章分析了幾種backtrace的方法。

2014-12-31補充:

在wangpeng同學的幫助下,使用了下面的方法,可以更高效的獲得呼叫堆疊。

使用backtrace獲取堆疊資訊

一些記憶體檢測工具如valgrind,除錯工具如gdb,可以檢視程式執行時函式呼叫的堆疊資訊,有時候在分析程式時要獲得堆疊資訊,借助於backtrace是很有幫助的,其原型如下 include int backtrace void buffer,int size char backtrace sym...

使用backtrace獲取堆疊資訊

gdb將當前函式的棧幀編號為0,為外層函式的棧幀依次加1,這些編號將成為一些gdb命令的引數,以指明將要操作的是哪乙個函式的棧幀。gdb還支援使用address作為棧幀的識別符號,可在棧幀編號被破壞的情況下使用。1.在棧幀之間切換 gdb中有很多針對呼叫堆疊的命令,都需要乙個目標棧幀,例如列印區域性...

Linux下使用backtrace捕獲宕機堆疊資訊

linux下常見的宕機訊號,如下 訊號名編號值 描述系統預設處理方式 sigint 2正常終止程序 ctrl c 終止程序 sigquit 3異常終止程序 終止程序,並允許產生core檔案 sigabrt 6異常終止程序 終止程序,並允許產生core檔案 sigbus 7異常終止程序,硬體錯誤 終止...