名 前
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/ に 書 か れ て い る 。