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

在Surefire中使用AddressSanitizer遇SEGV错误的解决办法问询

解决AddressSanitizer与JVM信号冲突导致的SEGV崩溃问题

你遇到的这个SEGV崩溃确实是AddressSanitizer(ASAN)和JVM自身信号机制冲突导致的——JVM会主动触发并处理SEGV信号来实现一些核心功能(比如线程栈遍历、即时编译的边界检查),但ASAN默认会拦截所有SEGV信号并将其判定为致命错误,这就导致了误报崩溃。

直接忽略所有SEGV信号显然不可行,那样会漏掉JNI代码中真正的内存错误。正确的做法是让ASAN允许JVM的信号处理器正常工作,同时保留对JNI代码的检测能力,具体可以通过以下步骤调整:

1. 调整ASAN的环境变量配置

修改你的maven-surefire-plugin配置,添加ASAN_OPTIONS环境变量,关键设置两个参数:

  • allow_user_segv_handler=1:允许用户自定义的SEGV信号处理器(这里就是JVM的)优先运行,而不是被ASAN直接拦截
  • detect_leaks=0:关闭ASAN的内存泄漏检测(可选但推荐,因为JVM自身的内存管理会产生大量误报,也可能引发额外的兼容性问题)

修改后的配置如下:

<configuration>
  <forkMode>always</forkMode>
  <environmentVariables>
    <LD_PRELOAD>/usr/lib/x86_64-linux-gnu/libasan.so.4.0.0</LD_PRELOAD>
    <ASAN_OPTIONS>allow_user_segv_handler=1:detect_leaks=0</ASAN_OPTIONS>
  </environmentVariables>
</configuration>

2. 确保ASAN版本与编译环境匹配

要注意libasan.so.4.0.0对应的是GCC 7.x版本,如果你的JNI库是用更高版本的GCC编译的,需要替换成对应版本的libasan(比如GCC 8对应libasan.so.5,GCC 9+对应libasan.so.6等)。路径错误或版本不匹配也可能导致奇怪的崩溃。

3. 额外的调试选项(如果仍有问题)

如果上述配置还是有问题,可以尝试添加handle_segv=0到ASAN_OPTIONS中,这个参数会让ASAN完全不处理SEGV信号,完全交给JVM处理。但要注意,这会导致ASAN无法检测JNI代码中真正的SEGV错误,所以仅作为最后的调试手段。

原理说明

JVM的信号处理是其正常运行的一部分,ASAN默认的信号拦截逻辑会打断这个流程。通过allow_user_segv_handler=1,ASAN会在检测到SEGV时先调用JVM的信号处理器,只有当JVM不处理这个信号时,ASAN才会将其判定为错误——这样既保留了对JNI代码的内存错误检测,又不会干扰JVM的正常运行。

内容的提问来源于stack exchange,提问作者St.Antario

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:15:30