2016-02-12 76 views
1

我想調試調用另一個程序並使用ptrace的程序。使用GDB與execl,等待和ptrace

我可以運行它,很好;然而,當試圖用gdb進行調試時,程序在等待時掛起(&狀態)。我想要做的是調試主進程並可能來回切換。

我認爲這將是更容易顯示代碼和gdb輸出:

switch(pid = fork()) 
    { 
    case -1: /*error*/ 
    { 
     perror("fork()"); 
     exit(-1); 
    } 
    case 0:/*child process*/ 
    { 
     ptrace(PTRACE_TRACEME, NULL, NULL);  /*allow child process to be traced*/ 
     execl(path, name, NULL);    /*child will be stopped here*/ 
     perror("execl()"); 
     exit(-1); 
    } 
    /*parent continues execution*/ 
    } 

    wait(&status); 
    while(true) 
    { 
    if(WIFEXITED(status) || (WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)) 
    { 
     cout << "process " << child << "terminated\n"; 
     exit(0); 
    } 
    get_and_handle_input(); 

當用gdb,它停靠在等待(&狀態):

gdb ./prog 
GNU gdb (GDB; openSUSE 13.2) 7.8 
Copyright (C) 2014 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-suse-linux". 
Type "show configuration" for configuration details. 
For bug reporting instructions, please see: 
<http://bugs.opensuse.org/>. 
Find the GDB manual and other documentation resources online at: 
<http://www.gnu.org/software/gdb/documentation/>. 
For help, type "help". 
Type "apropos word" to search for commands related to "word"... 

warning: /etc/gdbinit.d/gdb-heap.py: No such file or directory 
Reading symbols from ./prog...done. 
(gdb) r ../tests/function_test 
Starting program: /home/user/dev/src/prog ../tests/function_test 
[New process 7930] 
^C 
Program received signal SIGINT, Interrupt. 
0x00007ffff68479d2 in __libc_wait (stat_loc=0x7fffffffdc7c) at ../sysdeps/unix/sysv/linux/wait.c:30 
30   return INLINE_SYSCALL (wait4, 4, WAIT_ANY, stat_loc, 0, 
(gdb) bt 
#0 0x00007ffff68479d2 in __libc_wait (stat_loc=0x7fffffffdc7c) at ../sysdeps/unix/sysv/linux/wait.c:30 
#1 0x00000000004059bc in main (argc=<optimized out>, argv=<optimized out>) at shell.cpp:44 
(gdb) info inferiors 
    Num Description  Executable   
    2 process 7930  /home/user/dev/src/prog 
* 1 process 7926  /home/user/dev/src/prog 
(gdb) continue 
Continuing. 

如果我切換到進程2並繼續使用,然後進程2運行;然而,這對我沒有任何好處(即使我在過程1中設置了一個斷點)。

希望這是有道理的。如果我需要清理任何東西,請告訴我。

+1

'(gdb)show detach-on-fork'的輸出是什麼? –

+0

'gdb是否會將叉子的孩子分開.' – SailorCire

+0

將它設置爲開啓似乎工作。如果你想把它寫成一個更多解釋的答案,那麼我會接受它。 – SailorCire

回答

1

當它可以的時候,gdb會嘗試在目標進程中得到fork事件的通知。

在Linux上,gdb調用ptrace(PTRACE_SETOPTIONS,...,TRACEFORK|TRACECLONE|TRACEEXEC)TRACECLONE可確保在分叉後自動跟蹤子進程。當目標進程分叉時,gdb查看follow-fork-modedetach-on-fork的設置,並且或者保持連接到兩個進程(但只允許一個運行)或從一個進程中刪除所有斷點(如果有的話)並從中分離(因此允許兩個進程運行,一個追蹤,一個不)。

既然你已經設置detach-on-forkoff,GDB保持連接到這兩個進程,並運行一個進程,並保持其他暫停。如果follow-fork-modeparent,則默認情況下,父項運行並且waitpid只是掛起。如果follow-fork-modechild,則您的ptrace(PTRACE_TRACEME, ...)調用將失敗,因爲一次只能有一個Tracer進行過程。所以最好的做法似乎是將detach-on-fork設置爲on,以便gdb只會跟蹤父進程。