3

ちょっと興味があります: gdb にコア ファイルをロードすると、バックトレースは次のようになります。

...

Thread 2 (Thread 1109):
#0  0x2b03d968 in ?? ()

Thread 1 (Thread 23490):
#0  0x2b0c3624 in ?? ()
(gdb) 

しかし、「ファイル」を使用してバイナリをロードすると、次のようになります。

...

#0  __pthread_cond_wait (cond=0x46b810, mutex=0x46b7f0) at pthread_cond_wait.c:156
#1  0x004076a8 in main (argc=1, argv=0x7fa66784) at idpoint.c:258
...

#0  0x2b0c3624 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:67
#1  0x2b0c8464 in *__GI_abort () at abort.c:88
#2  0x2b0faeec in __libc_message (do_abort=2, fmt=0x2b1d0840 "*** glibc detected *** %s: %s: 0x%s ***\n") at ../sysdeps/unix/sysv/linux/libc_fatal.c:173
#3  0x2b107e3c in malloc_printerr (action=3, str=0x2b1d0930 "free(): invalid next size (fast)", ptr=<value optimized out>) at malloc.c:5994
...

質問: シンボルが読み込まれる前に、なぜ gdb はコール スタックを表示しようとさえしないのですか? 私の推測では、セグメントがメモリ内のどこに配置されているかがわからず、どのスタック データをデータとアドレスとして解釈するかがわからないのでしょうか? これは正しいです?

スタックの深さのアイデアを得るために、または後で解釈するために、シンボルなしでコールスタックを表示する gdb:s の最善の試みを得ることができれば、それは素晴らしいことです...

4

1 に答える 1

3

バイナリ ファイルにはシンボリック情報 (デバッグ シンボル) が含まれているため、デバッガーは、たとえば、各関数のスタック フレームの大きさを [関数内の特定の時点でも!] 理解できます。この情報は、コードの開始時にメモリにロードされないため、coreファイルに存在する方法はありません。

もちろん、使用できますx/200 $esp(または、スタックポインターが呼び出されるものは何でも-x86だと思います-ARMの場合は$R15、メモリから呼び出されます)。残念ながら、シンボルにアクセスできなければgdb、スタックに何があるかを実際に知ることはできず、スタックの生のダンプを提供することしかできません。ほとんどの場合、何も表示しないよりも役に立ちません。ランダムなデータのロードを示すため (特にフレーム ポインターがオフになっている場合は、ほとんどのスタックが表示されます。フレーム ポインターを使用すると、スタックのネストを解除する可能性があります)、ほとんどの場合、ほとんど役に立ちません。

于 2013-02-14T11:31:27.177 に答える