GDB バックトレース メッセージ「0x0000000000000000 in ??」()" 平均?
質問
次の出力でバックトレースが行われる場合、これは何を意味しますか?
#0 0x00000008009c991c in pthread_testcancel () from /lib/libpthread.so.2
#1 0x00000008009b8120 in sigaction () from /lib/libpthread.so.2
#2 0x00000008009c211a in pthread_mutexattr_init () from /lib/libpthread.so.2
#3 0x0000000000000000 in ?? ()
プログラムは標準シグナル 11、セグメンテーション違反によりクラッシュしました。私のアプリケーションは、スレッド ライブラリとして pthread を使用する、FreeBSD 6.3 上で実行されるマルチスレッド FastCGI C++ プログラムです。
情報ソースによると、これは -g でコンパイルされており、ソースのすべてのシンボル テーブルがロードされています。
明らかなように、実際のコードはトレースに表示されませんが、代わりにエラーは標準の pthread ライブラリから発生しているようです。特に、何ですか?() ????
編集:最終的にはクラッシュの原因を、メイン コード内の標準的な無効なメモリ アクセスに突き止めました。スタック トレースが破損した理由は説明されていませんが、それは別の日の質問です :)
解決
gdb は pthread_mutexattr_init から適切な戻りアドレスを抽出できませんでした。アドレスは 0 でした。「??」シンボルテーブルでアドレス0を検索した結果です。シンボリック名が見つからないため、デフォルトの「??」が出力されます。
残念ながら、なぜ正しい返信先アドレスを抽出できなかったのかはわかりません。
他のヒント
何かを行った結果、スレッド ライブラリがクラッシュしました。スレッド ライブラリ自体はデバッグ シンボル (-g) を使用してコンパイルされていないため、クラッシュが発生したソース コード ファイルや行番号を表示できません。さらに、スレッドであるため、呼び出しスタックはファイルを指しません。残念ながら、これを追跡するのは難しいバグです。コードをステップ実行して、正確にいつクラッシュが発生するかを絞り込む必要があります。
必ずデバッグ シンボルを使用してコンパイルしてください。(gcc の場合は -g オプションだと思います)。そうすれば、GDB からさらに興味深い情報を取得できるはずです。製品版をコンパイルするときは、忘れずにオフにしてください。
何かが欠けている可能性がありますが、これは誰かが使用していることを示していませんか? NULL
関数ポインタとして?
#include <stdio.h>
typedef int (*funcptr)(void);
int
func_caller(funcptr f)
{
return (*f)();
}
int
main()
{
return func_caller(NULL);
}
これにより、gdb で実行すると、同じスタイルのバックトレースが生成されます。
rivendell$ gcc -g -O0 foo.c -o foo
rivendell$ gdb --quiet foo
Reading symbols for shared libraries .. done
(gdb) r
Starting program: ...
Reading symbols for shared libraries . done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
0x00000000 in ?? ()
(gdb) bt
#0 0x00000000 in ?? ()
#1 0x00001f9d in func_caller (f=0) at foo.c:8
#2 0x00001fb1 in main () at foo.c:14
これはかなり奇妙なクラッシュですが... pthread_mutexattr_init
データ構造を割り当てる以上のことはほとんど行いません。 memset
それ。他に何か起こっていることを探したいと思います。スレッドライブラリか何かが一致していない可能性がありますか。私の BSD の知識は少し古いですが、以前はこれに関する問題がありました。
おそらく、クラッシュの原因となったバグがスタックを破壊した (スタックの一部が上書きされた) のでしょうか?その場合、バックトレースは役に立たない可能性があります。その場合どうすればいいのかわかりません...