java与ntdll.dll的关系
Posted
技术标签:
【中文标题】java与ntdll.dll的关系【英文标题】:relationsship between java and ntdll.dll 【发布时间】:2018-11-23 09:29:05 【问题描述】:我有一个 java 应用程序 (tomcat-app) 在后台使用 JNI 连接到 C 库。这个 java 应用程序以一种非常随机的方式崩溃。我在系统事件中看到,是基于ntdll.dll崩溃的,它是Windows/System32中的系统库。
谁能告诉我,ntdll.dll 提供了哪些功能,它的用途是什么以及为什么 java 需要这个 ntdll.dll?
我使用 Google 来寻找解决方案,但是这种崩溃几乎可能发生在所有 Windows 系统上,我结合了很多应用程序(似乎它不仅仅是一个 windows-java 问题)。标准解决方案是重新安装/更新系统和/或应用程序。但是有没有解释,为什么这个 ntdll.dll 会造成这么大的麻烦?
如果我将更高版本的 ntdll.dll 放入 java 目录或 c-library 的目录中,您是否认为这会有所帮助,以便 java 或 c-lib 可以采用这个较新的版本,而不是Windows/System32 版本?
非常感谢您的建议。
【问题讨论】:
ntdll.dll
在所有进程中加载,无一例外。和你的崩溃绝对无关ntdll.dll
鉴于 ntdll.dll
已成功用于数百万次安装,并且您的(可能是本地开发的)JNI 应用程序使用的安装次数减少了多个数量级,出现随机故障的几率有多大ntdll.dll
而不是您自己的应用程序?鉴于ntdll.dll
做了诸如内存管理之类的事情,它很可能在地雷上失败,您的代码通过堆或堆栈损坏等方式引入进程内存空间。
【参考方案1】:
ntdll 是一个底层的windows系统api,它提供了数百个windows api函数,如内存管理、加载DLL和系统异常。
您不得使用与您系统上的版本不同的版本,因为它是您运行的 Windows 操作系统版本的紧密耦合/不可或缺的一部分。
如果没有进一步的信息,很难判断问题可能是什么,但也许您在 JNI 包装器中使用了不正确的调用约定,这会导致堆栈不平衡。
【讨论】:
更有可能只是简单的堆损坏。 您不能使用与环境中的版本不同的版本,因为系统调用索引会发生变化(对于 Nt*/Zw* 导出 - 顺便说一下,它们是相同的存根)。偶尔会更改 Ldr*、Rtl* 等。【参考方案2】:看来,JNI 调用是正确的(我们使用了一个外部库,它使用了 JNI)。此外,我们还找到了解决此问题的方法。 Windows 的功能更新提高了 ntdll.dll 的版本。这解决了问题; java.exe的崩溃再也没有出现过。
【讨论】:
以上是关于java与ntdll.dll的关系的主要内容,如果未能解决你的问题,请参考以下文章
将用户模式 dll 中的高级函数映射到 NTDLL.dll