【问题标题】:JNI lib crash, with a change in a .c file which is not included in the MakefileJNI lib 崩溃,在 Makefile 中未包含的 .c 文件发生更改
【发布时间】:2023-03-25 02:43:01
【问题描述】:

我们面临一个不寻常的问题,我们的 JNI 库在加载时崩溃。 我们使用 CentOS 5.4/G++ 和 VS2005 进行开发。

场景: 我们目前正在改进我们的产品,并希望使用 JNI 将新信息传递回 Java 服务器代码。 我们的 C/C++ 代码运行良好,我们在开发环境中运行了大约 6 个小时左右对其进行了测试。我们更新了两个结果结构(已经存在),每个结构都有一个长值,以传递我们新增强的结果。

当我们更新 JNI 代码以将结果传递给 Java 代码时,我们发现 Java 服务器在加载 JNI 时崩溃,我们进行了调试,发现 JNI 库崩溃了,即使我们没有对 JNI 进行更改lib 代码库。

在我们进一步的调试中,我们发现 JNI Makefile 包含一个 .c 文件(aa.c),其中包含我们对新增强功能的一些更改;我们开始一一评论我们在这个 aa.c 文件中的更改,发现只有当我们调用 BBB.cpp::method1() 时才会发生崩溃(我们已添加,作为我们新增强功能的一部分)。

不寻常的是,这个 .c 文件(aa.c)在 JNI 库中是不需要的,而且我们没有从 JNI 库中调用 aa.c 的任何方法; 现在我们已经从 JNI Makefile 中删除了 aa.c 并且编译得很好,但是当我们调用 BBB.cpp::method1() 时仍然会崩溃,如果我们删除这个 method1() 调用,那么它就可以正常工作了。

我们不确定它为什么/如何链接到 Makefile 中未包含的文件并崩溃。

这是我们看到的错误日志


AgentServer#0 已启动:好的 12750 [Connection#Cnx:#0.0.1026:0 - Session#c0s1] 错误 com.xx.xxx.xxxx - 无法加载 JNI BBBController 库 java.lang.UnsatisfiedLinkError: /opt/XXXXX/lib/libjnixxx.so: Can't load IA 32-bit .so on a IA 32-bit platform 在 java.lang.ClassLoader$NativeLibrary.load(Native Method) 在 java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1751) 在 java.lang.ClassLoader.loadLibrary(ClassLoader.java:1676) 在 java.lang.Runtime.loadLibrary0(Runtime.java:822) 在 java.lang.System.loadLibrary(System.java:993)


请提出建议,任何想法将不胜感激。

提前致谢,

阿库拉

【问题讨论】:

  • 毫无疑问您已经检查过bugs.sun.com/bugdatabase/view_bug.do?bug_id=6515362。什么 Java 版本?
  • 该错误通常意味着您缺少一个依赖共享库,而不是您有 32/64 位差异。在您的 .so 上运行 ldd 并查看它列出的所有内容是否都在 LD_LIBRARY_PATH 中。
  • @Alan Stokes,我正在使用 jdk 1.5_22
  • @bmargulies 我在现有的 libjni(工作正常)和我创建的 libjni(导致崩溃)上运行 ldd 都依赖于相同的库,但是 LD_LIB_PATH 没有它们。并且它显示的库

标签: java c++ crash java-native-interface loadlibrary


【解决方案1】:

我建议您在启动应用程序时尝试在 ld.so.1 中打开调试功能,看看是否能提供任何线索。见http://linux.die.net/man/8/ld-linux中的LD_DEBUG

【讨论】:

  • 我们已经尝试过这个选项,但对我们没有多大帮助
  • 你有命名冲突吗?您是否检查了您的应用程序的符号表,有/没有导致问题的例程,并检查没有重复项?当您使用 C++ 时,名称修饰开始发挥作用。另外,您是否尝试过使用/不使用例程重新编译 everything ?你在使用模板吗?
【解决方案2】:

终于,我们能够解决这个问题了。

我们看到这个问题是因为我们用来构建 JNI 库的 Makefile 有很多构建不需要的 .o 文件。 其中一个文件恰好是我们正在修改的文件,但其他相关文件未包含在 Makefile 中,这导致加载时崩溃,因为它无法解析引用。

为了找到并解决问题,我们创建了一个简单的 Java 类,它只加载 libjni.so,这给了我们未定义的方法引用,我们搜索并开始修复不需要的方法。 我知道这是一种粗略的方法,需要一些时间才能找到并解决原始问题。 这对我们有用,所以我想我会与其他人分享。

阿库拉

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-13
    • 1970-01-01
    • 1970-01-01
    • 2014-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多