Enhancing the Debugger

You can write extensions that enhance debugging through new debugging behavior and views of data. Debugging extensions can be especially useful when you're providing support for new kinds of documents (in addition to JWS files, for example), projects, or data types, and you want to ensure useful debugging for the new features.

Through debugger extensions you can define new views for variables — The locals and watch windows allow you to come up with new views for variable types.

For debugger extension samples, see CustomProject Sample.

Building Debugger Extensions

In your extension.xml file you sketch out your action's user interface as well as connect the action UI and logic to the IDE. The UI for your action will be a menu command (including a popup) or a toolbar button. In your extension XML, part of your user interface can be defined through the <action-ui> element, but you may want to generate user interface dynamically with Java code.

You add support for new actions by

Extension XML for Debugger Extensions

 

Implementing a Debugger Extension's Logic

Defining new views for variables

 

 

IDebugExpressionListener -- two methods

IDebugExpressionView -- the rest

 

toString, but name is null

getName, but it's null

The IDE calls your init method with values you'll use throughout your view class. These include:

You should assign these values to instance variables so that you can use them again in code. The init method is a good place to create an instance-level IDebugExpression variable from the expression you've received; you do this by calling evaluateExpression method of IDebugData. Finally, if the type you're providinga view for has fields, you'll want to call IDebugData.requestFields to prompt the IDE to evaluate the field data (by calling your fieldsChanged method.

Here's an example:

private IDebugExpression m_expression;
private String m_name;
private JTree m_tree;
...
public void init(String primaryExpression, JTree tree, String name)
{
    m_primaryExpression = primaryExpression;
    m_tree = tree;
    m_name = name;
    IDebugData debugData = DebugSvc.get().getDebugData(null);
    if(debugData != null)
    {
        m_expression = debugData.evaluateExpression(primaryExpression, this);
        debugData.requestFields( primaryExpression, this);
    }
}

Your call to evaluateExpression prompts the IDE to call your expressionChanged method. But generally, this method will be called under two circumstances: if the variable you're providing a view for becomes stale (the view hasn't been refreshed since the user last stepped while debugging) or after the IDE gets the value. So your implementation should handle two cases:

If the view is stale you should at least tell the JTree that it should update its display of the variable.

If the view isn't stale,

expressionChanged with the expression created by evaluating the expression string with "this"

refreshFields

getTreeModel to signal nodeChanged

getName again, but now its value is the expression string

toString again, and now there's an expression name

getValueRenderer to get a cell with the value in it

toString again

getValueRenderer

toString

fieldsChanged

processChild

addChild

processChild

addChild

toString

getValueRenderer

toString

...

expressionChanged called for every step

getPrimaryExpression

 

Controlling debugger UI and behavior

[point to frame topic]

You can provide additional windows through an extension. Ensure that the frame will become visible when the IDE enters debug mode (such as when the user clicks the Start button). You do this in the frame's extension.xml file by specifying the frame's scope attribute value as "urn:com-bea-ide:debug".

Related Topics

[tbd]