Ich schrieb ein einfaches Programm, um die Kontrolle Flussübertragung eines Signal-Handler zu verstehen. Das folgende Programm lässt das Kind wiederholt in die .text-Region schreiben und den Handler auslösen.Wie Debuggen eines C-Programms mit Signalhandler in Gdb?
#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;
}
Allerdings möchte ich dies mit gdb überprüfen. Das Zerlegen des Hauptteils ergibt die folgende Montage. Ich habe einen Breakpoint mit dem folgenden Befehl erstellt, so dass GDB an dem Punkt brechen kann, direkt bevor es in die .text-Region schreibt.
(GDB) b * 0x00000000004006fb
Dann laufe ich das Programm in gdb. Aber der gdb stoppt nicht und führt den Signalhandler weiter aus.
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
Fragen: 1.Why gdb gewohnt an der Adresse breche ich angeben?
2.Wie kann ich gdb verwenden, damit ich die genaue Adresse kenne, auf die der Befehlszeiger zeigt, wenn er vom Signalhandler zurückkehrt?
Sie sollten printf nicht im Signalhandler verwenden –
@SeekAddo, OK. Ich kann es ändern, um Informationen in eine Datei zu protokollieren. Aber wie löse ich die Hauptfrage? – drdot
Mögliches Duplikat von [Wie kann ich GDB dazu bringen, mir mitzuteilen, welche Adresse einen Fehler verursacht hat?] (Https://stackoverflow.com/questions/3003339/how-can-i-get-gdb-to-tell-me-what -address-aded-a-segfault) –