Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [incquery-dev] debugger tooling

Hi
Seems promising. My question is that how different is this view from implementing a logical structure presentations for the IncQuery matcher classes. Logical structures are used to define what attributes are to be displayed. The first part of a video for the Debug Visualization project demonstrates a little bit what is possible with logical structures (http://www.youtube.com/watch?v=bMSv5OKZ_no).

I don't want to make your work seem less; but it might give an idea which way to go from here (that I do not know).
In this solution I tried to minimize the code used for the user interface. Basically I am extending the org.eclipse.debug.internal.ui.views.variables.VariablesView class and I am using the functionalities of that one. The only thing that I have overriden is that when internally a stack frame is set for this view to display the variables I simply "transform" the frame. This means that I wrap the original frame and fool the view by adding my own variables (on the top level these are the engines) instead of the original local variables. In the end, no additional user interface code is used, I only restrict and modify the visible children for my custom variables. on the bottom level (from the match parameters) I use the original code to obtain the visible local variables without any restriction.
The attached screenshot was taken during the debugging of an OSGi test application with pattern matching.
Here you can see on the top level of the tree hierarchy the IncQueryEngine instances in the target JVM. Note that this View is usually one level below the target Eclipse instance, this case is special in the sense, that the debugger and the target app run "in the same Eclipse instance" (of course in different JVMs). This view would briefly correspond to point 2 in the issue description.
Nevertheless, I do not really understand what does it mean to "point my debugger" (@Gaben).
Basically, it boils down to somehow identifying and selecting a single engine and then displaying the internals of that.
These things are accessible through the Debugger API, basically I can retrieve the ClassLoader object (a special one, these things are under the com.sun.jdi package) from the stack frame when the view is notified that the application has stopped at a breakpoint. Then I can get all the instances of the given class (engines) and access attributes of these instances similarly to Java Reflection. I can even call methods in the target VM with the Debugger API, but at the moment it is a bit problematic. Consider the following snippet:

    Method method = null;
        try {
            List<Method> methods = ref.referenceType().methodsByName(methodName);
            for (Method m : methods) {
                if (m.arguments().isEmpty()) {
                    method = m;
                    break;
                }
            }
        }
        catch (AbsentInformationException e) {
            //ignore
        }
        if (method != null) {
            while (result == null && t < 10) {
                try {
                    result = ref.invokeMethod(threadReference, method, new ArrayList<Value>(), 0);
                } catch (Exception e) {
                    result = null;
                }
                t++;
            }
        }

The classes here are from the com.sun.jdi package.

This method body tries to call the given method (parameterless!) on the given ObjectReference instance. However, sometimes I get an InvalidThreadStateException during the invocation.
The JavaDoc says that this Exception is thrown when the thread has not been suspended by an event (http://download.java.net/jdk8/docs/jdk/api/jpda/jdi/com/sun/jdi/ObjectReference.html#invokeMethod%28com.sun.jdi.ThreadReference,%20com.sun.jdi.Method,%20java.util.List,%20int%29). What I have found out (and is surprising) is that consecutive invocations (2-3 tries) usually (99% of the time) succeed. This method implementation with the while loop may seem strange but it works most of the time, I just wanted to restrict the possibility of an infinite loop. This whole method invocation is necessary because I cannot get the matches of a matcher from an instance field.
Are you sure that the threadReference refers to a thread that is suspended? Can you check threadReference#isSuspended (http://download.java.net/jdk8/docs/jdk/api/jpda/jdi/com/sun/jdi/ThreadReference.html#isSuspended())?

If the thread is indeed not suspended, it would suggest that the suspension of threads is not automatical (and be careful, as breakpoints can suspend only a single thread or all threads, depending on breakpoint properties).

The thread is suspended for sure, the most annoying thing is that most of the time a consecutive try solves the problem.

Cheers,
Tomi


Back to the top