段錯誤定位
原因是昨天遇到一個BUG,復現機率很小,一直復現了一下午,後來google發現可以用execinfo.h裡的backtrace函式及訊號處理機制, 來讓程式在發生段錯誤時自動列印呼叫堆疊。最後終於復現出來了兩次,用這個函式也定位到了出錯位置,是多執行緒下的一個同步問題。
之前遇到的BUG基本都是可復現的,用簡單的列印很快就能定位到BUG位置。對於這種不可復現的BUG在開發測試的時候最好能一直帶著backtrace函式,以最快的速度定位BUG。
#include <execinfo.h>
#define BACKTRACE_SIZE 256
void segv_handler(int sig)
{
void *func[BACKTRACE_SIZE];
int size;
size = backtrace(func, BACKTRACE_SIZE);
backtrace_symbols_fd(func, size, STDERR_FILENO);
exit(1);
}
int main(void)
{
int *p = NULL;
signal(SIGSEGV, segv_handler);
*p = 0xdeadbeef; //---------------------Line 29
return 0;
}
程式開始的時候註冊一下SIGSEGV訊號的回撥,然後編譯的時候帶上-g。程式執行出錯的時候會以彙編的形似列印呼叫棧。形式一般是這樣:
./auto[0x400654]
/lib64/libc.so.6(+0x35250)[0x7fbbe4283250]
./auto[0x400543] //----------------出錯地址
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7fbbe426fb35]
./auto[0x40057e]
前邊兩行是SIGSEGV訊號被觸發的回撥,第三行是段錯誤的位置。addr2line -e auto 0x400543
可以列印出這個地址對應的程式碼位置。或者也可以用objdump -d xxx
列印出來彙編然後去搜尋這個地址。
參考:https://www.cnblogs.com/lchzd8/p/15845824.html