You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust中重写AddressSanitizer回调函数__asan_on_error?

在Rust中重写AddressSanitizer回调函数的问题与解决方法

问题分析

你遇到的核心问题是:Rust代码中标记了#[no_mangle]和pub extern "C"的__asan_on_error函数未被ASan识别,等价C++代码却能正常触发自定义回调。这是因为Rust的链接顺序与ASan库的初始化逻辑冲突——ASan的默认实现会优先于你的自定义函数被链接,从而覆盖了你的实现。

解决方案

可以在Rust中重写ASan回调,只需调整编译链接规则,确保自定义函数优先被ASan库加载:

1. 修正函数签名

ASan的__asan_on_error标准签名返回类型为void,修正后的Rust代码如下:

use std::hint::black_box;
use libc;

#[no_mangle]
pub extern "C" fn __asan_on_error() {
    std::process::abort();
}

fn main() {
    let ptr = Box::into_raw(Box::new(1));
    unsafe { drop(Box::from_raw(ptr)) };
    black_box(unsafe { *black_box(ptr) } + 1);
}

2. 调整编译链接选项

针对aarch64-apple-darwin目标,需要通过链接参数强制优先加载你的自定义符号。修改运行命令为:

RUSTFLAGS="-Z sanitizer=address -Clink-arg=-Wl,-force_load,$(rustc --print sysroot)/lib/rustlib/aarch64-apple-darwin/lib/librustc_driver-*.dylib" cargo run --profile=dev --target aarch64-apple-darwin

-Wl,-force_load参数会告诉macOS的ld64链接器强制加载指定库中的符号,确保你的__asan_on_error优先于ASan库的默认实现被解析。

3. 验证效果

修改后运行程序,ASan检测到错误时会立即触发abort(),不会输出完整的错误日志,行为与C++版本一致。

原因说明

C++编译时,自定义回调函数在主编译单元中,链接器会优先选择当前单元的符号;而Rust编译流程中,ASan库的链接时机更早,默认实现被优先使用。通过强制加载自定义符号,就能覆盖ASan的默认回调。

你调用__asan_describe_address等函数正常工作,是因为这些是主动调用ASan库的API,不存在符号覆盖的链接顺序问题。

内容的提问来源于stack exchange,提问作者Jeonghyeon Kim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 23:40:58