メモ用。デバッグ等で有用なコールスタックはgdbなどの各種デバッガで取得できるけれど、実行中にアプリケーション内で取得したい場合がある。
それはglibcが使えるならbacktrace()、backtrace_symbols()で実現できる。
例えば下記のコード:
#include <stdio.h> #include <execinfo.h> void hoge1(void) { size_t i; void *trace[128]; char **ss_trace; size_t size = backtrace(trace, sizeof(trace) / sizeof(trace[0])); ss_trace = backtrace_symbols(trace, size); if (ss_trace == NULL) { /*Failure*/ return; } /*例えば表示*/ for (i = 0; i < size; i++) { printf("%s\n", ss_trace[i]); } free(ss_trace); } void hoge2(void) { hoge1(); } void hoge3(void) { hoge2(); } int main(void) { hoge3(); return 0; }
これをgccなら「-rdynamic」のオプションをつけてビルド(必要なら「-g」オプションも)。そして実行すると、例えばmacなら以下の様なバックトレース出力が得られる。
0 a.out 0x0000000100b4cd9b hoge1 + 43 1 a.out 0x0000000100b4ce39 hoge2 + 9 2 a.out 0x0000000100b4ce49 hoge3 + 9 3 a.out 0x0000000100b4ce5d main + 13 4 libdyld.dylib 0x00007fff8ff3d7e1 start + 0
コード内でのファイル名と行数情報を得たい場合、GNU binutilsを使えるならaddr2lineを使用。実行ファイルがa.outで、上記のhoge2の記述箇所を知りたいなら、例えば以下のコマンドを実行すると取得できる。
addr2line -f -e a.out 0x100b4cd39