我有一个 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
Run Code Online (Sandbox Code Playgroud)
我也试过这个:
$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]
Run Code Online (Sandbox Code Playgroud)
所以它会继续而不在断点处停止。值得一提的是,如果我run median.o < input
从 gdb 本身调用,它可以工作。
如何在由脚本运行的 C 程序上设置断点?
这是人们在使用 gdb 时遇到的一个经典问题。它太常见了,你会认为它会有一个方便的名字!
这个问题有几种解决方案,一些经过时间考验,一些相对更具实验性。
如果要调试的程序(在 gdb 行话中,“劣等”)是长时间运行的——例如,GUI 或某种服务器——那么最简单的方法就是运行脚本,等待劣等开始,然后附加到它。您可以使用 PID 进行附加,在 gdb 提示符下使用gdb -p PID
或使用attach PID
。
如果程序是短暂的,那么另一种经典的方法是sleep
在程序启动的早期添加一个调用;说作为 的第一行main
。然后,继续attach
计划。
这些都是经典的方法。但现在让我们谈谈更有趣的东西。
gdb 具有多劣模式,可以一次调试多个进程。这种模式,IME,仍然有点脆弱,但我已经取得了一些成功。
首先,您将 gdb 置于正确的模式:
set detach-on-fork off
set non-stop off
set pagination off
Run Code Online (Sandbox Code Playgroud)
(如果您有一个较旧的 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 Code Online (Sandbox Code Playgroud)
现在run
应该启动脚本,并自动将 gdb 附加到创建的每个子进程;最终停在断点处。
还有一种方法。很久以前,有一个内核补丁来添加“全局断点”,加上一个 gdb 补丁来使用这个功能。据我所知,这些都没有合并过。但是,我在我的gdb helpers项目中编写了一个变体。
那里有一个名为preattach
. 它的作用是使用 SystemTap 来监视exec
一个指定的程序;然后它在 gdb 附加到它时暂停这个程序。
归档时间: |
|
查看次数: |
5827 次 |
最近记录: |