【发布时间】:2019-12-12 04:56:24
【问题描述】:
我正在调试一个大型多线程应用程序,并试图在将无效指针值分配给变量时捕获错误。我不能简单地从故障点回溯,因为消费者和生产者是不同的线程,所以我试图在该变量的每个赋值语句上设置一个条件断点,以测试赋值是否无效。
让我们考虑这个例子:
#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 中的指针是否无效,它足够短,可以在单行条件中使用并且不依赖于指向的值。
【问题讨论】:
-
“我不确定这种方法是否可靠”。即使除了您指出的问题,我也看不出这是多么可靠。该条件检查 0 值,但根本不能保证无效指针指向 0。事实上,无效指针可能会在访问时出现段错误,甚至更糟的是,它会指向随机内存,这将不是段错误,并且在访问时不会返回可预测的值。
-
所以退后一步,在这种情况下,您对“无效指针”的定义是什么?也就是说,您如何得出问题在于指针具有无效值的结论?
-
@kaylum 这里的“无效指针”是指“取消引用时会导致段错误的东西”。我知道这个定义太狭窄了,但对我来说已经足够了
-
看来你知道任务发生在哪里。如果这是真的,那么只需将分配更改为函数调用。函数调用将首先尝试取消引用指针,然后执行实际分配。然后调试器可以将此作为正常的段错误捕获。小心确保编译器不会优化代码的取消引用部分。
-
感谢您的建议,但这是一些遗留代码,除非必要,否则我真的不想修改它。如果没有更好的方法,我会这样做