gpt4 book ai didi

c - GDB 和 LLDB 都无法在简单的 C 文件中可靠地执行断点命令

转载 作者:太空狗 更新时间:2023-10-29 15:40:00 25 4
gpt4 key购买 nike

作为研究项目的一部分,我正在尝试编写一个 gdb 命令文件,该文件输出任意 C 源文件中每一行代码的特定信息,直到程序终止。这似乎很容易通过 while 循环完成,在循环中输出我想要的任何数据,然后在循环结束时调用“next”。 (我知道我希望“step”进入函数调用;我现在不关心这个。)

但是,除了我在每一行输出的数据,我还想在某些断点处执行特殊的命令。这似乎很容易通过“命令”完成。但是,我遇到了 while 循环和断点命令无法同时工作的问题。

这是我为测试目的而使用的极其简单的 C 文件:

int global;

int main() {
int x;
x=-1;
global = 5;
return(0);
}

我用 gcc -g -o simple simple.c 编译它。然后我运行 gdb -x commands.txt。如果commands.txt的内容如下:

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

...那么 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]

但是,如果我编辑命令文件以尝试作为循环执行,替换

next
next
next
continue

while true
next
end

但保留脚本的其余部分完全相同,然后我为第 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.

我知道当前形式的循环是有问题的,因为它会一直调用“next”直到程序终止(因此它永远不会到达脚本底部的“quit”),但这似乎不是就像它应该停止运行断点命令一样——但这似乎正在发生。 (如果正在执行断点命令,我可以设置我的 while 循环在遇到 C 程序退出点之前设置的断点时终止。)

这是 GDB 中的错误,还是我误解了什么?如果这种构造根本行不通,那么有没有办法在程序运行的每一步执行一系列固定的 GDB 命令,直到程序终止,同时还执行在某些断点处指定的命令——或者这根本不可能GDB 脚本?

(我的 gdb 版本是 7.11.1,如果重要的话,我的操作系统是 Linux。)


更新

我决定试一试 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

这是表现出相当奇怪的行为。上面的版本命中第一个断点,执行相关命令,然后忽略所有后续断点。如果我注释掉仅第二个断点、它的关联命令和相应的帧变量 x继续,那么断点 1 和 3 都会得到hit 并执行相应的命令。仅注释掉第一个或第三个断点及其关联的命令和 frame variable xcontinue 导致只有第一个未注释的断点被命中,并且其关联的命令运行。简而言之,似乎在连续两行代码上设置断点会导致第一个断点之后的所有断点都被忽略。

有人知道这是怎么回事吗?有没有办法让我在每一行都有一个断点并让它们都被击中?这个问题是否与上述 gdb 问题有任何关系?

最佳答案

我仍然没有弄清楚为什么 gdb 和 lldb 会按照它们的方式运行,但我确实设计了一种替代方法来实现我想要的。我编写了一个脚本,使用两个命名管道与 lldb 通信,脚本的标准输出链接到 lldb 的标准输入,反之亦然,因此脚本可以发送 lldb 命令(frame variable -L, bt step 等)然后获取 lldb 的输出并解析它。该脚本当然可以循环所有它想要的,所以这绕过了我无法让 gdb 或 lldb 命令文件正确循环的问题。

关于c - GDB 和 LLDB 都无法在简单的 C 文件中可靠地执行断点命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45043826/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com