Conditional breakpoint workaround

As you may know, the Ax debugger does not feature conditional breakpoints. It does obviously allow you to set breakpoints, but there is no option to make them active depending on some condition that is evaluated each time the breakpoint is encountered. There are some programming scenarios where it is highly advantageous to be able to do this, and providing this feature has been a recurring request from the Ax community.

 

As it happens, it is possible to mimic conditional breakpoints by using a statement that is not well known to many X++ programmers: The breakpoint statement(!). Whenever a breakpoint statement is executed, the debugger will wake up, just as if the user had set a breakpoint at the indicated position.

 

The way to emulate the conditional breakpoints is simply to provide the breakpoint inside an if statement:

 

If (condition)

    Breakpoint;

 

in some interesting place in your source (where you would otherwise have put your conditional breakpoint). Now the whole range of what is allowed in expressions is at your disposal for determining whether or not the breakpoint should be executed: You could do stuff like

 

If ( (select firstonly Name from CustTable where CustTable.Name == ‘Jones’).RecId)

    Breakpoint;

 

To break when Jones is present in the customer table.

 

There is another useful technique that you can use, involving the use of the setPrefix function. This function allows you to associate a string to the current call stack frame: When the current method returns, the call stack frame is destroyed and the string goes away. The getPrefix function provides a string that is the result of concatenating of all the strings on the call stack, with a trailing tab character (presumably to make printing them in the infolog reflect indentation).

 

If you are diligent in providing this information, typically with:

 

setPrefix(funcname())

 

you will be able to set a breakpoint according to where the method was called from (going down any number of stack frames) by examining this string. For instance by counting references to a particular function name you could easily express that the breakpoint should trigger when the function was called more than a predefined number of times.

 

You may want to create a static method in the Global class:

 

static public boolean EnableBreakpoints() { return true; }

 

And use that in the conditions:

 

If (EnableBreakpoints() && parm1 == 67)

    Breakpoint;

 

so could easily turn them all off at once. In any case, do not ship your application to the customer with breakpoints in them!

 

As you can see, this is far above and beyond what can be done with normal expressions in conditional breakpoints. For your information, the .NET environment does support starting the debugger programmatically by using the System.Diagnostics.Debugger.Break() method.

 

This technique works on all versions of Ax.