linux程序崩溃时调用链,Linux 获取并分析程序崩溃时的调用堆栈
下面是一個(gè)小例子,說明了程序出現(xiàn)段錯(cuò)誤時(shí),如何打印程序的堆棧信息。
#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); /* 還原默認(rèn)的信號(hào)處理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'; //讓這里出現(xiàn)一個(gè)訪問非法指針的錯(cuò)誤
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()
{
//設(shè)置 信好的處理函數(shù)
signal(SIGSEGV, WidebrightSegvHandler); // SIGSEGV 11 CoreInvalid memory reference
signal(SIGABRT, WidebrightSegvHandler); // SIGABRT 6 CoreAbort signal from
char *a = NULL;
error_0(a);
exit(0);
}
然后為了定位錯(cuò)誤,我們需要加上-g參數(shù)編譯一個(gè)帶調(diào)試信息的版本,程序運(yùn)行后打印堆棧信息如下
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]
知道了函數(shù)的地址可以有三種方法獲取函數(shù)所在的文件和名稱等相關(guān)信息。
使用GDB調(diào)試工具定位和調(diào)試錯(cuò)誤。
info line *0x8048580 打印地址0x8048580處的相關(guān)信息。
list *0x8048580 獲取地址0x8048580相關(guān)的上下文代碼信息。
然后便可以確定行號(hào),進(jìn)行g(shù)db調(diào)試了。
使用GCC編譯選項(xiàng)生成MAP文件查找地址對(duì)應(yīng)的函數(shù)信息。
使用GCC編譯選項(xiàng)生成MAP文件查找地址對(duì)應(yīng)的函數(shù)信息。在通過gcc/g++間接調(diào)用鏈接程序ld時(shí),所有的ld選項(xiàng)前必須加上“-Wl,”,因?yàn)?Map是ld的選項(xiàng)。所以,要讓g++生成mapfile,需要增加編譯參數(shù)“ -Wl,-Map,mapfile”。
例:gcc -o helloworld helloworld.c -Wl,-Map,helloworld.map
然后通過map文件來查看函數(shù)的地址和函數(shù)名的對(duì)應(yīng)關(guān)系了。
使用 Addr2line 將函數(shù)地址解析為函數(shù)名。 Addr2line 工具(它是標(biāo)準(zhǔn)的 GNU Binutils 中的一部分)是一個(gè)可以將指令的地址和可執(zhí)行映像轉(zhuǎn)換成文件名、函數(shù)名和源代碼行數(shù)的工具。這種功能對(duì)于將跟蹤地址轉(zhuǎn)換成更有意義的內(nèi)容來說簡(jiǎn)直是太棒了。 注意編譯程序時(shí)需要添加-g選項(xiàng)才可以,也可以添加-Wl 和-map選項(xiàng)。 在調(diào)用 Addr2line 工具時(shí),要使用 -e 選項(xiàng)來指定可執(zhí)行映像是 test。通過使用 -f 選項(xiàng),可以告訴工具輸出函數(shù)名。 例如:addr2line 0x08048258 -e test -f
總結(jié)
以上是生活随笔為你收集整理的linux程序崩溃时调用链,Linux 获取并分析程序崩溃时的调用堆栈的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux文件内容添加序号,nl命令将指
- 下一篇: rust安装教程linux,如何在 Li