• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2025-03-14 15:19 Aet 隐藏边栏 |   抢沙发  1 
文章评分 1 次,平均分 5.0

概述

  1. AddressSanitizerASan)最初由 Google 开发并开源,是 LLVM/Clang 编译器工具链的一部分
  2. 它的核心目标是检测内存错误(如缓冲区溢出、释放后使用等),并通过 影子内存(Shadow Memory) 和 运行时插桩(Instrumentation) 实现高效检测
  3. Windows相关
    1. 微软从 Visual Studio 2019 (v16.9) 开始,将 ASan 功能移植到 MSVC 编译器 中
    2. 目前检测不了内存泄露

Windows平台支持

关于Visual Studio

  1. Visual Studio 2019 v16.9+:原生集成ASan,无需额外安装
  2. 旧版本VS(如2017):需手动安装ASan插件

Clang for windows

  1. 需使用Clang-cl工具链,支持ASan但配置复杂

局限

  1. 不支持动态库(DLL)的ASan插桩
  2. 某些API(如_aligned_malloc)可能无法被完全跟踪

启用ASan检测内存泄漏(Visual Studio

步骤1:启用ASan

  1. 打开项目属性 → C/C++GeneralEnable Address SanitizerYes
  2. 确保生成配置为 DebugASan依赖调试符号)

步骤2:配置泄漏检测

  1. 设置环境变量 ASAN_OPTIONS(可选):
    1. detect_leaks=1:强制启用泄漏检测(默认已开启)
    2. malloc_context_size=20:记录泄漏时的堆栈深度

步骤3:编译并运行程序

  1. 直接运行程序(F5),ASan会在程序退出时输出泄漏报告

VS具体情况

  1. 按上述步骤,Visual studio 集成的ASan可以检测到内存的越界访问
  2. 按上述步骤,Visual studio 集成的ASan检测不到内存的泄露
    1. 可能功能在开发中,可以确定,2024年底的时候,这功能还没有添加

Unix、里面使用ASan

Debian

  1. 验证环境是debian12系统

环境准备

  1. 安装支持asan的编译器

  1. 查看版本

  1. 安装调试符号和依赖库

编译启用ASan

  1. bash

  1. makefile

运行时配置

  1. ASan 默认不启用内存泄漏检测,需通过环境变量显式开启

  1. 我自己仅仅用了

  1. 动态库路径(Debian 特定问题)
    1. 若遇到动态库加载错误,手动指定 ASan 运行时库路径:
    2. 不过我没有遇到这个问题,所以没有执行下面这一句

测试代码

效果

gcc具体情况

  1. 可以检测到内存越界的情况
  2. 可以检测到内存泄露

macOS里面使用ASan

XCode

  1. xcode里面继承了ASan
  2. 启用步骤如下:
    1. Product
    2. `Scheme - Edit Scheme
    3. Run - Diagnostics
    4. Address Sanitizer

XCode具体情况

  1. xcode里面可以检测到内存的越界访问
  2. xcode里面,可以用Product-Analyze提示相关内存泄露信息

clang

  1. 使用bash

clang具体情况

  1. 我这边是armmacOS
  2. 目前显示:detect_leaks is not supported on this platform

解读内存泄漏报告

示例

泄露类型

  1. Direct leak:直接未释放的内存
  2. Indirect leak:因其他泄漏导致无法释放(如指针丢失)

高级配置

排除误报

  1. 忽略特定泄漏:在代码中添加:

  1. 过滤全局变量:确保全局变量使用volatileconst,避免被误判

输出到文件

  1. 设置 ASAN_OPTIONS

  1. 报告将保存到 asan.log.12345PID后缀)

实时检测(非退出时)

  1. 手动触发泄漏检查:

内存泄露检测原理

概述

  1. ASanWindows上通过 LeakSanitizerLSan) 检测内存泄漏,其核心机制如下:

1 内存分配追踪

  1. 拦截分配函数:
    1. 替换malloccallocreallocfree,记录每个分配的内存块及其调用栈
  2. 维护分配表:
    1. 全局哈希表保存所有未释放的内存块信息(地址、大小、分配堆栈)

2 泄露判定

  1. 程序退出时检查:
    1. 在程序正常退出或崩溃时,遍历分配表,标记所有未被释放的内存块为泄漏
  2. 忽略全局变量:
    1. 通过扫描全局区段,排除全局变量持有的内存(需调试符号)

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享