如何禁用AddressSanitizer内存访问时的检查函数插入功能
禁用AddressSanitizer内存访问检查函数的方法
一、通过命令行标志禁用
编译时直接关闭内存访问 instrumentation:
使用LLVM后端参数-mllvm -asan-instrument-memory=false,这会彻底跳过ASAN对所有加载/存储指令的检查函数插入。运行时禁用特定检测(编译时仍插入检查):
若仅需在运行时关闭某类检测(如栈缓冲区溢出),可设置环境变量:ASAN_OPTIONS=detect_stack_buffer_overflow=0 ./your_program注意:此方法只是运行时不触发报错,编译阶段仍会插入检查函数。
二、修改LLVM源码(AddressSanitizer.cpp)实现禁用
1. 彻底跳过内存访问检查插入
找到AddressSanitizer.cpp中处理加载/存储指令的visitLoad和visitStore函数(LLVM最新版本中位于约2000-2200行),注释原有逻辑并直接返回:
void AddressSanitizer::visitLoad(Instruction &I) { // 注释所有原有插入检查的代码 return; } void AddressSanitizer::visitStore(Instruction &I) { // 注释所有原有插入检查的代码 return; }
2. 修改默认开关
文件开头定义了控制内存访问 instrumentation 的标志AsanInstrumentMemory,将其默认值改为false:
static cl::opt<bool> AsanInstrumentMemory( "asan-instrument-memory", cl::init(false), // 原默认值为true cl::desc("Instrument memory accesses"));
这样编译后的ASAN pass默认不会插入内存访问检查,也可通过命令行-mllvm -asan-instrument-memory=true临时启用。
3. 选择性禁用特定场景检查
若只想跳过某类内存的检查(如栈内存),可在visitLoad/visitStore中添加判断逻辑:
void AddressSanitizer::visitLoad(Instruction &I) { Value *Ptr = I.getOperand(0); if (isStackAddress(Ptr)) { return; // 跳过栈内存加载操作的检查 } // 保留原有堆内存等其他场景的检查逻辑 // ... 原有代码 ... }
内容的提问来源于stack exchange,提问作者MJUCOM
相关产品推荐
相关产品推荐

