2015-05-07 20 views
7

Ich versuche Zuordnungen aller Objekte in JVM zu verfolgen.Hinzufügen von invokestatic zu java/lang/Object. <init> über JVM TI Agent verursacht JVM zum Absturz mit segfault

In den verschiedenen Dokumenten über Zuteilung Profilometer wurde erwähnt, dass der einfachste Weg, dies zu tun dies: hinzufügen invokestatic Tracker.trackAllocation()V Anweisung java/lang/Object.<init> (in der Regel besteht es aus einer einzigen return Anweisung, fügen wir invokestatic, bevor es, so dass es 2 Anweisungen jetzt).

(Ich weiß, dass dieser Ansatz langsam ist und Array-Zuordnungen nicht verfolgen wird, aber ich wollte mit der einfachsten Lösung beginnen. Auch gebe ich keinen Verweis auf das zugewiesene Objekt zum Tracker, aber das wird später hinzugefügt.)

Die Klassendatei ist mit dem JVM TI-Agenten im onClassLoaded-Hook ausgestattet.

Nach dem Hinzufügen der Anweisung invokestatic stürzt JVM jedoch mit segfault ab. Das Tracker-Objekt wird dem Bootstrap-Klassenlader hinzugefügt, sodass es in jeder Phase sichtbar sein sollte. Ich habe versucht, nop anstelle von invokestatic hinzuzufügen, und JVM funktioniert gut mit der geänderten Object-Klasse. Das Problem liegt also speziell beim Aufruf einer statischen Methode.

Ich habe auch versucht, Anwendung (nicht Teil der Basis) Klassen zu instrumentieren und es hat gut funktioniert - Tracker wurde aufgerufen und es gab keine Abstürze. Ich habe auch versucht, Object an 2 Punkten neu zu definieren: wenn es anfänglich geladen wird (erste geladene Klasse), oder nach dem vmInit-Ereignis (wenn alle Basisklassen geladen sind und Beschränkungen für jni aufgehoben werden).

Gibt es irgendetwas, das ich vermisse, java.lang.Object zu instrumentieren?

-Code für die Agenten ist hier: https://gist.github.com/Korobochka/3bf2f906f6ab85b22dec (Fehlerüberprüfung gestrippt wird, Code-Klassen für die Änderung ist auch nicht enthalten, aber es funktioniert gut genug für andere Klassen)

+0

Zeigen Sie uns den Code – apangin

+0

@apangin Ich habe den Kern mit Agentencode am Ende der Frage hinzugefügt. Dies ist die Version, in der Object nach vmInit geändert wird. – Korobochka

+1

Ich denke, das Problem ist, dass die Tracker-Klasse selbst ein Objekt ist, das instanziiert werden muss, bevor ein Objekt erstellt wird, aber das würde erfordern, dass die Klasse zuerst geladen wird ... und so weiter. Du musst diesen Zyklus irgendwie unterbrechen. – biziclop

Antwort

5

Sieht aus wie das Problem in ist System.out.println Aufruf von LeakAgentInterface. Zunächst kann System.out noch nicht initialisiert werden. Zweitens kann println Objekte selbst zuweisen.

+1

Und dies beinhaltet die "Zeichenfolge", die gedruckt wird, die auch ein Objekt ist; sogar Kompilierzeitkonstante 'Zeichenfolgen müssen zur Laufzeit zugewiesen werden, wenn sie das erste Mal verwendet werden ... – Holger

+0

Einfach überprüft, das ist in der Tat der Fall. Vielen Dank!Ich habe ein paar Stunden damit verschwendet und der Fehler war sehr einfach und dumm = (Aber ich habe nur den Fehler im C++ Code gesucht. Dumm mich. – Korobochka