我使用 JNI 的 java 应用程序因 hs_err_pid 文件而崩溃,错误为“异常访问冲突”。操作系统是 Windows VISTA。
据我所知,我的本机代码正在非法写入一些不属于它的内存块。
过去,我在纯本机代码的 Linux 上使用 valgrind 来检测此类问题。
但是在使用 java 时,valgrind 根本就失败了并且不起作用。
你会建议什么(如果有的话)方法来识别有问题的代码片段?
我无法手动挖掘本机代码(几百万行)来识别它。
我使用 JNI 的 java 应用程序因 hs_err_pid 文件而崩溃,错误为“异常访问冲突”。操作系统是 Windows VISTA。
据我所知,我的本机代码正在非法写入一些不属于它的内存块。
过去,我在纯本机代码的 Linux 上使用 valgrind 来检测此类问题。
但是在使用 java 时,valgrind 根本就失败了并且不起作用。
你会建议什么(如果有的话)方法来识别有问题的代码片段?
我无法手动挖掘本机代码(几百万行)来识别它。
我终于能够解决这个问题。我想我会在这里发布程序,以防其他人处于类似情况。
第 1 步:使用适当的调试符号构建本机代码。编译器标志可能类似于
"-g -rdynamic -O0"
.
第 2 步:下面的 valgrind 命令应该可以完成这项工作。
valgrind --error-limit=no --trace-children=yes --smc-check=all --leak-check=full --track-origins=yes -v $JAVA -XX:UseSSE=0 -Djava.compiler=NONE $JAVA_ARGS
在上面的命令中,$JAVA 是 java 可执行文件,$JAVA_ARGS 是你的 java 程序的参数。
一旦成功启动,将需要更多数量级的时间来完成执行。Valgrind 将打印数千个错误(大多数与 jvm 相关,可以忽略)。但是,您可以识别与您的 jni 代码相关的那些。
这种通用策略应该适用于大多数与本机内存相关的问题。
如果您在 Linux 下运行 Java,则可以使用该-XX:OnError="gdb - %p"
选项gdb
在错误发生时运行。请参阅此示例。
在 windows 下,您可以使用该-XX:+UseOSErrorReporting
选项来获得类似的效果。
对于调试 JNI 代码,本文中发布的一种方法可能很有用(它是关于使用 Netbeans 和 Visual Studio 调试 JNI)。这很简单 - 只需启动您的 Java 程序,然后在 Visual Studio 中选择Debug
->Attach to process
并选择运行您的程序的 java.exe 进程。
当您向 C++ 代码添加断点时,Visual Studio 将在它们上中断。瞧:)