gpt4 book ai didi

c - 如何将 valgrind 与实际上是宏扩展的函数一起使用

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

让我们从一个例子开始,我认为这会立即说明我正在处理的问题。这是一个简单的测试程序,与现实相差甚远,但确实很好地说明了问题

 1    #include <stdio.h>
2 #include <stdlib.h>
3
4 struct first {
5 int i_value;
6 };
7
8 struct second {
9 float f_value;
10 };
11
12 #define DEFINE_FUNCTION(type, struct_name, field_name) \
13 void my_ ## type ## _function(struct struct_name *object, type value) \
14 { \
15 /* Deliberately read an uninitialized value to make valgrind */ \
16 /* report the issue */ \
17 if (object->field_name == -1) \
18 return; \
19 object->field_name = value; \
20 }
21
22 DEFINE_FUNCTION(int, first, i_value);
23 DEFINE_FUNCTION(float, second, f_value);
24
25 void
26 my_test_function(struct first *object, int value)
27 {
28 /* Deliberately read an uninitialized value to make valgrind */
29 /* report the issue */
30 if (object->i_value == -1)
31 return;
32 object->i_value = value;
33 }
34
35 int
36 main(void)
37 {
38 struct first frst;
39 struct second scnd;
40
41 my_test_function(&frst, -5);
42 my_int_function(&frst, -2);
43 my_float_function(&scnd, 3.0);
44
45 return 0;
46 }

如果你编译这段代码并使用

valgrind --show-origins=yes ./compiled-program

你会看到这样的输出

==25304== Memcheck, a memory error detector
==25304== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==25304== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==25304== Command: ./macro-valgrind
==25304==
==25304== Conditional jump or move depends on uninitialised value(s)
==25304== at 0x40056F: my_test_function (macro-valgrind.c:30)
==25304== by 0x400597: main (macro-valgrind.c:41)
==25304== Uninitialised value was created by a stack allocation
==25304== at 0x40057F: main (macro-valgrind.c:37)
==25304==
==25304== Conditional jump or move depends on uninitialised value(s)
==25304== at 0x40053A: my_float_function (macro-valgrind.c:23)
==25304== by 0x4005BC: main (macro-valgrind.c:43)
==25304== Uninitialised value was created by a stack allocation
==25304== at 0x40057F: main (macro-valgrind.c:37)
==25304==
==25304== Conditional jump or move depends on uninitialised value(s)
==25304== at 0x400547: my_float_function (macro-valgrind.c:23)
==25304== by 0x4005BC: main (macro-valgrind.c:43)
==25304== Uninitialised value was created by a stack allocation
==25304== at 0x40057F: main (macro-valgrind.c:37)
==25304==
==25304==
==25304== HEAP SUMMARY:
==25304== in use at exit: 0 bytes in 0 blocks
==25304== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==25304==
==25304== All heap blocks were freed -- no leaks are possible
==25304==
==25304== For counts of detected and suppressed errors, rerun with: -v
==25304== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

正如您在上面的 valgrind 输出中看到的,报告的第一个未初始化读取来自 my_test_function() 函数,它显示了发生问题的确切行。这样修复代码就相当容易了。其他报道显然无法理解。您最多只能知道它是哪个函数,仅此而已。

我知道生成的代码令人困惑 valgrind这就是为什么我的实际问题是,

  • 有没有办法用gcc编译代码?可以帮助 valgrind 理解这类函数吗?

最佳答案

我通过以下方式解决这种由宏引起的调试问题:

1/注释掉标准库/第三方#includes

2/通过 gcc -E -C -P,展开宏

3/放回#includes

4/通过 clang-format,打断很长的行

5/编译带调试信息

程序和以前一样,只是gdb和valgrind引用了扩展源。然后很容易找到错误,然后使用 diff 工具将其追溯到原始来源。

上面的内容听起来很麻烦,但步骤 1 到 4 与步骤 5 一样可编写脚本,因此开发期间的实际开销很小。这不是我的默认设置的原因是跳转到 ide 中的错误会将我带到生成的代码,这通常很烦人。

关于c - 如何将 valgrind 与实际上是宏扩展的函数一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38556570/

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