Provided by: manpages-ja-dev_0.5.0.0.20210215+dfsg-1_all
名前
backtrace, backtrace_symbols, backtrace_symbols_fd - アプリケーション自身でのデバッグのサ ポート
書式
#include <execinfo.h> int backtrace(void **buffer, int size); char **backtrace_symbols(void *const *buffer, int size); void backtrace_symbols_fd(void *const *buffer, int size, int fd);
説明
backtrace() は、呼び出したプログラムのバックトレースを buffer が指す配列に入れて返 す。バックトレースは、プログラムで 現在動作中の関数呼び出しの並びである。 buffer が指す配 列の個々の要素は void * 型で、 対応するスタックフレームからのリターンアドレスである。 size 引き数は buffer に格納できるアドレスの最大個数を指定する。 バックトレースが size より大き い場合、 size 個の直近の関数呼び出しに対応するアドレスが返される。 完全なバックトレースを 取得するためには、確実に buffer と size が十分大きくなるようにすること。 backtrace() によって buffer にアドレスの集合が得られたら、 backtrace_symbols() によっ て、アドレス集合を、そのアドレスをシンボルで表した文字列の配列 に翻訳できる。 size 引き数 は buffer に格納されたアドレスの数を指定する。 個々のアドレスのシンボル表現は、関数名 (特 定できた場合)、 関数へのオフセット (16進表記)、実際のリターンアドレス (16進表記) から構成 される。 backtrace_symbols() の実行結果としては、 文字列ポインターの配列のアドレスが返さ れる。 この配列は backtrace_symbols() によって malloc(3) され、呼び出し側で free しなけれ ばならない (ポインターの配列が指す個々の文字列は free する必要はないし、 free すべきでもな い)。 backtrace_symbols_fd() は、 backtrace_symbols() と同じ引き数 buffer と size をとるが、呼 び出し側に文字列の配列を返す代わりに、 文字列をファイルディスクリプター fd に 1 行に 1 エ ントリーの形で書き込む。 backtrace_symbols_fd() は malloc(3) を呼び出さない。 そのた め、これに続く関数が失敗する可能性がある状況でも利用できる。
返り値
backtrace() は buffer に格納したアドレスの個数を返す。その個数は size より大きくなること はない。 返り値が size より小さい場合、バックトレース全体が格納されている。返り値が size と等しい場合、バックトレースは切り詰められているかもしれない。 切り詰められた場合、最も古 いスタックフレームのアドレスは 返されないことになる。 backtrace_symbols() は、成功すると、この呼び出しで malloc(3) された配列へのポインターを 返す。 エラーの場合、 NULL を返す。
バージョン
backtrace(), backtrace_symbols(), backtrace_symbols_fd() はバージョン 2.1 以降の glibc で 提供されている。
準拠
これらの関数は GNU による拡張である。
注意
これらの関数は、関数のリターンアドレスがスタック上でどのように格納されるか に関してある仮 定を置いている。 以下の点に注意。 * (gcc(1) の 0 以外の最適化レベルで暗黙のうちに行われる) フレームポインターの省略を行う と、これらの前提が崩れる可能性がある。 * インライン関数はスタックフレームを持たない。 * 末尾呼び出しの最適化 (tail-call optimization) を行うと、 あるスタックフレームが別のス タックフレームを置き換える可能性がある。 シンボル名は特別なリンカーオプションを使用しないと利用できない場合がある。 GNU リンカーを 使用するシステムでは、 -rdynamic リンカーオプションを使う必要がある。 "static" な関数のシ ンボル名は公開されず、 バックトレースでは利用できない点に注意すること。
例
以下のプログラムは、 backtrace() と backtrace_symbols() の使用例を示したものである。 以 下に示すシェルのセッションは、 このプログラムを動かした際の実行例である。 $ cc -rdynamic prog.c -o prog $ ./prog 3 backtrace() returned 8 addresses ./prog(myfunc3+0x5c) [0x80487f0] ./prog [0x8048871] ./prog(myfunc+0x21) [0x8048894] ./prog(myfunc+0x1a) [0x804888d] ./prog(myfunc+0x1a) [0x804888d] ./prog(main+0x65) [0x80488fb] /lib/libc.so.6(__libc_start_main+0xdc) [0xb7e38f9c] ./prog [0x8048711] プログラムのソース #include <execinfo.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> void myfunc3(void) { int j, nptrs; #define SIZE 100 void *buffer[100]; char **strings; nptrs = backtrace(buffer, SIZE); printf("backtrace() returned %d addresses\n", nptrs); /* backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) を 呼び出しても、以下と同様の出力が得られる。 */ strings = backtrace_symbols(buffer, nptrs); if (strings == NULL) { perror("backtrace_symbols"); exit(EXIT_FAILURE); } for (j = 0; j < nptrs; j++) printf("%s\n", strings[j]); free(strings); } static void /* "static" はシンボルを公開しないことを意味する */ myfunc2(void) { myfunc3(); } void myfunc(int ncalls) { if (ncalls > 1) myfunc(ncalls - 1); else myfunc2(); } int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "%s num-calls\n", argv[0]); exit(EXIT_FAILURE); } myfunc(atoi(argv[1])); exit(EXIT_SUCCESS); }
関連項目
gcc(1), ld(1), dlopen(3), malloc(3)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。