2.12.2. Finding the cause of a data abort

This example demonstrates how you can use the trace features of RealView Debugger to locate a problematic area in your application. It assumes that you are using an ETM-based target, for example an ARM966E-S processor.

The primes.axf image used in this example is designed to calculate the nth prime number, where you are prompted to indicate n when running the image. However, execution of the image results in a data abort.

This example is in two parts:

  1. Procedure for finding the cause of a data abort

  2. Displaying inferred registers.

Procedure for finding the cause of a data abort

To determine the cause of the data abort in the Primes example:

  1. Connect to your debug target.

  2. Load the example image primes.axf into the debugger. This file is located in the install_directory\RVDK\Examples\...\primes directory. The tab for primes.cpp is displayed in the File Editor pane.

  3. Disable the Data Abort vector catch to prevent any Data Abort exception from being caught by the debugger. How you do this depends on your JTAG interface unit:

    RealView ICE interface unit

    If you are using RealView ICE:

    1. Select Debug → Processor Exceptions... from the Code window main menu to open the Processor Exceptions List Selection dialog box.

    2. Make sure that required exception is not selected in the list of processor events.

    3. Click OK to close the dialog box.

    Alternatively, you can disable the Data Abort vector catch using the BGLOBAL command (see the RealView Developer Kit v2.2 Command Line Reference Guide for more details). For example:

    bglobal,disable “data abort”
    
    Non-ARM JTAG interface unit

    If you are using a non-ARM JTAG interface unit, see the documentation accompanying your hardware for information on how to disable the vector catch for an exception.

  4. Select View → Analysis Window from the Code window main menu to display the Analysis window.

  5. Configure the general tracing options. From the Analysis window main menu:

    1. Select Edit → Trigger Mode → Collect Trace Before Trigger.

    2. Select Edit → Trigger Mode → Stop Processor On Trigger.

    3. Select Edit → Data Tracing Mode → Data and Address.

    This ensures that a buffer-load of trace data is captured for the area of your application occurring before any trigger point you set. This is useful when you want to see the events leading up to, but not occurring after, the trigger point. In this example, the trigger point represents the area in the application where the data abort occurs.

    Note

    You can use the default ETM configuration for the target.

  6. Display the Data Abort vector as follows:

    1. In the File Editor pane of the Code window, select the Dsm tab to display the disassembly of the application image.

    2. Right-click in the white space to the right of the disassembly code in the File Editor pane. A context menu is displayed.

    3. Select View from Location... from the context menu. A Prompt dialog box is displayed.

    4. In the dialog box, enter the value 0 and click Set. This displays the region of memory containing the exception vectors. An arrow is placed next to the address 0x00000000.

  7. Set a trace trigger point on the Data Abort vector as follows:

    1. In the File Editor pane of the Code window, select the Dsm tab to display the disassembly of the application image.

    2. Right-click in the left margin at the address 0x00000010 to display the context menu.

    3. Select Set/Toggle Tracepoint... from the context menu. A List Selection dialog box is displayed.

    4. In the List Selection dialog box, select Set Trigger and click OK. Another arrow is placed next to the address 0x10. This arrow indicates the trigger point you have set, and details of this trigger tracepoint are displayed in the Break/Tracepoints pane of the Code window, as shown in Figure 2.42.

      Figure 2.42. Setting a trigger point

      Setting a trigger point
  8. Set a start of trace range tracepoint to capture instruction and data accesses as follows:

    1. Right-click in the left margin at the address 0x0 to display the context menu.

    2. Select Set/Toggle Tracepoint... from the context menu. A List Selection dialog box is displayed.

    3. In the List Selection dialog box, select Start of Trace Range (Instruction and Data) and click OK. Another arrow is placed next to the address 0x0. This arrow indicates the start of the trace range you have set, and details of this tracepoint are displayed in the Break/Tracepoints pane of the Code window, as shown in Figure 2.43. The end of the trace range is automatically set to the end of memory space (0xFFFFFFFF).

      Note

      If you do not set any tracepoints (that is, the trigger and trace range in this example), then Automatic Tracing Mode is used. See Automatic Tracing Mode for information on selecting the Automatic Tracing Mode.

      If you set a trigger but no trace range, then all instructions are traced, but no data (see Trigger).

      Figure 2.43.  Setting a trace range

      Setting a trace range
  9. Select Debug → Run from the Code window main menu. The image is executed and a prompt is displayed in the Output pane at the bottom of the Code window.

  10. In the Output pane (ensuring that the StdIO tab is selected), enter 20 and press Enter. As a result of a deliberate error in the image, a data abort occurs. Because you have set a trigger point at the data abort address, the results of the trace capture are returned.

  11. To view the results of the trace capture, select View → Analysis Window from the Code window main menu. The Analysis window is opened, and the Trace tab is displayed. The disassembly of program instructions is displayed by default, as shown in Figure 2.44.

    Figure 2.44. Results displayed in the Trace tab

    Results displayed in the Trace tab
  12. Hide the Opcode column and view the interleaved source and function boundaries to help you locate the error in CalculatePrimes().

    From the Analysis window main menu, do the following:

    1. Select Trace Data → Opcode (see Columns in the Trace tab for more details).

    2. Select Trace Data → Interleaved Source (see Rows in the Trace tab for more details).

    3. Select Trace Data → Function Boundaries (see Rows in the Trace tab for more details).

    4. Select Find → Find Trigger.

    RealView Debugger locates the row in the output representing the trigger point you have set, shown in Figure 2.45.

    Note

    Some of the details shown in Figure 2.45, for example the values in the Elem column, might be different depending on your JTAG interface unit and target processor.

    Figure 2.45. Interleaved source in Trace tab

    Interleaved source in Trace tab
Observations on tracing the data abort

The red line labeled DATA ABORT, shown in Figure 2.45, is the trigger point (at address 0x00000010). In the rows with an Elem value of -72 to -46, you can see that a value of -1 (0xFFFFFFFF) is being used as a pointer. When OutputResults() attempts to use the value on input, the Data Abort occurs (the rows with an Elem value of -14).

The error is in the way the CalculatePrimes() function returns the prime number calculated. The main() function expects an address to be returned, which it can place in a pointer, and then use for outputting. However, the CalculatePrimes() function is passing a number not an address. This means that the image tries to access memory location -1 (0xFFFFFFFF).

In this example, the vector is initialized to one space more than is required, and all elements are set to -1. This ensures that the calculation function passes back the one unused element.

Displaying inferred registers

RealView Debugger enables you to view the values that the registers held at each instruction in the trace output. The values are obtained by examining line of the trace output, so not all register values can be inferred. The registers are interleaved with the trace output, and the instruction boundaries are also displayed.

To display inferred registers for the data abort example:

  1. If you have not already done so, perform the procedure in Procedure for finding the cause of a data abort.

  2. From the Analysis window menu:

    1. Select Trace Data → Inferred Registers (see Rows in the Trace tab for more details).

    2. Select Find → Find Trigger.

    The Trace tab looks like that shown in Figure 2.46. You might have to scroll down to view the information following the trigger point.

    Figure 2.46. Inferred registers in the Trace tab

    Inferred registers in the Trace tab
Copyright © 2006 ARM Limited. All rights reserved.ARM DUI 0335A
Non-Confidential