6

我有一个 C DLL,它使用 JNI 代理对执行实际举重的底层 java 程序的任何调用。我正在动态加载 jrockit jvm.dll 以进行函数调用。

供应商 A 有一个 C# DLL,它实际上调用了我的 C DLL,而另一个供应商 B 有一个 C# 程序,它调用了供应商 A 的 C# DLL。

使用供应商 A 的 C# DLL 进行测试时没有任何问题,但在与供应商 B 的 C# 程序集成后,我通过 JNI_CreateJavaVM 初始化 JVM 的调用会导致整个程序崩溃。

任何帮助,将不胜感激。

我收到的错误消息是:

[ERROR] Could not find allocated thread local data key in TIB
[ERROR] Could not create fast TLD
JRockit aborted: Unspecified Error(52)
Assertion failed: Could not create fast tld 
In vmDebug Before Abort() (src/jvm/runtime/debug/debug.c:103)

编辑 1:好的,我已经反汇编了 jvm.dll,它调用 TlsAlloc,然后调用 TLSSet 并到达显示错误消息的代码,第二个图像中 je SHORT 04755D4B 之前的 cmp esi、edx 不能相等。

第一个图像中调用 04755DD0 的内容在第二个图像中。

有谁知道之前的计算(操作 esi 和 edx 的 1)是做什么的?

拆卸 1 拆卸 2

编辑 2:(响应 PT)我没有设置任何特定的线程系统,所以我想它使用的是默认的线程系统,根据这里:http ://docs.oracle.com/cd/E13222_01/ wls/docs81b/jrockit/threads.html

你的猜测很可能是正确的,在查看反汇编时,我发现代码逻辑是这样的,它首先调用 TlsAlloc 然后调用 TlsSetValue 将 TlsAlloc 返回的索引处的线程本地存储设置为常量幻数4711 之后它使用 eip 从线程信息块的开头循环查找值 4711,一旦找到它,代码然后再次调用 TlsSetValue 将值设置为 1147,此时它检查 eip 是否实际指向通过确保将 [eip] 设置为 1147 来获取线程本地存储。

供应商 B 在他们的程序中使用 C#,因此,他们将使用 CLR 虚拟机。一旦它到达供应商 B 调用我的 DLL 的点,他们将已经初始化 WPF prism 和 mef 框架,将所有接口模块加载到各自的位置,初始化所有单例(WPF prism 术语中的导出)模型并初始化 MS 工作流。但是,当我将初始化代码移至前几行时,jvm 初始化成功(这不是初始化 jvm 的正确位置,我们尚未测试其余代码是否有效)。

代码仅在 TlsSetValue 失败时分支到错误,是否有任何原因导致 TlsSetValue 失败?我应该在供应商 B 的代码中寻找可能导致问题的哪些内容?

4

1 回答 1

3

我遇到了同样的错误,我设法弄清楚发生了什么,至少在我的情况下。它看起来像 JRockit 中的一个错误,您的问题对调查它非常有帮助。

对放置在槽中的“幻数”执行的搜索从 TEB 的开头开始延伸到两页数据。但是,TEB 本身只有 64 个存储槽。请参阅http://msdn.microsoft.com/en-gb/library/windows/desktop/ms686708(v=vs.85).aspx

如果分配的存储槽的索引为 64 或更高,Windows 不会将数据放入嵌入式数组中,而是将其放入 TlsExpansionSlots 指针指向的块中。由于这在 TEB 之外,因此对幻数的搜索会失败,并且 JRockit 会产生此错误。

我的这种情况也发生在 .NET 程序中。我的猜测是 CLR 大量使用 TLS,从而更有可能分配高插槽号。

就我而言,JRockit 在尝试写入日志行时实际上崩溃了,可能是因为它发生得太早以至于尚未创建日志。不确定您使用的是哪个版本的 JRockit。我的是:

C:\>java -version
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
BEA JRockit(R) (build R27.6.5-32_o-121899-1.6.0_14-20091001-2107-windows-ia32, compiled mode)

我不知道这是否在以后的修订中得到解决。如果不是,我们(即我的雇主)可能不得不向甲骨文提出。

于 2013-01-14T18:52:45.640 回答