hilfe bei jdb

kyroding

Grünschnabel
Hallo,

ich habe ein kleines problem bei der der jdb library. ich schaffe es zwar in meiner anwendung in einer Methode anzuhalten und mir deren lokale variablen anzuzeigen, schaffe es aber nicht mir die werte der Klassenvariablen (ich glaube das geht irgendwie mit Fields) anzuzeigen. Heisst also ich habe zwar die namen der klassen variablen nicht aber deren werte. Ich hoffe mir kann einer helfen.

Bsp: in dieser klasse halte ich bei aufruf der testMethod an und hätte gern auch die werte von intVal und strVal.

public class test
{

private int intVal = 3;
private String strVal = "test"


public void testMethod()
{
int i=0;
}

}


Gruß kyro
 
Na dann gib sie doch einfach aus. :rolleyes:
z.b.
Code:
System.out.println(Variablenname);

!Ach ja und verwende das Nächstemal die Code-Tags!
 
Hallo,

danke für die schnelle Antwort. aber ich glaube ich muss es doch etwas genauer beschreiben.

Ich habe eine java-Anwendung welche ich im debugmodus starte. Auf diese Anwendung verbinde ich mich via der jdb (debugger)-library. Nun halte ich in einer beliebigen methode einer beliebigen Klasse an (stoppe die vm). Hier erhalte ich ohne großen aufwand die lokalen variablen der methode:

Code:
public static void printValues(List list , StackFrame stack)
{
	  for (Iterator it2=list.iterator(); it2.hasNext();) 
    	  {
		  Object obj = it2.next();
    		  LocalVariable localVariable = (LocalVariable) obj;
    		  Value localVariableValue = stack.getValue(localVariable);
    		 
    		  System.out.println("Method-Variable " +localVariable.name()+ ": "+   
                  localVariableValue );			    	  
    	  }
}
....
 if (event instanceof BreakpointEvent) 
  {
	    	ThreadReference thread=((BreakpointEvent) event).thread();
	    	List stackList=thread.frames();

			    	
	    	StackFrame stackFrame=(StackFrame) stackList.get(0);
			    
					
	    	try
	    	{
	    		ObjectReference thisObject=stackFrame.thisObject();
  	 
			List loList = stackFrame.visibleVariables();
	        	printValues(loList, stackFrame);	
	    	}
	    	catch(Exception e)
	    	{
    		  e.printStackTrace();
	    	}
}

wie nun aber bekomme ich die variablen der zu debuggenden Klasse (und deren werte). Vielleicht hat ja jemand ein Codebeispiel für mich. Das ganze soll mal ein kleiner debugger werden.

Gruß kyro
 
Hallo,

hier mal ein einfches Beispiel:
Java:
package de.tutorials;

public class DebugDummy {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int i = 4711;
        System.out.println("1");
        System.out.println("2");
        String s = "foo";
        System.out.println("3");
        System.out.println("4");
        System.out.println("5");
        System.out.println("6");
        System.out.println("7");
    }

}

Unser Debugger:
Java:
package de.tutorials;

import java.util.List;
import java.util.Map;

import com.sun.jdi.Bootstrap;
import com.sun.jdi.LocalVariable;
import com.sun.jdi.StackFrame;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.VirtualMachineManager;
import com.sun.jdi.connect.AttachingConnector;
import com.sun.jdi.connect.Connector;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.EventQueue;
import com.sun.jdi.event.EventSet;
import com.sun.jdi.event.MethodEntryEvent;
import com.sun.jdi.request.EventRequestManager;
import com.sun.jdi.request.MethodEntryRequest;
import com.sun.jdi.request.StepRequest;

public class JTIExample {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        VirtualMachineManager vmm = Bootstrap.virtualMachineManager();
        AttachingConnector ac = vmm.attachingConnectors().get(0);

        Map<String, Connector.Argument> env = ac.defaultArguments();
        Connector.Argument port = env.get("port");
        port.setValue("8000");

        Connector.Argument hostname = env.get("hostname");
        hostname.setValue("localhost");

        VirtualMachine vm = ac.attach(env);
        EventQueue eventQueue = vm.eventQueue();
        EventRequestManager mgr = vm.eventRequestManager();

        // Wir legen die VM schlafen...
        vm.suspend();

        // Wir suchen unseren "Main-Thread"
        ThreadReference mainThread = null;
        List<ThreadReference> threads = vm.allThreads();
        for (ThreadReference thread : threads) {
            if ("main".equals(thread.name())) {
                mainThread = thread;
            }
        }

        // Hier registrieren wir einen MethodEntryRequest der dem JDI mitteilt,
        // das wir an dem Methodeneintrittsereignis interessiert sind.
        MethodEntryRequest methodEntryRequest = mgr.createMethodEntryRequest();
        methodEntryRequest.addClassFilter("*DebugDummy");
        methodEntryRequest.addThreadFilter(mainThread);
        methodEntryRequest.enable();

        // Wir lassen die VM weiterlaufen
        vm.resume();

        System.out.println("go");

        mainThread.resume();

        // wir suchen unser MethodEntryEvent im aktuellen EventSet der
        // EventQueue
        Event event = null;
        while (true) {
            EventSet eventSet = eventQueue.remove();
            event = eventSet.eventIterator().next();
            if (event instanceof MethodEntryEvent) {
                break;
            }
        }

        MethodEntryEvent mee = (MethodEntryEvent) event;
        // Location location = mee.location();

