Provided by: manpages-ja-dev_0.5.0.0.20210215+dfsg-1_all bug

名前

       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 個の直近の関数呼び出しに対応するアドレスが返される。  完全なバックトレースを
       取得するためには、確実に buffersize が十分大きくなるようにすること。

       backtrace()   によって  buffer  にアドレスの集合が得られたら、  backtrace_symbols() によっ
       て、アドレス集合を、そのアドレスをシンボルで表した文字列の配列 に翻訳できる。 size  引き数
       は  buffer に格納されたアドレスの数を指定する。 個々のアドレスのシンボル表現は、関数名 (特
       定できた場合)、 関数へのオフセット (16進表記)、実際のリターンアドレス (16進表記)  から構成
       される。  backtrace_symbols()  の実行結果としては、 文字列ポインターの配列のアドレスが返さ
       れる。 この配列は backtrace_symbols()  によって malloc(3) され、呼び出し側で free しなけれ
       ばならない (ポインターの配列が指す個々の文字列は free する必要はないし、 free すべきでもな
       い)。

       backtrace_symbols_fd()  は、 backtrace_symbols()  と同じ引き数 buffersize をとるが、呼
       び出し側に文字列の配列を返す代わりに、  文字列をファイルディスクリプター 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/ に書かれている。