简体   繁体   English

附加到另一个进程时如何在gdb中设置断点

[英]How to set breakpoint in gdb when attach to another process

I have a C program which a really complicated script is written to run it. 我有一个C程序,编写了一个非常复杂的脚本来运行它。 I need to debug this program using gdb . 我需要使用gdb调试该程序。 I have tried to run the script and attach gdb to it's process, but then I'm not able to set breakpoints that I need: 我试图运行脚本并将gdb附加到它的进程中,但是后来我无法设置所需的断点:

$ gdb median.o 27944
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
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-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
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"...
Reading symbols from median.o...done.
Attaching to program: median.o, process 27944
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/ld-2.19.so...done.
done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00007fc376e9cbfa in ?? ()
(gdb) break median.c:10
Cannot access memory at address 0x40059d

I also tried this: 我也试过这个:

$gdb -p 28303
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
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-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
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".
Attaching to process 28303
Reading symbols from /bin/dash...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libc-2.19.so...done.
done.
Loaded symbols for /lib/x86_64-linux-gnu/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/ld-2.19.so...done.
done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00007fe918e50bfa in wait4 () at ../sysdeps/unix/syscall-template.S:81
81  ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) break median.c:10
No source file named median.c.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (median.c:10) pending.
(gdb) continue
Continuing.
Please enter 3 numbers separated by spaces > 6 is the median
[Inferior 1 (process 28303) exited normally]

So it continues without stopping at the breakpoint. 因此它继续运行而不会在断点处停止。 It is worth mentioning that if I call run median.o < input from gdb itself, it works. 值得一提的是,如果我从gdb本身调用run median.o < input ,它就可以工作。

How can I set breakpoints on a C program which is being run by a script? 如何在由脚本运行的C程序上设置断点?

This is a classic problem that people have with gdb. 这是人们使用gdb时遇到的经典问题。 It's so common that you'd think it would have a handy name! 它是如此普遍,以至于您会以为它有一个方便的名称!

There are a few solutions to the problem, some time-tested and some relatively more experimental. 有一些解决问题的方法,有些经过了时间的考验,而有些则相对更具实验性。

  • If the program to debug (in gdb lingo, "the inferior") is long-running -- for example, a GUI or a server of some kind -- then the simplest way is to just run the script, wait for the inferior to start, and then attach to it. 如果要调试的程序(在gdb术语中为“劣等”)是长时间运行的(例如,GUI或某种类型的服务器),那么最简单的方法是仅运行脚本,等待劣等开始,然后附加到它。 You can attach using the PID, either with gdb -p PID or using attach PID at the gdb prompt. 您可以使用PID进行附加,既可以使用gdb -p PID进行attach PID ,也可以在gdb提示符下使用attach PID

  • If the program is short-lived, then another classic approach is to add a call to sleep early in the program's startup; 如果程序是短命的,那么另一种经典方法是在程序启动时提早添加sleep调用。 say as the first line of main . 也就是说,作为第一线main Then, continue with the attach plan. 然后,继续执行attach计划。

Those are the classic ways. 这些是经典方式。 But now let's talk about the more fun stuff. 但是,现在让我们谈谈更有趣的东西。

gdb has a multi-inferior mode, where it can debug multiple processes at once. gdb具有多种劣质模式,可以同时调试多个进程。 This mode, IME, is still a bit fragile, but I've had some success with it. IME这种模式仍然有点脆弱,但是我已经取得了一些成功。

First you put gdb into the correct mode: 首先,将gdb设置为正确的模式:

set detach-on-fork off
set non-stop off
set pagination off

(If you have an older gdb you will also need set target-async on ). (如果您有较旧的gdb,则还需要set target-async on )。

Now you can debug the shell , something like: 现在您可以调试shell ,例如:

$ gdb --args /bin/sh /path/to/my/script
(gdb) [... set the mode as above ...]
(gdb) break some_function_in_my_inferior

Now run should start the script, and automatically attach gdb to each child process that's created; 现在run应该启动脚本,并自动将gdb附加到创建的每个子进程中; eventually stopping at the breakpoint. 最终在断点处停止。

There's still one more way. 还有另一种方法。 A long time ago, there was a kernel patch to add "global breakpoints", plus a gdb patch to work with this feature. 很久以前,有一个内核补丁程序可以添加“全局断点”,还有一个gdb补丁程序可以使用此功能。 As far as I know, none of this was ever merged. 据我所知,这些都没有合并。 But, I wrote a variant in my gdb helpers project. 但是,我在gdb帮助程序项目中编写了一个变体。

There is a new command there called preattach . 那里有一个称为preattach的新命令。 What it does is use SystemTap to watch for an exec of a specified program; 它所做的是使用的SystemTap看一个exec指定的程序的; then it pauses this program while gdb attaches to it. 然后在gdb附加到该程序时暂停该程序。

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

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