使用带有execl,wait和ptrace的gdb

时间:2016-02-12 18:06:01

标签: gdb multiprocessing ptrace

我正在尝试调试调用另一个程序并使用ptrace的程序。

我可以运行它,就好了;但是,当尝试使用gdb调试它时,程序会在等待(& status)时挂起。我想要做的是调试主进程并可能来回切换。

我认为显示代码和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时,它会在等待(&amp; status)停止:

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并使用continue,则进程2运行;然而,这对我没有任何好处(即使我在过程1中设置了一个断点)。

希望这是有道理的。如果我需要清除任何内容,请告诉我。

2 个答案:

答案 0 :(得分:1)

如果可以,gdb会尝试通知目标进程中的fork事件。

在Linux上,gdb调用ptrace(PTRACE_SETOPTIONS,...,TRACEFORK|TRACECLONE|TRACEEXEC)TRACECLONE确保在fork之后自动跟踪子进程。当目标进程分叉时,gdb查看follow-fork-modedetach-on-fork的设置,并且保持附加到两个进程(但只允许运行)或从一个进程中删除所有断点(如果有)处理和分离(因此允许两个进程运行,一个跟踪,一个跟踪)。

由于您已将detach-on-fork设置为off,因此gdb仍会附加到这两个进程,并运行一个进程并保持另一个进程暂停。如果follow-fork-modeparent,则为默认值,父项运行且waitpid仅挂起。如果follow-fork-modechild,则您的ptrace(PTRACE_TRACEME, ...)来电将失败,因为一次只能有一个跟踪进程。因此,最佳做法似乎是将detach-on-fork设置为on,以便gdb只跟踪父进程。

答案 1 :(得分:0)

我在gdb 8.2.1中遇到了同样的问题。 它似乎已在gdb 8.3.1中修复。