简体   繁体   English

如何在GDB中调试fork-exec进程的入口点?

[英]How to debug the entry-point of fork-exec process in GDB?

I have a C linux application (A) that spawns another process (P) when it is started. 我有一个C linux应用程序(A),它启动时产生另一个进程(P)。 When I want to debug PI start A as usual and I connect with ddd/gdb to P. 当我想像往常一样调试PI start A并且我用ddd / gdb连接到P.

Problems appear when I want to debug the entry-point (start of main) of P. If I follow the usual approach when I connect the debugger to P is already to late. 当我想调试P的入口点(主要的开始)时出现问题。如果我将调试器连接到P时遵循通常的方法已经很晚了。 The solution I've found was to insert a sleep at the begining of the main of P so I have time to connect with gdb but this is not a very elegant solution. 我发现的解决方案是在P的主要开头插入一个睡眠,所以我有时间与gdb连接,但这不是一个非常优雅的解决方案。

I've also tried using asm("int $3") but it doesn't seems to work. 我也尝试过使用asm("int $3")但它似乎不起作用。

Do you have any idea how I could solve this problem? 你知道我怎么能解决这个问题吗? (preferably without altering the code of A or P) (最好不要改变A或P的代码)

You should use this option: 您应该使用此选项:

set follow-fork-mode mode

Where mode is one of parent , child or ask . 模式parentchildask

To follow the parent (this is the default) use: 要遵循父级(这是默认值),请使用:

set follow-fork-mode parent

To follow the child: 跟随孩子:

set follow-fork-mode child

To have the debugger ask you each time: 让调试器每次都问你:

set follow-fork-mode ask

So basically you'd start out connecting gdb to A, then set gdb to follow the child, and then when A spawns P, gdb will connect to P and detach from A. 所以基本上你开始将gdb连接到A,然后设置gdb跟随子,然后当A生成P时,gdb将连接到P并从A分离。

In addition to the Nathan Fellman's answer , catchpoints come in handy, ig: 除了Nathan Fellman的答案之外抓点也很方便,ig:

catch exec

Catchpoint works as a breakpoint. Catchpoint用作断点。 Every time a call to exec() syscall is detected, GDB stops. 每次检测到对exec()系统调用的调用时,GDB都会停止。 This allows you to set any breakpoint (ig break main ) in any newly loaded executable before continuing. 这允许您在继续之前在任何新加载的可执行文件中设置任何断点(ig break main )。 Another catchpoint catch fork works similarly for fork() syscall detection. 另一个catchpoint catch fork类似于fork()系统调用检测。

It is especially convenient: 特别方便:

  • when both parent and child has to be followed ( set detach-on-fork off ); 当必须遵循父母和子女时( set detach-on-fork off );
  • when parent processes forks often loading various executables. 当父进程分叉经常加载各种可执行文件时。

You should be able to do this by making use of gdb's remote debugging features, specifically gdbserver . 您应该能够通过使用gdb的远程调试功能(特别是gdbserver来实现此目的。 In effect, launch (P) using gdbserver . 实际上,使用gdbserver启动(P)。 These links have more detailed info: 这些链接有更详细的信息:

exec part with file + break main exec部分file + break main

The fork was part was explained at: https://stackoverflow.com/a/377295/895245 叉子的部分解释如下: https//stackoverflow.com/a/377295/895245

Now for the exec : 现在为exec

ac: AC:

#include <unistd.h>

int main(void) {
    execl("./b", "./b", "ab", "cd", (char*)NULL);
    return 1;
}

bc: 公元前:

#include <stdio.h>

int main(int argc, char **argv ) {
    printf("%s\n", argv[0]);
    printf("%s\n", argv[1]);
}

Then: 然后:

gcc -g a.c -o a
gcc -g b.c -o b
gdb -nh -q a

Now on the interactive session: 现在进行交互式会话:

Reading symbols from a...done.
(gdb) start
Temporary breakpoint 1 at 0x4004ea: file a.c, line 4.
Starting program: /home/ciro/test/gdb-exec/a 

Temporary breakpoint 1, main () at a.c: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 b.c, line 4.
(gdb) n

Breakpoint 2, main (argc=0, argv=0x7fffffffa570) at b.c:4
4               printf("%s\n", argv[1]);
(gdb) n
process 4877 is executing new program: /home/ciro/test/gdb-exec/b

Breakpoint 2, main (argc=3, argv=0x7fffffffa598) at b.c:4
4               printf("%s\n", argv[1]);
(gdb) n
ab
5               printf("%s\n", argv[2]);
(gdb) n
cd
6       }
(gdb) 

You just have to make sure that you go up to the exec before running file, possibly with a b execl , since after that you will be using symbols from the new file. 你必须确保在运行文件之前你去了exec ,可能还有一个b execl ,因为之后你将使用新文件中的符号。

Tested in Ubuntu 14.04, gdb 7.7.1. 在Ubuntu 14.04中测试,gdb 7.7.1。

在main()处设置一个断点,它也会在执行程序的main()处断开。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM