How to use AFL visual debugger

Basics

To run the formula under debugger simply choose Debug->Go (F5 key) menu in the Formula Editor or click toolbar button marked below as Start/Continue.

In most cases the code would execute in a blink of an eye so you won't even see if it worked. You can stop the execution long enough to see the what is happening by setting a breakpoint and then stepping ahead.

Breakpoints

To set a breakpoint move the cursor to the line where you want to stop the execution and choose Debug->Insert/Remove Breakpoint menu or press press red circle button in the toolbar, or press F9 key. The breakpoint will be shown as red circle in the left margin.

Breakpoints can be added/removed at any time, before you start debugging and while you are debugging. They can be added/removed when debugger is stopped at breakpoint and while the code is running.

Now, start debugging again (Debug->Go). Execution should stop at line marked with breakpoint sign, before this line's code actually executes. A yellow arrow shows current position of execution as shown in the picture below.

Single stepping

You can cause the code to execute by stepping ahead (Debug->Step Over, F10 key). You could also click Debug->Step Into (F11 key) option. The difference between Step Into and Step Over is when you try to single-step a call to user-defined function.

If the line contains a call to user-defined function:

Examining contents of the variables

When debugger is stopped at breakpoint or stopped by single-stepping, you can examine the contents of variables anywhere in the code. To quickly check the content of any variable simply hover the mouse over the variable. After less than one second a tooltip will appear showing type and value of the variable.

The Watch window

If you are interested in watching several variables easily you can use Watch window. To open Watch window use Window->Watch menu.

To add a new variable to Watch window double click on empty row and type the variable name. You can also simply select the variable in the editor and drag it over the Watch window.

To edit existing variable in the Watch window double click on its name and type the variable name.

To delete the variable from Watch window, click on the name once (select it) and press DELETE key.

In addition to variables, you can use entire expression in the Watch window. You can either drag-drop expressions from editor onto Watch window, or type the expression after double clicking as you would with variables. The expression evaluator used by Watch window supports the following:

Note that only identifiers that can be used in Watch window are variable identifiers. You can not use function identifiers, so you can't call functions from the Watch window.

The values entered in the Watch window are watched for changes and if change in value occurs between two debugging steps, given value is highlighted with yellow background. Numeric (scalar) values are displayed in green when they increased or red if they are decreased.

Arrays tab

The array tab in the Watch window shows exploration-like array output for detailed examination of array contents (first 20 arrays from watch window are reported). It is very convenient as arrays are usually large and having them in the table format together with bar number and corresponding date/time stamp makes it a lot easier to see their contents. Additionally each element of each array is watched for changes and individual item change is highlighted and auto-scroll occurs so first changed item is always visible in the 'Arrays' tab.

Output window

When you run the code in the debugger, you can use the Output window (open it using Window->Output menu) to display all texts that are printed using printf() function. When formula finishes its execution the text "Debug session has ended" is displayed in the Output window.

Debugger preferences

Tools->Preferences window contains now a dedicated page with Debugger settings. The settings are as follows:

Keyboard shortcuts

The following keyboard shortcuts are available in the debugger mode:

Tips & tricks

If you want to stop execution when certain condition is met, put the breakpoint inside the if statement like this:

      if( reset > 0 AND param > 4 )
      {
          cs = 0; // PUT BREAKPOINT IN THIS LINE and it will stop only when condition is met
      }

Breakpoints currently work with:

Breakpoints that you place on other lines, won't trigger. The AFL editor won't allow to place breakpoint on empty line, or line that beginnins with // comment or sole brace

You need to be also aware about the fact that breakpoints placed inside conditional statements like if() are only hit when given condition is met. So for example if you have code like below, the code inside 'if' statements won't execute unless it is actually run in the chart (indicator) or in portfolio backtest in New Analysis window.

if( Status("action") == actionIndicator )
{
   // breakpoint placed here won't trigger under debugger because condition above is not met
}

if( Status("action") == actionPortfolio )
{
   // breakpoint placed here won't trigger under debugger because condition above is not met
}

AmiBroker executes code in various contexts indicated by "action" status. Parts of the code can be conditionally executed in certain contexts using statements like shown above. This allows for example to call Plot() only in charts and access backtest object only when it is available.

As of version 6.10, the debugger runs the code with actionBacktest context. To debug code that is run conditionally in other contexts, you can temporarily disable the conditional check, but please note that you still can not access certain objects because they are simply not available. Specificaly GetBacktesterObject() when called anywhere outside second phase of portfolio backtest within New Analysis would return empty (Null) object. In the future this limitation may be removed.