gpt4 book ai didi

c - 是否有一个编译器选项可用于将堆栈变量初始化为非零值(毒药)以帮助调试?

转载 作者:行者123 更新时间:2023-12-02 02:49:48 25 4
gpt4 key购买 nike

C 程序中的一种常见错误是程序使用一些未初始化的数据,通常假设某些数据为零,而实际上它从未初始化为零。这样的程序似乎可以工作,因为这些内存位置恰好为零,但有一天那里出现了一些垃圾,并且您的程序崩溃了。

我知道 valgrind 是发现此类问题的一个很好的工具。但有时 valgrind 无法使用,例如程序以非标准方式分配内存。

我的问题:gcc(或 clang)是否有一些编译器选项可用于要求编译器将局部变量初始化为一些非零“毒药”值,以暴露此类错误?

我认为编译器在技术上应该可以做到这一点,在每个函数调用时插入一些指令,将该数据放入通常未初始化的堆栈变量的内存空间中。会有一些性能成本,但与使用 valgrind 相比便宜,而且在某些情况下 valgrind 可能无法使用。

编辑:让我澄清一下,这个问题与编译器警告无关。当然,编译器警告非常有帮助,应该打开并处理它们,但这并不能解决未初始化数据的所有问题。例如,程序可能会获取局部变量的地址并将其传递给函数,然后编译器将不知道传递该地址是否允许函数将数据复制到那里(这很好),或者函数是否会这样做使用指向的数据(这意味着使用未初始化的数据)。

最佳答案

是的——clang有-fsanitize=memory option .

以下是文档的简短摘录:

If a bug is detected, the program will print an error message to stderr and exit with a non-zero exit code.

% ./a.out WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x7f45944b418a in main umr.cc:6
#1 0x7f45938b676c in __libc_start_main libc-start.c:226

您还可以使用-fsanitize-memory-track-origins来获取有关该问题的更多信息。

% clang -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O2 umr2.cc
% ./a.out
WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x7f7893912f0b in main umr2.cc:7
#1 0x7f789249b76c in __libc_start_main libc-start.c:226

Uninitialized value was stored to memory at
#0 0x7f78938b5c25 in __msan_chain_origin msan.cc:484
#1 0x7f7893912ecd in main umr2.cc:6

Uninitialized value was created by a heap allocation
#0 0x7f7893901cbd in operator new[](unsigned long) msan_new_delete.cc:44
#1 0x7f7893912e06 in main umr2.cc:4

有关使用、运行时成本和其他提示的详细信息,请参阅完整文档(上面链接)。

关于c - 是否有一个编译器选项可用于将堆栈变量初始化为非零值(毒药)以帮助调试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62184260/

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