Debugging the debugger with the inspector

The development of Moose 5.0 has recently moved to Pharo 3.0. The process of migrating from Pharo 2.0 was smooth, the only thing left is to integrate the GTInspector.

This turns out to be a tricky endeavor. The problem is that the SpecDebugger from Pharo relies on the inspector being implemented in Spec as well. Given that GTInspector is implemented in Glamour, this leads to collisions. As a consequence, installing the GTInspector leads to errors in the debugger. The problem is particularly hard because the error actually happens during the opening of the debugger.

When this happens, Pharo provides an emergency printout of the problem, but without any interaction possibilities. Essentially, you end up with an environment that is no better than a limited console.

After a first round of fixes, we ended up on the problem of UndefinedObject not understanding the message #owner:. However, the console does not provide much information about the stack where the error is found.

This is annoying. So, I set myself to find the method that generates the problem. This is a useful input for others that would like to help fix the issue.

In other words, I have a spike assessment on my hands. In this case, it is not the amount of code that is the problem, but rather the amount and intricacies of objects available at runtime.

There are multiple ways to approach this problem. I can look at the senders of owner:, but there are several possible candidates, and given that I not know well the code, it is hard to identify the root cause. I need a debugger, but how to get it given that the problem is in the debugger in the first place?

Let’s see. What else do I know? I know that the message (#owner:) and the receiver of the message (nil). What if I just create this method and inspect the context?

UndefinedObject>>owner: someObject
     thisContext contextStack inspect

I run a code that pops up a debugger, such as self halt, and the inspector appears. thisContext happens to provide all relevant information for the current stack.

Stack.png

This was already great. But, now I want to see the source code of the selected context. The context already has the method, and the method can already display its source. I open the Methods presentation and add a little method:

MethodContext>>gtInspectorSourceIn: composite
     <gtInspectorPresentationOrder: 30>
     self method gtInspectorSourceIn: composite 

Extending.png

I save. The result: a little static debugger. If the live debugger is gone, this little tool can be a life saver.

Source.png

One lesson learnt is that having interactive tools is essential during assessment. In my case, once I noticed that I could use another presentation, I could extend the inspector from within the inspector. The context switch was minimal. Once I saved, the inspector was updated and I could continue inspecting from where I left. The whole process was measured in minutes.

But, the most surprising lesson came from the realization of the incredible power that lies in Pharo and Moose. When such core things like a stack, or extending nil can be so easily manipulated, you should know you are in front of a special system. It changes the way you think about programs. Even if I develop these tools myself, I am still surprised of their power.

We are at a tipping point. Redefining programming is inevitable from this point on. We call it live programming.

Posted by Tudor Girba at 16 November 2013, 12:11 am with tags spike, story, moose, pharo, assessment link
|