2016-08-04 23 views
0

Mein Chef möchte, dass ich in unserem Java-Client für unsere Tester einen "One-Button-Memory-Leak-Checker" schreibe (da ich dann weniger Zeit damit verbringen müsste, unsere komplette manuelle Testsuite unter einem Profiler laufen zu lassen; habe keine automatisierte Testsuite.Wie erhalten * native * Stack-Trace bei Fehler für Java native Agent?

Ich habe etwas gefunden, das ziemlich nah an dem ist, was ich brauche: Heap Walker Ich musste es leicht ändern, um in VS in Windows zu kompilieren (ich denke, es wurde für GCC unter Mac gemacht). Aber wenn ich es starte, stürzt die JVM ab.

Ich möchte eine native Stack-Trace bekommen, um zumindest zu sehen, wo es abstürzt, und wenn ich herausfinden kann, was passiert, aber idk wie. Ich habe eine "Debug" DLL erstellt, aber ich bekomme immer noch keine Stack-Trace. Weder auf der Konsole noch in der von der JVM generierten Datei "hs_err_pidXXXX.log".

Ich habe keine C/C++ in etwa 15 Jahren getan; Ich kann immer noch "raten", was der Code macht, aber ich habe vergessen, wie das Debugging abläuft (jenseits von "printf everywhere" ...), und ich musste nie nativen Code in der JVM debuggen. Bisher war Google keine Hilfe; Ich benutze wahrscheinlich die falschen Begriffe, um zu suchen.

+1

Read [diese] (https://jpassing.com/tag/stacktrace-dbghelp/) oder [diese] (http: // www. codeproject.com/Articles/11132/Walking-the-callstack). Aber es ist vielleicht *** einfacher, einen Java-Heap-Dump ('jmap -dump: file = ') zu bekommen und ihn mit einem Tool wie ** [HeapAnalyzer] (https: // www .ibm.com/developerworks/community/groups/service/html/communityview? communityUuid = 4544bafe-c7a2-455f-9d43-eb866ea60091) ** – rustyx

+0

es sei denn, Sie tun es zum Zwecke der Zuweisung Callsite Recording Stack Spuren sind unwahrscheinlich hilft Ihnen bei der Diagnose eines Speicherlecks. – the8472

+0

Wenn der Agent funktioniert, würde es mir sagen, wo auf etwas verwiesen wird, das nicht mehr da sein sollte. Aber mein Problem ist, dass es abstürzt, was an sich nichts mit einem möglichen Speicherverlust zu tun hat. –

Antwort

2

JVM meldet normalerweise native Stack-Trace im Crash-Dump. Wenn in hs_err_pid.log kein Stack-Trace vorhanden ist, bedeutet dies, dass JVM den letzten Frame aus dem PC-Register nicht abrufen konnte, weil er auf eine nicht lesbare Adresse zeigte.

Zum Beispiel kann dies passieren, wenn ein nativer Code null Funktionszeiger dereferenziert:

void (*func)() = 0; 
func(); 

In diesem Fall PC Null sein wird, und JVM wird die Spur nicht gedruckt. Aber Sie können Anrufer-PC immer noch vom Stapel finden, weil die Rücksendeadresse normalerweise vor einem Anruf auf den Stapel geschoben wird. Hier ist, wie es in hs_err_pid.log zu finden:

Top of Stack: (sp=0x0000000002e2f438) 
0x0000000002e2f438: 00007ffcf03f1030 00007ffcf041d000 
         ^^^^^^^^^^^^^^^^ 
         the return address (the address after the last valid instruction) 

Dann Sie diese Adresse in Dynamic libraries Abschnitt finden und berechnen die von Anfang an von dll versetzt.

Dynamic libraries: 
... 
0x00007ffcf03f0000 - 0x00007ffcf0426000 C:\Java\Test\crash.dll 
^^^^^^^^^^^^^^^^^^ 
offset = 0x00007ffcf03f1030 - 0x00007ffcf03f0000 = 0x1030 

Verwenden Disassembler (z.B. Visual Studio dumpbin) die offest in die jeweilige Funktion/Befehl in den Code zu entschlüsseln.


Sie können auch einen Visual Studio-Debugger an die JVM anhängen, wenn dieser abstürzt. Um dies zu tun, sollten Sie Java mit -XX:+ShowMessageBoxOnError ausführen. Das folgende Fenster wird laden Sie den Debugger zu verbinden:

ShowMessageBoxOnError

+0

Der Inhalt von hs_err_pid.log schien etwas anders zu sein (vielleicht wegen einer anderen Java-Version oder 32/64 Bit Unterschied), und ich konnte die Adresse nicht zu einer bestimmten DLL zuordnen.Aber -XX: + ShowMessageBoxOnError hat es geschafft. Unglücklicherweise passiert der Fehler innerhalb der jvm.dll, und da Oracle die jvm.pdb nicht zur Verfügung stellt, musste ich aufgeben (auch ich war weit hinter der "zugewiesenen Zeit" für diese Aufgabe). –