将gdb on与execl、wait和ptrace一起使用

将gdb on与execl、wait和ptrace一起使用,gdb,multiprocessing,ptrace,Gdb,Multiprocessing,Ptrace,我正在调试一个调用另一个程序并使用ptrace的程序 我可以运行它,很好;然而,当试图用gdb调试它时,程序挂起在等待状态(&status)。我想做的是调试主进程,并可能来回切换 我认为显示代码和gdb输出会更容易: switch(pid = fork()) { case -1: /*error*/ { perror("fork()"); exit(-1); } case 0:/*child process*/ {

我正在调试一个调用另一个程序并使用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();
开关(pid=fork())
{
案例-1:/*错误*/
{
perror(“fork()”);
出口(-1);
}
案例0:/*子进程*/
{
ptrace(ptrace_TRACEME,NULL,NULL);/*允许跟踪子进程*/
execl(路径、名称、NULL);/*子级将在此处停止*/
perror(“execl()”);
出口(-1);
}
/*父级继续执行*/
}
等待(&状态);
while(true)
{
if(WIFEXITED(status)| |(WIFSIGNALED(status)&&WTERMSIG(status)=SIGKILL))
{

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

在Linux上,gdb调用
ptrace(ptrace_SETOPTIONS,…,TRACEFORK | TRACECLONE | TRACEEXEC)
TRACECLONE
确保在fork之后自动跟踪子进程。当目标进程fork时,gdb查看and的设置,并且其中一个保持连接到两个进程(但只允许一个进程运行)或者从一个进程中删除所有断点(如果有)并从中分离(从而允许两个进程运行,一个跟踪,一个不跟踪)


由于您已将
detach on fork
设置为
off
,gdb将保持连接到两个进程,并运行一个进程,另一个进程保持挂起状态。如果
follow fork mode
parent
,则默认情况下,父进程将运行,而
waitpid
只是挂起。如果
follow fork mode
child
,则ur
ptrace(ptrace\u TRACEME,…)
调用将失败,因为一个进程一次只能有一个跟踪程序。因此,最好的做法似乎是将
detach on fork
设置为
on
,以便gdb只跟踪父进程。

我在gdb 8.2.1中也遇到了同样的问题。
在gdb 8.3.1中,它似乎是固定的。

在fork上显示detach(在fork上显示detach)的输出是什么?
gdb是否将分离fork的子级是关闭的。将其设置为打开似乎有效。如果您想将其作为一个带有更多解释的答案来写,那么我将接受它。
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.