先來了解三個函式
#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 不僅如此,所...