Calling JNI_CreateJavaVM Crashes the Program

I have a C DLL that uses JNI to proxy any calls to the java base program that does the actual weightlifting. I dynamically load jrockit jvm.dll to call a function call.

Vendor A has a C # DLL that actually calls my C DLL, and another B provider has a C # program that calls the C # provider DLL.

There was no problem testing with the C # DLL provider, but after integrating with the B C # provider program, my call to initialize the JVM via JNI_CreateJavaVM crashes the entire program.

Any help would be appreciated.

The error message I received was:

[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) 

EDIT 1: ok I parsed jvm.dll and it calls TlsAlloc followed by TLSSet and to get the code that shows the error message, cmp esi, edx before SHORT 04755D4B in the second image is not equal.

The contents of call 04755DD0 in the first image is in the second image.

Does anyone know what the calculation is up to this (the one that controls esi and edx)?

Disassembly 1Disassembly 2

EDIT 2: (In response to PT) I did not install any specific streaming system, so I believe that it uses a standard stream system, which is native, like here: http://docs.oracle.com/cd/ E13222_01 / wls / docs81b / jrockit / threads.html

Your guess is most likely correct, looking at the disassembly, I found that the code logic looks something like this: first it calls TlsAlloc, and then TlsSetValue, to set the local storage of streams at the index returned by TlsAlloc to a constant magic number 4711, after which it loops with eip from the beginning of the stream information block, looking for the value 4711, after it is detected, the code calls TlsSetValue again to set the value to 1147, after which it checks if the eip is actually pointing to the local storage of the streams, ensuring that for [eip] is set to 1147.

Provider B uses C # for its programs, therefore, they will use the CLR virtual machine. As soon as he reaches the point where provider B calls my DLL, they already initialized the WPF prism and mef framework, loaded all the interface modules into the appropriate positions, initialized all Singleton models (Export in WPF prism) and initialized the MS workflow. However, when I change the initialization code to the first few lines, jvm succeeded in initializing it (this is the wrong place to initialize jvm, and we did not test if the rest of the code works).

The code only fails when TlsSetValue fails, is there a reason for TlsSetValue to fail? and what should I look for in vendor B code that might cause the problem?

+4
source share
1 answer

I ran into the same error, and I managed to figure out what was going on, at least in my case. This seems like a bug in JRockit, and your question really helped in exploring it.

The search performed for the “magic number” placed in the slot extends over two pages of data, starting from the beginning of the TEB. However, there are only 64 storage slots located in the TEB itself. See http://msdn.microsoft.com/en-gb/library/windows/desktop/ms686708(v=vs.85).aspx .

If the allocated storage slot is index 64 or higher, instead of putting data in the embedded array, Windows places it in the block pointed to by the TlsExpansionSlots pointer. Since this is outside the TEB, the magic number lookup fails, and JRockit generates this error.

My instance of this also occurred in a .NET program. My assumption is that the CLR makes significant use of TLS, which makes it more likely to accommodate a large slot number.

In my case, JRockit actually crashed while trying to write a log line, perhaps because it is so early that the log has not yet been created. Not sure which version of JRockit you are using. My:

 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) 

I do not know if this has been fixed in future versions. If this is not us (i.e. My employer), you may have to raise it using Oracle.

+3
source

All Articles