BACKTRACE(3) | Linux Programmer's Manual | BACKTRACE(3) |
名前
backtrace, backtrace_symbols, backtrace_symbols_fd -アプリケーション自身でのデバッグのサポート書式
#include <execinfo.h>説明
backtrace() は、呼び出したプログラムのバックトレースを buffer が指す配列に入れて返す。バックトレースは、プログラムで現在動作中の関数呼び出しの並びである。 buffer が指す配列の個々の要素は void * 型で、対応するスタックフレームからのリターンアドレスである。 size 引き数は buffer に格納できるアドレスの最大個数を指定する。バックトレースが size より大きい場合、 size 個の直近の関数呼び出しに対応するアドレスが返される。完全なバックトレースを取得するためには、確実に buffer と size が十分大きくなるようにすること。返り値
backtrace() は buffer に格納したアドレスの個数を返す。その個数は size より大きくなることはない。返り値が size より小さい場合、バックトレース全体が格納されている。返り値が size と等しい場合、バックトレースは切り詰められているかもしれない。切り詰められた場合、最も古いスタックフレームのアドレスは返されないことになる。バージョン
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.51 の一部である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。2008-06-14 | GNU |