        // Wir wollen nur über die ersten 5 Anweisungen der main Methode steppen
        // anschließend soll die Ausführung ganz normal weiter laufen...
        for (int i = 0; i < 5; i++) {
            // Wir erzeugen einen neuen StepRequest, da wir dem JDI mitteilen
            // wollen,
            // dass wir im Einzelschritt über die nächste Anweisung gehen
            // wollen.
            System.out.println("Try to step...");
            StepRequest stepRequest = mgr.createStepRequest(mainThread,
                    StepRequest.STEP_LINE, StepRequest.STEP_OVER);

            System.out.println("Visible stack variables:");

            StackFrame currentStackFrame = mee.thread().frame(0);
            List<LocalVariable> visibleVariables = currentStackFrame
                    .visibleVariables();
            for (LocalVariable localVariable : visibleVariables) {
                System.out.println(localVariable +" value: " + currentStackFrame.getValue(localVariable));
            }

            stepRequest.addClassFilter("*DebugDummy");
            stepRequest.addCountFilter(1);
            stepRequest.enable();

            // Wir lassen die VM weiterlaufen
            // Diese führt nun wie von uns angefordert die nächste Anweisung
            // aus.
            vm.resume();

            // Anschließend warten wir ein paar Sekunden...
            try {
                Thread.sleep(5000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // Wir entfernen den Request aus der Event queue, damit wir
            // in der nächsten Iteration einen neuen Request nachschieben
            // können.
            // Es darf nämlich immer nur ein Request per Thread gleichzeit
            // laufen.
            mgr.deleteEventRequest(stepRequest);
        }

        // Wir geben die fremde VM wieder frei... wir beenden unsere
        // Debuggingsession
        // -> Die Anwendung läuft wieder ganz normal weiter....
        vm.dispose();
    }
}



Ausgabe Debugger:
Code:
go
Try to step...
Visible stack variables:
args in de.tutorials.DebugDummy.main(java.lang.String[])@de.tutorials.DebugDummy:10 value: instance of java.lang.String[0] (id=38)
Try to step...
Visible stack variables:
args in de.tutorials.DebugDummy.main(java.lang.String[])@de.tutorials.DebugDummy:10 value: instance of java.lang.String[0] (id=38)
i in de.tutorials.DebugDummy.main(java.lang.String[])@de.tutorials.DebugDummy:11 value: 4711
Try to step...
Visible stack variables:
args in de.tutorials.DebugDummy.main(java.lang.String[])@de.tutorials.DebugDummy:10 value: instance of java.lang.String[0] (id=38)
i in de.tutorials.DebugDummy.main(java.lang.String[])@de.tutorials.DebugDummy:11 value: 4711
Try to step...
Visible stack variables:
args in de.tutorials.DebugDummy.main(java.lang.String[])@de.tutorials.DebugDummy:10 value: instance of java.lang.String[0] (id=38)
i in de.tutorials.DebugDummy.main(java.lang.String[])@de.tutorials.DebugDummy:11 value: 4711
Try to step...
Visible stack variables:
args in de.tutorials.DebugDummy.main(java.lang.String[])@de.tutorials.DebugDummy:10 value: instance of java.lang.String[0] (id=38)
i in de.tutorials.DebugDummy.main(java.lang.String[])@de.tutorials.DebugDummy:11 value: 4711
s in de.tutorials.DebugDummy.main(java.lang.String[])@de.tutorials.DebugDummy:14 value: "foo"

Starten mit:
Code:
C:\Dokumente und Einstellungen\Thomas.Darimont\workspace-3.3.1.1-aop\de.tutorials.training\bin>java -agentlib:jdwp=transport=dt_socket,server=y,address=8000 de.tutorials.DebugDummy

Ausgabe Client:
Code:
Listening for transport dt_socket at address: 8000
1
2
3
4
5
6
7
Listening for transport dt_socket at address: 8000

Gruß Tom
 
Hallo,

genau so ist es soweit hab ich es auch schon gelöst:

Code:
if (event instanceof BreakpointEvent) 
{
	ThreadReference thread=((BreakpointEvent) event).thread();
   	List stackList=thread.frames();
			    	
    	StackFrame stackFrame=(StackFrame) stackList.get(0);
			    
    	try
    	{
    		ObjectReference thisObject=stackFrame.thisObject();
			    		
    		ReferenceType refField = thisObject.referenceType();

    		List list = refField.allFields();
    		for (Iterator it2=list.iterator(); it2.hasNext();) 
      	  	{
    			Field field = (Field) it2.next();
			    			
    			Value val = refField.getValue(field);
    			System.out.println("Field "+field.name() + ": "+ val );
      	  	}
	...

Ich habe nun die Fields und kann auch deren Values anzeigen aber nur wenn sie static sind ist ein field nicht static bekomme ich die exception :

java.lang.IllegalArgumentException: Attempt to use non-static field with ReferenceType

kapier ich nicht :confused:
 
Hallo,

ich habs hinbekommen... die exception war völlig logisch. Wenn ich die values aus dem Object auslese funktioniert auch alles wunderbar. unten steht jetzt nochmal der funktionierende code zum Fields und deren Values auslesen. Ich danke euch allen für eure Hilfe ... Klasse Forum.

Gruß kyro


Code:
if (event instanceof BreakpointEvent) 
{
	ThreadReference thread=((BreakpointEvent) event).thread();
   	List stackList=thread.frames();
			    	
    	StackFrame stackFrame=(StackFrame) stackList.get(0);
			    
    	try
    	{
    		ObjectReference thisObject=stackFrame.thisObject();
			    		
    		ReferenceType refField = thisObject.referenceType();

    		List list = refField.allFields();
    		for (Iterator it2=list.iterator(); it2.hasNext();) 
      	  	{
    			Field field = (Field) it2.next();
			    			
    			Value val = thisObject.getValue(field);
    			System.out.println("Field "+field.name() + ": "+ val );
      	  	}
	...
 
Zurück