日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux程序崩溃时调用链,Linux 获取并分析程序崩溃时的调用堆栈

發布時間:2024/4/17 linux 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux程序崩溃时调用链,Linux 获取并分析程序崩溃时的调用堆栈 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

下面是一個小例子,說明了程序出現段錯誤時,如何打印程序的堆棧信息。

#include

#include

#include

#include

static void WidebrightSegvHandler(int signum)

{

void *array[10];

size_t size;

char **strings;

size_t i, j;

signal(signum, SIG_DFL); /* 還原默認的信號處理handler */

size = backtrace (array, 10);

strings = (char **)backtrace_symbols (array, size);

fprintf(stderr, "widebright received SIGSEGV! Stack trace:\n");

for (i = 0; i < size; i++) {

fprintf(stderr, "%d %s \n",i,strings[i]);

}

free (strings);

exit(1);

}

int invalide_pointer_error(char * p)

{

*p = 'd'; //讓這里出現一個訪問非法指針的錯誤

return 0;

}

void error_2(char * p)

{

invalide_pointer_error(p);

}

void error_1(char * p)

{

error_2(p);

}

void error_0(char * p)

{

error_1(p);

}

int main()

{

//設置 信好的處理函數

signal(SIGSEGV, WidebrightSegvHandler); // SIGSEGV 11 CoreInvalid memory reference

signal(SIGABRT, WidebrightSegvHandler); // SIGABRT 6 CoreAbort signal from

char *a = NULL;

error_0(a);

exit(0);

}

然后為了定位錯誤,我們需要加上-g參數編譯一個帶調試信息的版本,程序運行后打印堆棧信息如下

widebright received SIGSEGV! Stack trace:

0 ./a.out [0x8048580]

1 [0xb7fb3400]

2 ./a.out [0x8048636]

3 ./a.out [0x8048649]

4 ./a.out [0x804865c]

5 ./a.out [0x80486a9]

6 /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe5) [0xb7e52775]

7 ./a.out [0x80484c1]

知道了函數的地址可以有三種方法獲取函數所在的文件和名稱等相關信息。

使用GDB調試工具定位和調試錯誤。

info line *0x8048580 打印地址0x8048580處的相關信息。

list *0x8048580 獲取地址0x8048580相關的上下文代碼信息。

然后便可以確定行號,進行gdb調試了。

使用GCC編譯選項生成MAP文件查找地址對應的函數信息。

使用GCC編譯選項生成MAP文件查找地址對應的函數信息。在通過gcc/g++間接調用鏈接程序ld時,所有的ld選項前必須加上“-Wl,”,因為-Map是ld的選項。所以,要讓g++生成mapfile,需要增加編譯參數“ -Wl,-Map,mapfile”。

例:gcc -o helloworld helloworld.c -Wl,-Map,helloworld.map

然后通過map文件來查看函數的地址和函數名的對應關系了。

使用 Addr2line 將函數地址解析為函數名。 Addr2line 工具(它是標準的 GNU Binutils 中的一部分)是一個可以將指令的地址和可執行映像轉換成文件名、函數名和源代碼行數的工具。這種功能對于將跟蹤地址轉換成更有意義的內容來說簡直是太棒了。 注意編譯程序時需要添加-g選項才可以,也可以添加-Wl 和-map選項。 在調用 Addr2line 工具時,要使用 -e 選項來指定可執行映像是 test。通過使用 -f 選項,可以告訴工具輸出函數名。 例如:addr2line 0x08048258 -e test -f

總結

以上是生活随笔為你收集整理的linux程序崩溃时调用链,Linux 获取并分析程序崩溃时的调用堆栈的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。