linux c 程式異常退出時列印堆疊呼叫資訊

2021-09-03 01:15:02 字數 2754 閱讀 6137

先來了解三個函式

#include

int backtrace(void **buffer, intsize);

char **backtrace_symbols(void *const *buffer, intsize);

void backtrace_symbols_fd(void *const *buffer, intsize, intfd);

int backtrace(void **buffer,int size)

該函式用與獲取當前執行緒的呼叫堆疊,獲取的資訊將會被存放在buffer中,它是乙個指標陣列。引數 size 用來指定buffer中可以儲存多少個void* 元素。函式返回值是實際獲取的指標個數,最大不超過size大小在buffer中的指標實際是從堆疊中獲取的返回位址,每乙個堆疊框架有乙個返回位址。

注意某些編譯器的優化選項對獲取正確的呼叫堆疊有干擾,另外內聯函式沒有堆疊框架;刪除框架指標也會使無法正確解析堆疊內容

char ** backtrace_symbols (void *const *buffer, int size)

backtrace_symbols將從backtrace函式獲取的資訊轉化為乙個字串陣列. 引數buffer應該是從backtrace函式獲取的陣列指標,size是該陣列中的元素個數(backtrace的返回值),函式返回值是乙個指向字串陣列的指標,它的大小同buffer相同.每個字串包含了乙個相對於buffer中對應元素的可列印資訊.它包括函式名,函式的偏移位址,和實際的返回位址

現在,只有使用elf二進位制格式的程式和苦衷才能獲取函式名稱和偏移位址.在其他系統,只有16進製制的返回位址能被獲取.另外,你可能需要傳遞相應的標誌給鏈結器,以能支援函式名功能(比如,在使用gnu ld的系統中,你需要傳遞(-rdynamic))

backtrace_symbols生成的字串都是malloc出來的,但是不要最後乙個乙個的free,因為backtrace_symbols是根據backtrace給出的call stack層數,一次性的malloc出來一塊記憶體來存放結果字串的,所以,像上面**一樣,只需要在最後,free backtrace_symbols的返回指標就ok了。這一點backtrace的manual中也是特別提到的。

注意:如果不能為字串獲取足夠的空間函式的返回值將會為null

void backtrace_symbols_fd (void *const *buffer, int size, int fd)

backtrace_symbols_fd與backtrace_symbols 函式具有相同的功能,不同的是它不會給呼叫者返回字串陣列,而是將結果寫入檔案描述符為fd的檔案中,每個函式對應一行.它不需要呼叫malloc函式,因此適用於有可能呼叫該函式會失敗的情況。

程式測試:

#include #include #include #include #include #include #include void out_stack(char *sig);

void signal_exit(int dunno)

; sprintf(dunno_str, "%d", dunno);

switch (dunno)

break;

case 9:

signal_str = "sigkill(9)";

break;

case 15:

signal_str = "sigterm(15 kill)"; //kill

break;

case 11:

break;

default:

signal_str = "other";

break;

} exit(0);

}static void output_addrline(char addr)

; char *str1, *str2;

file* file;

str1 = strchr(addr,'[');

str2 = strchr(addr, ']');

if(str1 == null || str2 == null)

memcpy(addrline, str1 + 1, str2 -str1);

snprintf(cmd, sizeof(cmd), "addr2line -e /proc/%d/exe %s ", getpid(), addrline);

file = popen(cmd, "r");

if(null != fgets(line, 256, file))

pclose(file);

}void out_stack(char *sig)

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

free(strings);

}void test3(int n)

void test2(int n)

void test1(int n)

int main()

注意編譯的時候要加-g 和 -rdynamic選項

Linux C 應用程式退出時的事件響應

define sighup 1 hangup sighup是unix系統管理員很常用的乙個訊號。許多後台服務程序在接受到該訊號後將會重新讀取它們的配置檔案。然而,該訊號的實際功能是通知程序它的控制終端被斷開。預設行為是終止程序。define sigint 2 interrupt 對於unix使用者來...

android捕獲程式異常退出

今天看到迅雷動漫裡面乙個crashhandler 的類,我猜是崩潰處理類。進去一看。果然。順便學習一下。android系統的 程式異常退出 給應用的使用者體驗造成不良影響。為了捕獲應用執行時異常並給出友好提示,便可繼承 uncaughtexceptionhandler 類來處理。通過thread.s...

程式異常退出除錯

這周遇到乙個非常奇怪的事,程式在壓力測試的時候會莫名奇怪的掛掉,但是除錯時卻發現情況也是很詭異。使用gdb列印呼叫棧後發現,函式呼叫棧裡的this指標指向的值不對勁。credisclient connect this 0x603,ip port 4,timeout 1956863078 不僅如此,所...