1. 程式人生 > >C++中如何列印呼叫棧

C++中如何列印呼叫棧

  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