My boss wants me to see if I can write a "one button memory leak checker" in our Java client for our testers (since I then would have to spend less time myself running our full manual test suite under a profiler; we don't have an automated test-suite).
I have found something that is pretty close to what I need: Heap Walker I had to modify it slightly to compile in VS in Windows (I think it was made for GCC under Mac). But when I run it, the JVM crashes.
I'd like to get a native stack-trace to see at least where it crashes, and if I can find out what happens, but idk how. I have built a "debug" DLL, but I still get no stack-trace. Neither on the console, nor in the "hs_err_pidXXXX.log" file generated by the JVM.
I haven't done any C/C++ in about 15 years; I can still about "guess" what the code does, but I forgotten how the debugging goes (beyond "printf everywhere" ...), and I never had to debug native code in the JVM. So far, Google was no help; I'm probably using the wrong terms to search.
JVM usually reports native stack trace in the crash dump. If there is no stack trace in hs_err_pid.log
, it means JVM could not obtain the last frame from PC register, typically because it pointed to unreadable address.
For example, this can happen if a native code dereferences null function pointer:
void (*func)() = 0;
func();
In this case PC will be zero, and JVM won't print the trace. But you can still find caller PC from the stack, because the return address is typically pushed onto the stack before a call. Here is how to find it in hs_err_pid.log
:
Top of Stack: (sp=0x0000000002e2f438)
0x0000000002e2f438: 00007ffcf03f1030 00007ffcf041d000
^^^^^^^^^^^^^^^^
the return address (the address after the last valid instruction)
Then you can find this address in Dynamic libraries
section and calculate the offset from the beginning of dll.
Dynamic libraries:
...
0x00007ffcf03f0000 - 0x00007ffcf0426000 C:\Java\Test\crash.dll
^^^^^^^^^^^^^^^^^^
offset = 0x00007ffcf03f1030 - 0x00007ffcf03f0000 = 0x1030
Use disassembler (e.g. Visual Studio's dumpbin) to decode the offest into the particular function / instruction in the code.
You can also attach Visual Studio debugger to the JVM when it crashes. In order to do so, you should run Java with -XX:+ShowMessageBoxOnError
. The following window will invite you to connect the debugger: