2017-06-04 40 views
0

我寫了一個簡單的程序來理解信號處理程序的控制流轉移。以下程序將讓孩子重複地寫入.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.爲什麼GDB在我指定的地址不會破?

我2.How可以使用gdb的,讓我知道確切地址的指令指針指向當它從信號處理程序返回?在地址

+1

在信號處理 –

+0

@SeekAddo你不應該用printf,OK。我可以將其更改爲將信息記錄到文件。但我如何解決主要問題。 – drdot

+0

可能的重複[如何讓GDB告訴我什麼地址導致了段錯誤?](https://stackoverflow.com/questions/3003339/how-can-i-get-gdb-to-tell-me-what -address-caused-a-segfault) –

回答

1

爲什麼GDB不會休息我指定?

因爲你正在調試的錯誤(父)進程。

要停止的指令只在孩子執行,調試的不是孩子。

要調試的孩子,使用set follow-fork-mode child

如何使用gdb,以便我知道指令指針從信號處理程序返回時指向的確切地址?

放在在信號處理程序中的指令ret一個斷點,並做x/a $rsp時斷點命中。