gpt4 book ai didi

c - 设置条件断点以捕获无效指针值

转载 作者:行者123 更新时间:2023-12-01 01:36:37 24 4
gpt4 key购买 nike

我正在调试一个大型多线程应用程序,并试图在将无效指针值分配给变量时捕获错误。我不能简单地从失败点回溯,因为消费者和生产者是不同的线程,所以我试图在该变量的每个赋值语句上设置一个条件断点,以测试赋值是否无效。

让我们考虑这个例子:

#include <stdio.h>

int main() {
char* arr[] = {"foo", "bar", 0x1234, "baz"};

for(int i=0; i<4; ++i) {
char* str = arr[i];

puts(str);
}
}

我发现我可以这样处理:

break test.c:7 if !arr[i][0]

它有效,但是,我不确定这种方法是否可靠,因为它实际上试图访问(可能)无效的内存地址。此外,当字符串为空时,它具有明显的误报。

此外,我遇到了 this answer ,但看起来我必须以某种方式告诉链接器将这些函数添加到我的可执行文件中以供 gdb 使用,而且它看起来太复杂而无法在单行条件下使用。

所以,我的问题是:是否有任何可靠的方法来检查指针在 gdb 中是否无效,它足够短,可以在单行条件中使用并且不依赖于指针值。

最佳答案

由于您使用的是 Linux,最好的方法是最有可能使用反向 调试器,例如 rr .

你用 rr record ./a.out arg0 ... 运行程序,然后,一旦它崩溃,你可以在“坏”变量上设置一个观察点,并且 reverse-continue 一直到变量最后更改的地方。它就像魔法一样有效!

这是一个与您的示例相关的 session :

$ rr record ./a.out
rr: Saving execution to trace directory `$HOME/.local/share/rr/a.out-5'.
foo
bar
Segmentation fault

$ rr replay
...
Program stopped.
0x00007f69546b4f30 in _start () from /lib64/ld-linux-x86-64.so.2
(rr) c
Continuing.
foo
bar

Program received signal SIGSEGV, Segmentation fault.
__strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:96
96 ../sysdeps/x86_64/multiarch/strlen-avx2.S: No such file or directory.
(rr) bt
#0 __strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:96
#1 0x00007f6954366040 in __GI__IO_puts (str=0x1234 <error: Cannot access memory at address 0x1234>) at ioputs.c:35
#2 0x000056227d5ec189 in main () at foo.c:9

(rr) up
#1 0x00007f6954366040 in __GI__IO_puts (str=0x1234 <error: Cannot access memory at address 0x1234>) at ioputs.c:35
35 ioputs.c: No such file or directory.
(rr) up
#2 0x000056227d5ec189 in main () at foo.c:9
9 puts(str);
(rr) p str
$1 = 0x1234 <error: Cannot access memory at address 0x1234>
(rr) watch -l str
Hardware watchpoint 1: -location str
(rr) reverse-cont
Continuing.

Program received signal SIGSEGV, Segmentation fault.
__strlen_avx2 () at ../sysdeps/x86_64/multiarch/strlen-avx2.S:96
96 ../sysdeps/x86_64/multiarch/strlen-avx2.S: No such file or directory.
(rr) reverse-cont
Continuing.

Hardware watchpoint 1: -location str

Old value = 0x1234 <error: Cannot access memory at address 0x1234>
New value = 0x56227d5ed008 "bar"
0x000056227d5ec179 in main () at foo.c:7
7 char* str = arr[i];
(rr) p i
$2 = 2
(rr) p arr[i]
$3 = 0x1234 <error: Cannot access memory at address 0x1234>

关于c - 设置条件断点以捕获无效指针值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59297955/

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