如何将 gcc 与 fsanitize=address 一起使用?

问题描述 投票:0回答:1

我正在尝试学习如何使用

-fsanitize=address -fno-omit-frame-pointer
来检测内存泄漏。我写了一些简单的东西,显然有内存泄漏,但是用
gcc -fsanitize=address -fno-omit-frame-pointer file.c
编译然后执行该函数似乎没有问题。

这篇文章似乎表明我们需要设置编译器标志和链接器标志,而不是使用

-lasan
如何在gcc中使用AddressSanitizer?

我认为没有必要,但我已经尝试过

gcc -fsanitize=address -static-libasan -fno-omit-frame-pointer s.c
,因为文档似乎在这里提到了。 https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

我也尝试了以下操作:https://lemire.me/blog/2016/04/20/no-more-leaks-with-sanitize-flags-in-gcc-and-clang/

以防万一,我使用的是 MacOS。我已经通过brew更新和升级了gcc。版本信息是:

Apple LLVM version 10.0.1 (clang-1001.0.46.4)

这是我写的虚拟代码:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
    char *buffer = malloc(1024);
    sprintf(buffer, "%d", argc);
    printf("%s\n", buffer);
    buffer = malloc(10);
    buffer[0] = 'A';
    buffer[9] = '\0';
    printf("%s\n", buffer);
}

我从未释放过任何东西,所以我希望地址清理程序能够捕获它。但是当我运行代码时,我得到以下结果:

$ ./s
1
A????????

我误解/做错了什么?

c gcc memory-leaks
1个回答
0
投票

在带有 Apple Clang 的 macOS 上,

-fsanitize=address
默认情况下不一定能捕获内存泄漏。
AddressSanitizer
主要检测越界和释放后使用错误。 Apple 较旧的 Clang 工具链通常不完全支持内存泄漏检测组件(
LeakSanitizer
LSan
)。

在许多基于 Linux/LLVM 安装中,

-fsanitize=address
还包括泄漏检测 if 您可以使用
ASAN_OPTIONS=detect_leaks=1
或使用
-fsanitize=leak
启用它。在装有 Apple Clang 的 macOS 上(尤其是 10.x、11.x 等旧版本),
LeakSanitizer
通常被禁用或不完整。

但是,有一些解决方法。您可以从 Homebrew 安装 LLVM/Clang(不仅仅是 Apple 的 Xcode Clang)。

brew install llvm
/usr/local/opt/llvm/bin/clang -- version

然后尝试使用那个 clang 编译而不是 Apple 的编译。该版本具有更完整的 LSan/ASan 集成。

如果您的 Clang 环境支持,您可以设置环境变量来启用泄漏检测:

ASAN_OPTIONS=detect_leaks=1 ./s
© www.soinside.com 2019 - 2024. All rights reserved.