使用 gdb 调试 C 预处理器宏中的崩溃
我有一个带有多行宏的 C 程序,并且该程序在宏内崩溃,如何查明发生崩溃的在宏内的位置?
这是我的程序的简化版本。实际上,CRASHES
有多行长,并且不容易手动扩展。
#include <stdio.h>
#include <stdarg.h>
#define CRASHES(ptr) \
(*(ptr) == 123)
main()
{
char *foo = NULL;
if (CRASHES(foo))
printf("This will never happen.");
}
当使用 gdb a.out
编译并运行它时,我得到了预期的 EXC_BAD_ACCESS
(我使用的是带有 gdb 6.3 的 Mac OS X),但是崩溃指向第 8 行而不是第 4 行是实际导致崩溃的地方。
我已经尝试按照 docs 并在宏本身中插入了几个 assert()
。不幸的是,这并没有提供更多信息。
I have a C program with a multi-line macro and the program crashes within the macro, how can I pinpoint the location within the macro where the crash happens?
Here is a simplified version of my program. In reality CRASHES
is multiple lines long and not easily expandable manually.
#include <stdio.h>
#include <stdarg.h>
#define CRASHES(ptr) \
(*(ptr) == 123)
main()
{
char *foo = NULL;
if (CRASHES(foo))
printf("This will never happen.");
}
When compiling and running this with gdb a.out
I get the expected EXC_BAD_ACCESS
(I am on Mac OS X with gdb 6.3), however the crash points to line 8 and not line 4 where the crash is actually caused.
I already tried compiling the program with additional debugging flags -gdwarf-2
and -g3
as suggested by the docs and inserted several assert()
s within the macro itself. Unfortunately that did not provide more information.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
此处提供了有关宏调试的大量有价值的信息。
...另一种方法是使用预处理器,即使用
-E
进行编译,并将扩展的宏复制粘贴到您的 src 代码中,看看是否可以从那里进行调试。lots of valuable information here about macro debugging.
...another approach is to use the preprocessor, i.e. compile it using
-E
and copy-paste the expanded macro into your src-code and see if you can debug from there.当然,这会崩溃,因为您正在引用 NULL 指针...(这不是问题所在,对吗?)。对于这个特定的例子,很简单:gcc -g2,gdb说得
相当清楚,你自己扩展宏并看看为什么(因为 *foo == 123 访问内存你无法读取,因为 foo 是 NULL) 。在更复杂的情况下, gcc -E 有帮助,或者避免使用宏。
Of course this crashes since you are deferencing a NULL pointer...(it was not this the question right?). With this particular example, it is easy: gcc -g2, and gdb says
which is rather clear, you expand by yourself the macro and see why (since *foo == 123 access memory you can't read, since foo is NULL). In more complex cases, gcc -E helps, or avoid using macros.
您没有提及它如何崩溃的。如果它是段错误,请注意它可能会比您实际取消引用错误指针值的时间晚一点发生。
You don't say anything about how it crashes. If it's a segfault, be aware that it might occur a bit later than when you actually dereferenced the bad pointer value.
我有什么办法可以将它转换为实际的函数吗?这是宏的一大弊病。
I there any way you could convert it to an actual function? This is one of the great evils of macros.