我有一个C程序,编写一个非常复杂的脚本来运行它。我需要使用gdb
调试此程序。我试图运行脚本并将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
我也试过这个:
$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]
所以它继续而不是在断点停止。值得一提的是,如果我从gdb本身调用run median.o < input
,它就可以工作。
如何在脚本运行的C程序上设置断点?
答案 0 :(得分:3)
这是人们对gdb的一个经典问题。这很常见,以至于你认为它会有一个方便的名字!
这个问题有一些解决方案,一些经过时间考验,一些相对更具实验性。
如果要调试的程序(在gdb语言中,&#34;劣等&#34;)长时间运行 - 例如,GUI或某种服务器 - 那么最简单的方法是只是运行脚本,等待下级开始,然后附加到它。您可以使用PID进行附加,使用gdb -p PID
或在gdb提示符下使用attach PID
。
如果程序是短暂的,那么另一种经典方法是在程序启动的早期添加对sleep
的调用;说是main
的第一行。然后,继续attach
计划。
这些是经典的方式。但现在让我们谈谈更有趣的事情。
gdb具有多劣模式,可以一次调试多个进程。这种模式,IME,仍然有点脆弱,但我已经取得了一些成功。
首先,您将gdb置于正确的模式:
set detach-on-fork off
set non-stop off
set pagination off
(如果你有一个较旧的gdb,你还需要set target-async on
)。
现在您可以调试 shell ,例如:
$ gdb --args /bin/sh /path/to/my/script
(gdb) [... set the mode as above ...]
(gdb) break some_function_in_my_inferior
现在run
应启动脚本,并自动将gdb附加到已创建的每个子进程;最终在断点处停下来。
还有一种方法。很久以前,有一个内核补丁添加&#34;全局断点&#34;,加上一个gdb补丁来处理这个功能。据我所知,这一切都没有合并过。但是,我在gdb helpers项目中编写了一个变体。
有一个名为preattach
的新命令。它的作用是使用SystemTap来监视指定程序的exec
;然后它会在gdb附加到它时暂停这个程序。