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