Skip to main content



      Home
Home » Language IDEs » Java Development Tools (JDT) » access runtime variables and pass them to a separate debugger view
access runtime variables and pass them to a separate debugger view [message #521523] Wed, 17 March 2010 17:31 Go to next message
Eclipse UserFriend
Hi all,

This may sound naive to most people here, but I am new to jdt and couldn't figure it out...

Background: we want to provide a debugging tool for our 3D application developers that allows them to browse the runtime scene tree and examine the attribute values of each scene node in debug mode. Two reasons for the tool: 1. the rendering part is done through JNI calls to our native 3D engine, so most attributes are not seen from the VariablesView in Eclipse; 2. we want a customized view for inspecting the scene tree.

Launching a new view should be straightforward, however, I have no clue how to access a runtime variable, "unwrapp" it, so we get the proper java object (in our case, the sceen root), and pass it to the new view. Can anyone please offer some advice or point me to some references? Thanks a lot in advance!

Alternatively, shall we launch a standalone viewer app from the main process asynchronously and pull the values from main when needed? The downside as I see being that we won't be able to leverage the existing plug-ins Eclipse provides and extend upon them. Are there any other ways to achieve our goal or any thoughts on the two approaches? Any input would be highly appreciated!

Best,
Jingjing
Re: access runtime variables and pass them to a separate debugger view [message #521813 is a reply to message #521523] Thu, 18 March 2010 15:15 Go to previous messageGo to next message
Eclipse UserFriend
Can someone please suggest something? I am looking into org.eclipse.jdt.internal.debug.core.model, am I on the right track? Do I need to have my own implementation of sun's JDI (java debug interface) to access objects from the virtual machine? Any extension points that I can leverage from Eclipse? Thanks in advance for any helps... It is really driving me crazy...
icon12.gif  Re: access runtime variables and pass them to a separate debugger view [message #533452 is a reply to message #521813] Thu, 13 May 2010 19:59 Go to previous message
Eclipse UserFriend
I figured it out and finished the debugger, thought it might be helpful to post it in case someone wants to do similar things. I'm just starting learning JDWP, JDI myself, so advanced Java programmers can skip it. If you noticed any mistakes in the post, please help reply and correct me. Thanks in advance!

First of all, you CAN get a handle of the variable from the Debug Variable view, but it can NOT simply be "unwrapped" into a Java Object. What you get is a JDIVariable that mirrors the local variable in the current stackframe. Similar to reflection, you can then recursively evaluate the attribute values of a complex object, which was how I implemented my scene browser. You can find a graphical overview here: http://java.sun.com/j2se/1.4.2/docs/guide/jpda/architecture. html. I also found this article helpful: http://bracha.org/mirrors.pdf in explaining the fundamentals.

Eclipse implements sun's JDI interface. Lots of my time was spent on trying to figure out how to use these internal classes to invoke method calls, create a mirror instance from a java object, etc. Hopefully you guys would not need to do the same thing any more. The below code snippets should be self-explanatory, let me know otherwise.

1. Access JDIVariable:
My debugger is designed as an Eclipse plugin. I extended the context menu in the Variables View, and the entry point for browsing a variable is in the command handler of the new menu item.

so:
public class myHandler extends AbstractHandler {
public Object execute(ExecutionEvent event) {

IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);

ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event).getActivePage(). getSelection();

if (selection != null & selection instanceof IStructuredSelection) {
IStructuredSelection strucSelection = (IStructuredSelection) selection;
JDIVariable obj = (JDIVariable) strucSelection.getFirstElement();

try {
IValue objval = obj.getValue();
if (objval instanceof JDIValue) {
if (objval instanceof JDIObjectValue) {

JDIObjectValue jdiobjval = (JDIObjectValue)objval;

IAdaptable dc = DebugUITools.getDebugContext();
IJavaStackFrame frame= (IJavaStackFrame) dc.getAdapter(IJavaStackFrame.class);

if (frame != null) {
IJavaThread thread = (IJavaThread) frame.getThread();

if (thread instanceof JDIThread) {
JDIThread jdithread = (JDIThread) thread;
// then do your stuff, the thread will be used later

}
}

2. convert primitive types to JDIPrimitiveValue
public JDIValue floatToJDIValue(VirtualMachineImpl vmImpl, JDIThread thread, float value) {
FloatValue fv = vmImpl.mirrorOf(value);
return (new JDIValue((JDIDebugTarget)thread.getDebugTarget(), fv));
}

3. convert array to JDIArrayValue
static public JDIValue arrayToJDIValue(VirtualMachineImpl vmImpl, JDIThread thread, int arrLen, String arrSignature) {

// allClasses() includes classes, interfaces and arrays
// Both the JNI signature and the generic signature are returned for each class
List allclasses = vmImpl.allClasses();

for(int idx = 0; idx < allclasses.size(); idx++) {
Object tmptype = allclasses.get(idx);

if (tmptype instanceof ArrayTypeImpl) {
ArrayTypeImpl arrayType = (ArrayTypeImpl)tmptype;

if (arrayType.signature().equals(arrSignature)) {
ArrayReference arrRef = arrayType.newInstance(arrLen);
return (new JDIArrayValue((JDIDebugTarget)thread.getDebugTarget(), arrRef));

}
}
}

4. invoke methods with no args
static public JDIValue invokeMethodWithNullArgs(JDIObjectValue jdiObjVal, JDIThread thread, String methodName, String methodSignature) {
String refTypeSignature = jdiObjVal.getUnderlyingObject().referenceType().signature();
try {
return (JDIValue) (jdiObjVal.sendMessage(methodName, methodSignature, null, thread, refTypeSignature));
} catch (DebugException e) {
e.printStackTrace();
}
return null;
}

5. get a mirror of a java object
/**
*
* @param vmImpl mirror of the virtual machine
* @param thread the thread in which to invoke the constructor
* @param classSignature JNI-style signature of the class
* @param conSignature JNI-style signature of the object's constructor
* @param conArgs argument list to be passed into the constructor
*
* @return representation of a new instance of the object on JVM
*/
static public JDIValue objectToJDIValue(VirtualMachineImpl vmImpl, JDIThread thread,
String classSignature, String conSignature, List conArgs) {
// or classesByName()
List classes = vmImpl.classesBySignature(classSignature);
ClassTypeImpl classtype = (ClassTypeImpl)classes.get(0);

// get constructor
String conMethodName = "<init>"; //TODO: double check if this is always the case
if (conSignature.length() == 0) { // default, no arguments for the constructor
conSignature = "()V";
}

List methods = classtype.methodsByName(conMethodName, conSignature);

Method conMethod = (Method)methods.get(0);
int options = ClassType.INVOKE_SINGLE_THREADED;

try {

ObjectReference newObjRef = classtype.newInstance(thread.getUnderlyingThread(), conMethod, conArgs, options);
return (new JDIObjectValue((JDIDebugTarget) thread.getDebugTarget(), newObjRef));

} catch (InvalidTypeException e) {
e.printStackTrace();
} catch (ClassNotLoadedException e) {
e.printStackTrace();
} catch (IncompatibleThreadStateException e) {
e.printStackTrace();
} catch (InvocationException e) {
e.printStackTrace();
}

return null;

}

return null;

}

6. to get VirtualMachineImpl from a JDIObjectValue
vmImpl = ((ObjectReferenceImpl)objVal.getUnderlyingObject()).virtualM achine()


I hope it helps. Thanks for reading!

Best,
Jingjing

[Updated on: Thu, 13 May 2010 20:06] by Moderator

Previous Topic:Bottom-Up Web Service help
Next Topic:Custom Quick Assist - how to determine code indentation?
Goto Forum:
  


Current Time: Fri Mar 21 11:08:19 EDT 2025

Powered by FUDForum. Page generated in 0.04228 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top