プログラムのある時点でスタック トレースを作成します。libcのbacktrace_symbols()
関数で 1 回、libunwindunw_get_proc_name()
から1 回。
backtrace_symbols() 出力:
/home/jj/test/mylib.so(+0x97004)[0x7f6b47ce9004]
unw_get_proc_name() の出力:
ip: 0x7f6b47ce9004, offset: 0x458e4
ここでは、命令ポインタアドレス (0x7f6b47ce9004) が同じで正しいことがわかります。backtrace_symbols()0x97004
からの関数オフセットも正しいですが、 unw_get_proc_name()から取得したものではありません( )。0x458e4
誰かがここで何が起こっているのか、オフセットにこの違いが生じる原因を知っていますか?
どちらの方法も、次の例のような類似のコードを使用します。
バックトレース():
void *array[10];
size_t size;
size = backtrace(array, 10);
backtrace_symbols_fd(array, size, STDERR_FILENO);
libunwind:
unw_cursor_t cursor;
unw_context_t context;
unw_getcontext(&context);
unw_init_local(&cursor, &context);
while (unw_step(&cursor) > 0) {
unw_word_t offset, pc;
char fname[64];
unw_get_reg(&cursor, UNW_REG_IP, &pc);
fname[0] = '\0';
(void) unw_get_proc_name(&cursor, fname, sizeof(fname), &offset);
printf ("%p : (%s+0x%x) [%p]\n", pc, fname, offset, pc);
}