如何在GDB中debuggingfork-exec进程的入口点?

我有一个C linux应用程序(A),它启动时产生另一个进程(P)。 当我想像往常一样debuggingPI启动A,并与ddd / gdb连接到P.

当我想debuggingP的入口点(主开始)的时候出现问题。如果按照通常的方法,当我将debugging器连接到P时已经晚了。 我find的解决scheme是在P的主开始插入一个睡眠,所以我有时间与gdb连接,但这不是一个非常优雅的解决scheme。

我也试过使用asm("int $3")但它似乎不工作。

你有什么想法我怎么能解决这个问题? (最好不改变A或P的代码)

Solutions Collecting From Web of "如何在GDB中debuggingfork-exec进程的入口点?"

你应该使用这个选项:

  set follow-fork-mode 模式 

模式parentchild或问题之一。

按照父母(这是默认)使用:

 set follow-fork-mode parent 

跟随孩子:

 set follow-fork-mode child 

要让调试器每次都问你:

 set follow-fork-mode ask 

所以基本上你会开始连接gdb到A,然后设置gdb跟随孩子,然后当A产生P时,gdb将连接到P并从A分离。

除了Nathan Fellman的回答之外 , 派头的人也会派上用场,ig:

 catch exec 

Catchpoint作为一个断点。 每次调用exec()系统调用时,GDB都会停止。 这允许您在继续之前在任何新加载的可执行文件中设置任何断点(ig break main )。 另一个catchpoint catch forkfork()系统调用检测类似。

特别方便:

  • 当父母和孩子都必须遵循( set detach-on-fork off );
  • 父进程分叉时经常加载各种可执行文件。

你应该可以使用gdb的远程调试功能,特别是gdbserver 。 实际上,使用gdbserver启动(P)。 这些链接有更详细的信息:

  • 使用gdbserver
  • GDB远程调试

exec部分与file + break main

叉是部分解释在: https : //stackoverflow.com/a/377295/895245

现在对于exec

AC:

 #include <unistd.h> int main(void) { execl("./b", "./b", "ab", "cd", (char*)NULL); return 1; } 

公元前:

 #include <stdio.h> int main(int argc, char **argv ) { printf("%s\n", argv[0]); printf("%s\n", argv[1]); } 

然后:

 gcc -g ac -oa gcc -g bc -ob gdb -nh -qa 

现在在互动会议上:

 Reading symbols from a...done. (gdb) start Temporary breakpoint 1 at 0x4004ea: file ac, line 4. Starting program: /home/cirsan01/test/gdb-exec/a Temporary breakpoint 1, main () at ac:4 4 execl("./b", "./b", "ab", "cd", (char*)NULL); (gdb) file b A program is being debugged already. Are you sure you want to change the file? (y or n) y Load new symbol table from "b"? (y or n) y Reading symbols from b...done. (gdb) b main Breakpoint 2 at 0x4004f5: file bc, line 4. (gdb) n Breakpoint 2, main (argc=0, argv=0x7fffffffa570) at bc:4 4 printf("%s\n", argv[1]); (gdb) n process 4877 is executing new program: /home/cirsan01/test/gdb-exec/b Breakpoint 2, main (argc=3, argv=0x7fffffffa598) at bc:4 4 printf("%s\n", argv[1]); (gdb) n ab 5 printf("%s\n", argv[2]); (gdb) n cd 6 } (gdb) 

在运行文件之前,你只需要确保你exec ,可能是使用b execl ,因为之后你将使用新文件中的符号。

测试在Ubuntu 14.04,gdb 7.7.1。

在main()中设置一个断点,它也会在execed程序的main()中断开。