C++中如何列印呼叫棧
阿新 • • 發佈:2019-02-02
if (your_condition_bool_val == true) { void * array[10]; char ** strings; size_t size = backtrace(array, 10); strings = backtrace_symbols(array, size); for (size_t i = 0; i < size; ++i) { TBSYS_LOG(WARN, "backtrace%lu:[%s]", i, strings[i]); } free(strings); }
然後在Makefile中保證有下面兩個編譯選項:
CXXFLAGS = -g -rdynamic
如果沒有rdynamic,只會打印出呼叫者的地址,通過addr2line工具可以從地址反查到函式,不過這麼做實在是太麻煩,還是加上編譯選項更方便。
輸出結果如下:
[2012-12-26 01:00:14.659541] WARN init (ob_schema_service_impl.cpp:249) [1108461888] backtrace0:[/home/raywill/ob2/bin/rootserver(_ZN9oceanbase6common19ObSchemaServiceImpl4initEPNS0_12ObScanHelperEb+0x378) [0x5fa784]] [2012-12-26 01:00:14.659552] WARN init (ob_schema_service_impl.cpp:249) [1108461888] backtrace1:[/home/raywill/ob2/bin/rootserver(_ZN9oceanbase10rootserver13ObRootServer210get_schemaEbbRNS_6common17ObSchemaManagerV2ERl+0x4ab) [0x50716f]] [2012-12-26 01:00:14.659558] WARN init (ob_schema_service_impl.cpp:249) [1108461888] backtrace2:[/home/raywill/ob2/bin/rootserver(_ZN9oceanbase10rootserver14ObRootBalancer18nb_get_table_countEv+0x134) [0x4cfebc]] [2012-12-26 01:00:14.659577] WARN init (ob_schema_service_impl.cpp:249) [1108461888] backtrace3:[/home/raywill/ob2/bin/rootserver(_ZN9oceanbase10rootserver14ObRootBalancer14do_new_balanceEv+0xdf) [0x4d0399]] [2012-12-26 01:00:14.659582] WARN init (ob_schema_service_impl.cpp:249) [1108461888] backtrace4:[/home/raywill/ob2/bin/rootserver(_ZN9oceanbase10rootserver14ObRootBalancer10do_balanceERb+0x115) [0x4d08b3]] [2012-12-26 01:00:14.659586] WARN init (ob_schema_service_impl.cpp:249) [1108461888] backtrace5:[/home/raywill/ob2/bin/rootserver(_ZN9oceanbase10rootserver22ObRootBalancerRunnable3runEPN5tbsys7CThreadEPv+0x180) [0x4d265a]] [2012-12-26 01:00:14.659591] WARN init (ob_schema_service_impl.cpp:249) [1108461888] backtrace6:[/home/raywill/ob2/bin/rootserver(_ZN5tbsys7CThread4hookEPv+0x64) [0x69d134]] [2012-12-26 01:00:14.659599] WARN init (ob_schema_service_impl.cpp:249) [1108461888] backtrace7:[/lib64/libpthread.so.0 [0x3cf70064a7]] [2012-12-26 01:00:14.659604] WARN init (ob_schema_service_impl.cpp:249) [1108461888] backtrace8:[/lib64/libc.so.6(clone+0x6d) [0x33950d3c2d]]
用法:#define BACKTRACE(LEVEL, cond, _fmt_, args...) \ do \ { \ if (cond) \ { \ void *buffer[100]; \ int size = backtrace(buffer, 100); \ char **strings = backtrace_symbols(buffer, size); \ if (NULL != strings) \ { \ TBSYS_LOG(LEVEL, _fmt_ " BackTrace Start: ", ##args); \ for (int i = 0; i < size; i++) \ { \ TBSYS_LOG(LEVEL, "BT[%d] @[%s]", i, strings[i]); \ } \ free(strings); \ } \ } \ } while (false)
BACKTRACE(INFO, c1==c2, "%s, %d, %d. here is trace:", "found c1 equals to c2", c1, c2); //當c1==c2時列印backtrace
BACKTRACE(INFO, true, "here is trace:"); //總是列印backtrace
【搞定】
附:
addr2line用法: addr2line --exe=my_app 0x111111 0x2222222 0x3333333