As part of a research project, I am trying to write a gdb command file that outputs certain information on every line of code in arbitrary C source files until the program terminates. This seems easily accomplished with a while loop, outputting whatever data I want within the loop, and then calling "next" at the end of the loop. (I know I would want "step" to enter function calls; I'm not concerned about that at the moment.)
作为一个研究项目的一部分,我正在尝试编写一个gdb命令文件,它在任意C源文件中的每一行代码上输出某些信息,直到程序终止。这似乎很容易通过while循环实现,在循环中输出我想要的任何数据,然后在循环的末尾调用“next”。(我知道我想要“step”输入函数调用;我现在不担心这个。
However, in addition to the data I output on every line, I also want to execute special commands at certain breakpoints. This seems easily accomplished with "command". However, I'm encountering a problem where the while loop and breakpoint commands won't both work.
然而,除了我在每一行上输出的数据之外,我还希望在某些断点上执行特殊的命令。这似乎很容易通过“命令”来实现。但是,我遇到了一个问题,即while循环和断点命令不能同时工作。
Here is the extremely simple C file I'm working with for testing purposes:
下面是我用于测试目的的极其简单的C文件:
int global;
int main() {
int x;
x=-1;
global = 5;
return(0);
}
I compile it with gcc -g -o simple simple.c
. Then I run gdb -x commands.txt
. If the contents of commands.txt are the following:
我使用gcc -g -o简单的simple.c编译它。然后运行gdb -x命令。如果是命令的内容。以下三种:
set confirm off
exec-file simple
file simple
set logging file gdb_output.txt
set logging on
set pagination off
#Special commands I want to execute on certain breakpoints
break 5
command
echo COMMAND 1 ACTIVATED\n
end
break 6
command
echo COMMAND 2 ACTIVATED\n
end
break 7
command
echo COMMAND 3 ACTIVATED\n
end
run
next
next
next
continue
quit
...then the contents of gdb_output.txt are the following, as expected:
…然后是gdb_output的内容。txt如下所示:
Breakpoint 1 at 0x4004da: file simple.c, line 5.
Breakpoint 2 at 0x4004e1: file simple.c, line 6.
Breakpoint 3 at 0x4004eb: file simple.c, line 7.
Breakpoint 1, main () at simple.c:5
5 x=-1;
COMMAND 1 ACTIVATED
Breakpoint 2, main () at simple.c:6
6 global = 5;
COMMAND 2 ACTIVATED
Breakpoint 3, main () at simple.c:7
7 return(0);
COMMAND 3 ACTIVATED
8 }
[Inferior 1 (process 29631) exited normally]
However, if I edit the command file to try to execute as a loop, replacing
但是,如果我编辑命令文件,尝试作为循环执行,替换
next
next
next
continue
with
与
while true
next
end
but leaving the rest of the script exactly the same, then the commands I specified for the breakpoints on lines 6&7 never execute, as evidenced by the contents of gdb_output.txt after running the modified command file:
但是,将剩下的脚本完全相同,然后我为第6和7行上的断点指定的命令永远不会执行,因为gdb_output的内容证明了这一点。运行修改后的命令文件txt:
Breakpoint 1 at 0x4004da: file simple.c, line 5.
Breakpoint 2 at 0x4004e1: file simple.c, line 6.
Breakpoint 3 at 0x4004eb: file simple.c, line 7.
Breakpoint 1, main () at simple.c:5
5 x=-1;
COMMAND 1 ACTIVATED
Breakpoint 2, main () at simple.c:6
6 global = 5;
Breakpoint 3, main () at simple.c:7
7 return(0);
8 }
__libc_start_main (main=0x4004d6 <main()>, argc=1, argv=0x7fffffffe128, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe118) at ../csu/libc-start.c:325
325 ../csu/libc-start.c: No such file or directory.
[Inferior 1 (process 29652) exited normally]
commands.txt:30: Error in sourced command file:
The program is not being run.
I know that the loop in its current form is problematic in that it will just keep calling "next" until the program terminates (so it never reaches "quit" at the bottom of the script), but that doesn't seem like it should stop the breakpoint commands from being run -- yet that is what appears to be happening. (If the breakpoint commands were being executed, I could condition my while loop to terminate once it hit breakpoints set before the C program's exit points.)
我知道循环以当前的形式是有问题的,它只会让程序调用“下一步”,直到终止(因此它永远无法达到“退出”脚本的底部),但这并不像它应该阻止断点命令运行——然而,似乎发生了什么。(如果正在执行断点命令,我可以将while循环设置为在C程序的退出点之前到达设置的断点后终止。)
Is this a bug in GDB, or am I misunderstanding something? If this construction fundamentally won't work, then is there a way to execute a canned series of GDB commands on every step of a program run until the program terminates, while also executing commands specified at certain breakpoints -- or is this fundamentally impossible with a GDB script?
这是GDB中的一个bug,还是我误解了什么?如果这种构造根本不起作用,那么是否有一种方法可以在程序运行的每个步骤上执行一系列GDB命令,直到程序终止,同时还可以执行在某些断点处指定的命令——或者这在GDB脚本中根本不可能实现?
(My gdb version is 7.11.1 and if it matters, my OS is Linux.)
(我的gdb版本是7.11.1,如果重要的话,我的操作系统是Linux。)
UPDATE
更新
I decided to give lldb a shot and ran into some more perplexing issues (using the same C file as above, compiled with the same command). Here is my lldb script:
我决定尝试一下lldb,并遇到了一些更复杂的问题(使用与上面相同的C文件,使用相同的命令编译)。下面是我的lldb脚本:
target create --no-dependents --arch x86_64 simple
breakpoint set --file simple.c --line 5
breakpoint command add
script print "COMMAND 1 ACTIVATED"
DONE
breakpoint set --file simple.c --line 6
breakpoint command add
script print "COMMAND 2 ACTIVATED"
DONE
breakpoint set --file simple.c --line 7
breakpoint command add
script print "COMMAND 3 ACTIVATED"
DONE
run
frame variable x
continue
frame variable x
continue
frame variable x
continue
quit
This is exhibiting rather strange behavior. The above version hits the first breakpoint, executes the associated command, then ignores all the following breakpoints. If I comment out just the second breakpoint, its associated command, and the corresponding frame variable x
, continue
, then breakpoints 1 and 3 both get hit and their corresponding commands are executed. Commenting out only the 1st or 3rd breakpoint and its associated command and frame variable x
, continue
results in just the first uncommented breakpoint getting hit, and its associated command run. In short, it appears that having breakpoints on two consecutive lines of code causes all breakpoints after the first to be ignored.
这显示出相当奇怪的行为。上面的版本到达第一个断点,执行相关的命令,然后忽略以下所有断点。如果我注释掉第二个断点,它的关联命令,以及相应的帧变量x,继续,然后断点1和3都被命中,并且执行相应的命令。只注释掉第1或第3个断点及其相关的命令和框架变量x,继续只会导致第一个未注释的断点被命中,并运行其相关的命令。简而言之,如果连续两行代码中有断点,那么第一行之后的所有断点都将被忽略。
Does anyone know what is going on here? Is there a way I can have a breakpoint on every line and have them all get hit? And is this problem in any way related to the gdb issues described above?
有人知道这是怎么回事吗?有没有一种方法可以让我在每一行都有一个断点,让它们都被命中?这个问题是否与上面描述的gdb问题有关?
1 个解决方案
#1
0
I still haven't figured out why gdb and lldb were acting the way they were, but I did devise an alternative approach to accomplish what I want. I wrote a script to communicate with lldb using two named pipes whereby the script's stdout is linked to lldb's stdin and vice-versa, so the script can send lldb commands (frame variable -L
, bt
, step
, etc.) then get lldb's output and parse it. The script can of course loop all it wants, so this bypasses the problem where I couldn't get gdb or lldb command files to loop properly.
我还没弄明白为什么gdb和lldb会这样做,但我确实设计了一种替代方法来实现我想要的。我编写了一个脚本,使用两个命名管道与lldb进行通信,其中脚本的stdout链接到lldb的stdin,反之亦然,因此脚本可以发送lldb命令(框架变量-L、bt、step等),然后获取lldb的输出并解析它。脚本当然可以循环它想要的所有内容,因此这绕过了无法让gdb或lldb命令文件正确循环的问题。
#1
0
I still haven't figured out why gdb and lldb were acting the way they were, but I did devise an alternative approach to accomplish what I want. I wrote a script to communicate with lldb using two named pipes whereby the script's stdout is linked to lldb's stdin and vice-versa, so the script can send lldb commands (frame variable -L
, bt
, step
, etc.) then get lldb's output and parse it. The script can of course loop all it wants, so this bypasses the problem where I couldn't get gdb or lldb command files to loop properly.
我还没弄明白为什么gdb和lldb会这样做,但我确实设计了一种替代方法来实现我想要的。我编写了一个脚本,使用两个命名管道与lldb进行通信,其中脚本的stdout链接到lldb的stdin,反之亦然,因此脚本可以发送lldb命令(框架变量-L、bt、step等),然后获取lldb的输出并解析它。脚本当然可以循环它想要的所有内容,因此这绕过了无法让gdb或lldb命令文件正确循环的问题。