首页 > 解决方案 > AddressSanitizer:运行包含调用 JNI_CreateJavaVM 的 C++ 代码时的 SEGV

问题描述

我们的产品是用 C++ 编写的,根据程序流程,调用 Java 本地接口 (JNI) 以加载和运行 Java 类,主要是为了进行 JBDC 调用以访问数据库表。当这个进程在 Linux 上运行时,具有特定的客户配置,大约 20% 的时间它会因分段错误而失败,从而生成核心转储。核心转储中的回溯表明程序在 JVM (libjvm.so) 中的某个地方出现故障。我尝试使用 -Xcheck:jni 运行,但它提供的信息似乎无法帮助隔离此问题。我已经尝试了 Java 7 和 8 的几个版本/构建。

为了尝试获取有关该崩溃的更多信息,我使用附加选项 -fsanitize=address -fstack-protector -fno-omit-frame-pointer 使用 gcc 4.8.5 重新编译了代码。当我编译并使用 -fsanitize=address 选项,然后运行程序时,它很快崩溃并出现以下错误:

ASAN:SIGSEGV
=================================================================
==15864== ERROR: AddressSanitizer: SEGV on unknown address 0x00000000 (pc 0xe2a00202 sp 0xfff4a8cc bp 0xf35e2b40 T0)
AddressSanitizer can not provide additional info.
    #0 0xe2a00201 (+0x201)
==15864== ABORTING

当从 C++ 代码调用 JNI_CreateJavaVM() 函数以设置调用 Java 时,似乎正在发生这种崩溃。我从图片中取出我们的代码,并尝试重新编译并运行此处提供的示例调用 API 代码。当我编译此代码并使用 -fsanitize=address 选项然后运行它时,它会因与上述相同的错误而崩溃。我使用的编译命令和选项粘贴在下面:

/usr/bin/g++ -m32 -fsanitize=address -I/scratch/jwcarter/jdk1.8.0_291_x86/include -I/scratch/jwcarter/jdk1.8.0_291_x86/include/linux -L/scratch/jwcarter/jdk1.8.0_291_x86/jre/lib/i386/client /scratch/jwcarter/rel125as/rps100/jnitest/c/jnitest.cpp -o jnitest -ljvm

为了使用 -fsanitize=address 编译选项来构建包含对 JNI_CreateJavaVM() 的调用的代码,是否需要指定其他编译或链接标志?谢谢。

标签: javac++gcc

解决方案


推荐阅读