I want to debug a program, using gdb. But I invoke that program through a script.
我想使用gdb调试程序。但我通过脚本调用该程序。
How can I use gdb? The script is long and its not possible for me to invoke the program directly using command line arguments from gdb.
我怎样才能使用gdb?脚本很长,我无法使用gdb中的命令行参数直接调用程序。
Also the process that is created when the script starts is short lived so can't attach gdb to the process.
脚本启动时创建的进程也很短暂,因此无法将gdb附加到进程。
What I want to do is something like, start gdb with that program, add my breakpoints then execute the script (FYI - it also takes arguments), then when it hits breakpoint do whatever I want.
我想做的是,用这个程序启动gdb,添加我的断点然后执行脚本(FYI - 它也接受参数),然后当它遇到断点时做我想做的任何事情。
I looked at shell option in gdb, but that spawns a new shell if I am not wrong and return to gdb when done. This is not what I want.
我在gdb中查看了shell选项,但是如果我没有错误会产生一个新shell,并在完成后返回gdb。这不是我想要的。
Please let me know if there is a better way.
如果有更好的方法,请告诉我。
2 个解决方案
#1
8
There are several ways.
有几种方法。
The truly old-school way is to hack a loop into your program's main
like:
真正的老派方式是破解你的程序主要的循环,如:
volatile int zzz;
...
int main() {
while (!zzz) sleep (1);
Then, run your script. In a separate window, run gdb on the program you want to debug, and use attach
to attach to the sleeping program. Then you can set breakpoints, etc, and finally:
然后,运行您的脚本。在单独的窗口中,在要调试的程序上运行gdb,并使用attach附加到休眠程序。然后你可以设置断点等,最后:
(gdb) set var zzz = 1
(gdb) cont
A slightly newer ("new" as in "it's been in gdb at least 10 years") way is to edit your script and put a gdb --args
before the invocation of the program you want to debug. This method doesn't always work, though. It doesn't handle redirections properly, among other things.
一个稍微更新的(“新的”,如“它已经在gdb中至少10年”)方式是编辑脚本并在调用要调试的程序之前放置一个gdb --args。但是,这种方法并不总是有效。除其他外,它不能正确处理重定向。
Finally, you can use multi-inferior debugging. This is the "newest" approach of all. Here I'm following my own blog post on the topic:
最后,您可以使用多次调试。这是所有人的“最新”方法。在这里,我正在关注该主题的自己的博客文章:
$ gdb /bin/sh # or whatever runs your script
(gdb) set args arguments-to-the-script
(gdb) set detach-on-fork off
(gdb) set target-async on
(gdb) set non-stop on
(gdb) set pagination off
Then you can do something like:
然后你可以这样做:
(gdb) add-inferior -exec program-you-want-to-debug
... then switch to that inferior and set breakpoints. Now switch back to the first inferior and run
-- it should all work!
...然后切换到那个劣势并设置断点。现在切换回第一个下级并运行 - 它应该全部工作!
#2
1
A couple of methods I have used in the past.
我过去使用过的几种方法。
- Rename
yourprog
toyourprog.real
. Make a script namedyourprog
that runsgdb --args yourprog.real "$@"
. - Make
yourprog
invokegdb
on its ownpid
, then callsleep
in a loop.
将yourprog重命名为yourprog.real。创建一个名为yourprog的脚本来运行gdb --args yourprog.real“$ @”。
让yourprog在自己的pid上调用gdb,然后在循环中调用sleep。
#1
8
There are several ways.
有几种方法。
The truly old-school way is to hack a loop into your program's main
like:
真正的老派方式是破解你的程序主要的循环,如:
volatile int zzz;
...
int main() {
while (!zzz) sleep (1);
Then, run your script. In a separate window, run gdb on the program you want to debug, and use attach
to attach to the sleeping program. Then you can set breakpoints, etc, and finally:
然后,运行您的脚本。在单独的窗口中,在要调试的程序上运行gdb,并使用attach附加到休眠程序。然后你可以设置断点等,最后:
(gdb) set var zzz = 1
(gdb) cont
A slightly newer ("new" as in "it's been in gdb at least 10 years") way is to edit your script and put a gdb --args
before the invocation of the program you want to debug. This method doesn't always work, though. It doesn't handle redirections properly, among other things.
一个稍微更新的(“新的”,如“它已经在gdb中至少10年”)方式是编辑脚本并在调用要调试的程序之前放置一个gdb --args。但是,这种方法并不总是有效。除其他外,它不能正确处理重定向。
Finally, you can use multi-inferior debugging. This is the "newest" approach of all. Here I'm following my own blog post on the topic:
最后,您可以使用多次调试。这是所有人的“最新”方法。在这里,我正在关注该主题的自己的博客文章:
$ gdb /bin/sh # or whatever runs your script
(gdb) set args arguments-to-the-script
(gdb) set detach-on-fork off
(gdb) set target-async on
(gdb) set non-stop on
(gdb) set pagination off
Then you can do something like:
然后你可以这样做:
(gdb) add-inferior -exec program-you-want-to-debug
... then switch to that inferior and set breakpoints. Now switch back to the first inferior and run
-- it should all work!
...然后切换到那个劣势并设置断点。现在切换回第一个下级并运行 - 它应该全部工作!
#2
1
A couple of methods I have used in the past.
我过去使用过的几种方法。
- Rename
yourprog
toyourprog.real
. Make a script namedyourprog
that runsgdb --args yourprog.real "$@"
. - Make
yourprog
invokegdb
on its ownpid
, then callsleep
in a loop.
将yourprog重命名为yourprog.real。创建一个名为yourprog的脚本来运行gdb --args yourprog.real“$ @”。
让yourprog在自己的pid上调用gdb,然后在循环中调用sleep。