【问题标题】:How to debug JNI heap corruption problems?如何调试 JNI 堆损坏问题?
【发布时间】:2011-03-14 21:57:46
【问题描述】:

我有一个 Java 应用程序,它通过 JNI 调用旧应用程序的许多不同的本地方法。但是 JVM 在任何 JNI 调用之外的随机位置发生堆栈转储而崩溃。有时它在 GC 期间崩溃,有时在类加载和其他地方。我怀疑一个或多个本机方法正在破坏 JVM 堆或其他一些数据结构。我需要知道这是哪个调用,以便修复本机实现。

旧版应用程序是第 3 方 DLL,我没有它的源代码和符号信息。为了使它可以从 Java 中调用,我构建了一个使用 JNI 调用约定的包装 DLL。

完美的解决方案是扩展 JVM 选项,强制 JVM 在每次 JNI 调用后自动检查堆及其其他数据结构的完整性。

你知道什么可以提供帮助吗?

附:请不要告诉我在 JVM 和遗留应用程序之间构建套接字或管道层,因为我们的要求不允许这样做。这是关于错误检测,而不是架构设计。

【问题讨论】:

  • 我假设你知道-Xcheck:jni
  • 我有同样的问题,如果这有帮助的话:/ 我有很多数据通过 JNI 传输,有时我会收到损坏的地址和数据包数据。它把整个模拟搞砸了,真的很烦人。

标签: java java-native-interface


【解决方案1】:

因为我没有答案并且自己找不到现成的解决方案,所以我最终用纯 C++ 构建了一个沙盒进程,只是为了找出问题所在。我的 Java 应用程序使用 ProcessBuilder 实例化沙箱进程,然后使用标准输入和标准输出与其通信。实际加载和调用旧版 DLL 的是沙箱,而不是 JVM。然后我使用 Microsoft 的应用程序验证程序监控沙盒进程,发现内存损坏问题 - 有一个调用传递的缓冲区小于预期。确定后,我只是增加了Java应用程序中用作缓冲区的字节[]的长度,现在JVM可以直接调用DLL而无需使用沙箱。

总的来说,我损失了将近 10 天,因为 JVM 没有在每次 JNI 调用后验证堆的选项。但至少现在如果有人发现崩溃,我们可以使用沙盒快速调试它。

【讨论】:

    猜你喜欢
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 2012-04-06
    • 2021-03-05
    • 2015-07-03
    相关资源
    最近更新 更多