シグナルハンドラの制御フロー転送を理解するための簡単なプログラムを書きました。次のプログラムは、子プロセスが.text領域に繰り返し書き込むようにし、ハンドラをトリガします。gdbでシグナルハンドラを使ってCプログラムをデバッグする方法は?
#include "csapp.h" // just include standard headers
extern char etext;
void handler() {
printf("pid = %d, in handler\n", getpid());
return;
}
int main(int argc, char **argv) {
if (signal(SIGSEGV, handler) == SIG_ERR) {
perror("signal error");
}
if (fork() == 0) {
printf("from Child before\n");
etext = 'a';
printf("from Child after\n");
}
return EXIT_SUCCESS;
}
ただし、これをgdbで確認したいと思います。メインを分解すると下のアセンブリが得られます。以下のコマンドを使用してブレークポイントを作成したので、gdbは.text領域に書き込む前の時点でブレークできます。
(GDB)のb * 0x00000000004006fb
それから私は、GDBでプログラムを実行します。しかしgdbは止まりませんし、シグナルハンドラを実行し続けます。
0x00000000004006ba <+0>: push %rbp
0x00000000004006bb <+1>: mov %rsp,%rbp
0x00000000004006be <+4>: sub $0x10,%rsp
0x00000000004006c2 <+8>: mov %edi,-0x4(%rbp)
0x00000000004006c5 <+11>: mov %rsi,-0x10(%rbp)
0x00000000004006c9 <+15>: mov $0x40069d,%esi
0x00000000004006ce <+20>: mov $0xb,%edi
0x00000000004006d3 <+25>: callq 0x400570 <[email protected]>
0x00000000004006d8 <+30>: cmp $0xffffffffffffffff,%rax
0x00000000004006dc <+34>: jne 0x4006e8 <main+46>
0x00000000004006de <+36>: mov $0x4007ba,%edi
0x00000000004006e3 <+41>: callq 0x400590 <[email protected]>
0x00000000004006e8 <+46>: callq 0x4005a0 <[email protected]>
0x00000000004006ed <+51>: test %eax,%eax
0x00000000004006ef <+53>: jne 0x40070c <main+82>
0x00000000004006f1 <+55>: mov $0x4007c7,%edi
0x00000000004006f6 <+60>: callq 0x400530 <[email protected]>
0x00000000004006fb <+65>: movb $0x61,0x9b(%rip) # 0x40079d
0x0000000000400702 <+72>: mov $0x4007d9,%edi
0x0000000000400707 <+77>: callq 0x400530 <[email protected]>
0x000000000040070c <+82>: mov $0x0,%eax
0x0000000000400711 <+87>: leaveq
0x0000000000400712 <+88>: retq
質問: 1.WhyのGDBが文句を言わない私が指定したアドレスで破りますか?
2.シグナルハンドラから戻ったときに命令ポインタが指している正確なアドレスを知るためにgdbを使う方法はありますか?
シグナルハンドラでprintfを使用しないでください。 –
@SeekAddo、OK。私は情報をファイルに記録するように変更することができます。しかし、どのように私は主な問題を解決するのですか? – drdot
[GDBにセグメンテーションの原因となったアドレスを教えてもらうにはどうすればいいですか?](https://stackoverflow.com/questions/3003339/how-can-i-get-gdb-to-tell-me-what -address-initiated-a-segfault) –