You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何控制ASAN不捕获C++函数__cxa_throw以解决程序卡死问题

如何控制ASAN不捕获C++函数__cxa_throw以解决程序卡死问题

看起来你在使用GCC 9.5.0版本的ASAN时,遇到了程序处理C++异常抛出时卡死的麻烦。结合你提供的backtrace,问题出在FastDDS抛出std::system_error时,ASAN进入__asan_handle_no_return后卡在了libc里。我来帮你梳理下可行的解决思路:

为什么intercept_cxx_exceptions=false对你无效

你提到尝试设置ASAN_OPTIONS=intercept_cxx_exceptions=false但没效果,而且在ASAN源码里找不到这个选项——这是因为这个选项是Clang/LLVM的ASAN特有的,GCC 9.5.0版本的ASAN还没有支持这个配置项,所以你的设置不会生效,源码里找不到相关关键字也完全正常。

针对GCC 9.5.0 ASAN的替代解决方案

1. 优先升级ASAN版本

你的问题大概率是旧版本ASAN的已知bug:GCC 9.x的ASAN在处理__cxa_throw时,可能会在__asan_handle_no_return中出现死锁或卡死情况。升级到GCC 11及以上版本(或切换到Clang 12+的ASAN),这些新版本修复了很多异常处理相关的问题,能大概率解决卡死问题。

2. 调整ASAN运行时选项规避卡死

如果暂时无法升级,可以尝试设置以下ASAN选项,可能绕过卡死场景:

  • 启用快速unwind,减少ASAN在异常处理时的栈回溯开销:
    export ASAN_OPTIONS=fast_unwind_on_malloc=1
    
  • 调整ASAN对no-return函数的处理,尝试关闭严格检查:
    export ASAN_OPTIONS=handle_no_return=0
    
    (注:这个选项在GCC 9中是否可用需要验证,如果无效可以跳过)

3. 隔离第三方库的ASAN拦截

你的异常是由FastDDS库抛出的,如果你无法升级ASAN,可以尝试不对FastDDS库启用ASAN检测

  • 重新编译FastDDS时,添加编译选项-no-sanitize=address,这样它抛出异常时不会触发ASAN的__cxa_throw拦截
  • 如果无法重新编译FastDDS,也可以在运行时用LD_PRELOAD只对自己的代码加载ASAN,不过这种方式需要谨慎操作,可能导致检测不完整

4. 排查异常根源

从backtrace看,FastDDS是因为网络相关错误抛出std::system_error,你可以先排查这个异常的原因(比如端口占用、网络配置问题),如果能避免异常抛出,自然就不会触发ASAN的卡死场景。

总结

最彻底的解决方案是升级ASAN到新版本;如果暂时做不到,调整ASAN运行时选项或隔离第三方库的ASAN检测是可行的临时方案。

备注:内容来源于stack exchange,提问作者GreatPi

火山引擎 最新活动