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]]
@leekayak 写了一个宏,更加好用!
#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