Debug Application Project

System Debugger Supported Design Flows

Standalone Application Debug Using Xilinx System Debugger

This topic describes how to use the Xilinx System Debugger to debug bare-metal applications.

  1. Create a sample Hello World project.
  2. Select the application and click Run > Debug As > Launch On Hardware (Single Application Debug).

Linux Application Debugging with System Debugger

  1. Launch the Vitis software platform.
  2. Create a Linux application.
  3. Select the application you want to debug.
  4. Right-click on the application and select Debug As > Debug Configuration.
  5. Click Launch on Hardware (Single Application Debug) to create a new configuration.
  6. In the Debug Configuration window:
    1. Click the Target Setup tab.
    2. From the Debug Type drop-down list, select Linux Application Debug.
    3. Provide the Linux host name or IP address in the Host Name field.
    4. By default, tcf-agent runs on the 1534 port on the Linux. If you are running tcf-agent on a different port, update the Port field with the correct port number.
    5. In the Application Tab, click Browse and select the project name. The Vitis software platform automatically fills the information in the application.

    6. In the Remote File Path field, specify the path where you want to download the application in Linux.

    7. If your application is expecting some arguments, specify them in the Arguments tab.

    8. If your application is expecting to set some environment variables, specify them in the Environments tab.

    9. Click the Debug button. A separate console automatically opens for process standard I/O operations.



    10. Click the Terminate button to terminate the application.

Troubleshooting

My application already exists in the Linux target. How can I tell System Debugger to use my existing application, instead of downloading the application?
  1. In the Application tab of System Debugger, leave the Project Name and Local File Path fields empty.
  2. In the Remote File Path field, specify the remote application path and click the Debug button. System debugger loads the specified application.

Attach and Debug using Xilinx System Debugger

It is possible to debug the Linux kernel using Xilinx System Debugger. Follow the steps below to attach to the Linux kernel running on the target and to debug the source code.

  1. Compile the kernel source using the following configuration options:
    CONFIG_DEBUG_KERNEL=y
    CONFIG_DEBUG_INFO=y
  2. Launch the Vitis software platform.
  3. Click Window > Open Perspective > Debug.
  4. Right-click on the application and select Debug As > Debug Configuration.
  5. In the Debug Configurations dialog box, select Launch on Hardware (Single Application Debug) and click the New button ().
  6. Name the configuration Zynq_Linux_Kernel_Debug.
  7. Debugging begins, with the processors in the running state.
  8. Click the Pause button to suspend the processor:. Debug starts in the Disassembly mode.
  9. Add vmlinux symbol files to both processor cores:
    1. Right-click on ARM Cortex-A9 MPCore#0 and select Symbol Files.
    2. Click add and add vmlinux symbol files.
    3. Click OK.
    4. Right-click on ARM Cortex-A9 MPCore#1 and select Symbol Files.
    5. Click add and add vmlinux symbol files.
    6. Click OK.
  10. You must set up Source Lookup if you built the code on a Linux machine and try to run the debugger on Windows.
  11. Select the debug configuration Zynq_Linux_Kernel_Debug, then right-click it and select Edit Source Lookup.
  12. Click Add.
  13. Select Path Mapping from the Add Source dialog box.
  14. Add the Compilation path and local file system path by clicking Add.
  15. Successful source lookup takes you to the source code debug.
  16. You can add function breakpoints using the Breakpoints view toolbar.
  17. Add a breakpoint at the start_kernel function.
  18. Click the reset button. The Zynq-7000 SoC processor boots from the SD card and stops at the beginning of the kernel initialization.
    Note: The Linux kernel is always compiled with full optimizations and in-lining enabled. Therefore, stepping through code might not work as expected due to the possible reordering of some instructions. Furthermore, some variables might be optimized out by the compiler and consequently might not be available for the debugger.

Standalone Application Debug using System Debugger on QEMU

  1. Launch the Vitis software platform.
  2. Create a standalone application project. Alternatively, you can also select an existing project.
  3. Select Debug As > Debug Configurations.
  4. Double-click Launch on Emulator (Single Application Debug) and select the Emulation check box on the Main Tab to create a new configuration.
    Note: Only hardware platforms based on Zynq UltraScale+ MPSoC can be selected for standalone application debugging.


  5. In the Debug Configuration dialog box:
    1. If your application is expecting some arguments, specify them in the Arguments tab page.
    2. If your application is expecting to set some environment variables, specify them in the Environments tab page.
  6. Click Debug.
  7. You can also launch the Emulation Console by selecting Window > Show View > Other. The Emulation Console can be used to interact with the program running on QEMU. The STDIN can be provided in the input box at the qemu% prompt. Output is displayed in the area above the input text.

Multi-Processor Debugging with System Debugger

You can debug multiple processors simultaneously with a single System Debugger debug configuration.

  1. Create application projects for the processors included in the design.
  2. Select any application and click Debug As > Debug Configurations.
  3. In the Debug Configurations window, left panel, select the configuration type (Single Application Debug) and click the New button: .
  4. Name the configuration Multi_Processor_ZC706_Debug.
  5. In the Target Setup tab, select the appropriate setup.
  6. Select the Standalone Application Debug from the Debug Type dropdown list.
  7. Select the target you want to connect. With this selection, no resets or initializations are performed on the target before launching the debugger.
  8. To automatically populate bitstream and initialization files, from the Hardware platform drop-down list, select the appropriate hardware platform. Use the Browse buttons if you wish to select different bitstream and initialization files.

  9. If you want to reset the entire system, enable the Reset entire system checkbox in the Debug Configurations window.
  10. If you want to program the bitstream after system reset, enable the Program FPGA checkbox.
  11. Enable the Run ps7_init checkbox to run the PS initialization file.
    Note: The Summary window displays a summary of System Debugger operations.
  12. Select the Applications tab to display all processors available to the selected hardware platform.
  13. Select the Download Application checkbox if you want to download the application to the selected processor.
    Note: If a single project exists for the processor, the Project Name and Application Name fields populate automatically when you select the Download Application checkbox. If more than one project exists for the processor, you must make the Project Name selection manually.
  14. Select the Stop at program entry checkbox if you want to stop the processor before application main().
  15. Click the Debug button to launch multi-processor debugging.

Using a Remote Host with System Debugger

  1. Setting Up the Remote System Environment
    1. Running the hw_server with non-default port (for example: 3122) enables remote connections. Use the following command to launch the hw_server on port 3122:
          the hw_server -s TCP::3122
    2. Make sure your board is correctly connected.
    3. In a cmd window of the host machine, check the IP Address:

  2. Setting Up the Local System for Remote Debug:
    1. Launch the Vitis software platform.
    2. Select the application to debug remotely.
    3. Select Debug As > Debug Configurations.
    4. Create a new system debugger configuration.
    5. In the Target Setup tab, click New to create a new target connection.

    6. In the New Target Connection dialog box, add the required details for the remote host that is connected to the target.
    7. Target Name: Type a name for the target.
    8. Host: IP address or name of the host machine.
    9. Port: Port on which the hardware server was launched, such as 3121.
    10. Select Use Symbol Server to ensure that the source code view is available, during debugging the application remotely. Symbol server acts as a mediator between hardware server and the Vitis software platform.
    11. Click OK.
    12. Now you can see that there are two available connections. In this case, remote_zc702_1 is the remote connection.

    13. Select or add the remaining debug configuration details and click Debug.

OS Aware Debugging

OS aware debug over JTAG helps in visualizing OS specific information such as processes or threads that are currently running, process or thread specific stack trace, registers, variables view. By enabling the OS awareness, you can debug the OS running on the processor cores and the processes or the threads running on the OS simultaneously.

Enabling OS Aware Debug

This section describes setting up OS aware debug for a Zynq board running Linux from an SD card, using the Vitis IDE. It is assumed that users are aware of setting up a Jtag connection to the board, building Linux kernel and booting it from an SD card. For details on how to set up the kernel debug, refer to Attach and Debug using Xilinx System Debugger.

  1. Compile the kernel source using the following configuration options:
    CONFIG_DEBUG_KERNEL=y
    CONFIG_DEBUG_INFO=y
  2. Launch the Vitis software platform.
  3. Click Window > Open Perspective > Debug.
  4. Click Debug As > Debug Configurations.
  5. In the Debug Configurations dialog box, select Single Application Debug and click the New button ().
  6. Click Debug.
  7. Debugging begins, with the processors in the running state.
  8. Select the Enable Linux OS Awareness option from the Debug view in the processor context.
  9. You can also perform the following actions from the menu that appears.
    • Refresh OSA Processes: Select this option to refresh the list of running processes.
    • Auto refresh on exec: When selected, all the running processes are refreshed and seen in the Debug view. When not selected, new processes are not visible in the debug view.
    • Auto refresh on suspend: When selected, all the processes will be re-synced whenever the processor suspends. When not selected, only the current process is re-synced.
    • Linux OSA File Selection: Select this option to change the symbol file.
  10. Alternatively, OS aware debugging can also be enabled using the -osa command in the Xilinx System Debugger (XSDB) command-line console.
    osa -file <symbol-file> -fast-step -fast-exec

Process/Thread Level Debugging

The Debug view is updated with the list of processes running on the Linux kernel, when the OS aware debugging is enabled. For details on how to enable OS aware debugging, refer to Enabling OS Aware Debug. The processes list is updated for the first time when the processor core is halted and is updated dynamically thereafter (new processes are added to the list and terminated processes are removed).

A process context can be expanded to see the threads that are part of the process.



Symbol files can be added for a process context to enable source level debugging and see stack trace variables. Source level breakpoints can also be set. Alternatively, the source level debugging can be enabled by setting the Path Map. The debugger uses the Path Map setting to search and load symbols files for all executable files and shared libraries in the system.

Note: Path Map is used for both symbols and source lookups.

Debugging a Process from main()

To debug a new process from main(), a global breakpoint (not against any particular target/context) should be set, before starting the process. Symbol files are loaded based on path map settings, so there should be a corresponding entry for the new process before starting it.

To debug a process from main():

  1. Select a project in the Project Explorer view.
  2. Select Debug As > Debug Configurations. The Debug Configurations window appears.
  3. Click the Path Map tab to set the path mappings for the selected debug configuration. Path maps help enable source level debugging. The debugger uses Path Map setting to search and load symbols files for all executable files and shared libraries in the system.
  4. Set either the line breakpoint in the source file of the Linux application or function breakpoint at main(). Every time a new process starts, the debugger checks symbols of the process and plants the breakpoint in the process if the source file or the main() function is found in the symbols.
  5. Run the application from the terminal.
  6. As soon as the control hits a breakpoint, the Debug view is updated with the information of the process.
  7. The Debug view also shows the file, function and the line information of the breakpoint hit. A thread label includes the name of the CPU core, if the thread is currently running on a core.
  8. Source level debugging such as stepping in, stepping out, watching variables, stack trace can be performed. The target side path for a binary file does not include a mount point path. This is a known limitation. For example, when the process is located on the SD card, which is mounted at /mnt, the debugger shows the file as <filename> and not as the expected /mnt/<filename>.

Debugging a Loadable Kernel Module

To debug a kernel module, set path mapping to map the module name to symbol file of the module. To see loaded modules, select Kernel in the Debug view, and look at the Modules view. Kernel modules are listed by name and not by the file path.

To debug a kernel module:

  1. Select a project in the Project Explorer view.
  2. Select Debug As > Debug Configurations. The Debug Configurations window appears.
  3. Click the Path Map tab to set the path mappings for the selected debug configuration.
  4. Click Add to insert the kernel module.
  5. Insert a function or line breakpoint and run the core. As soon as the breakpoint is hit, the debug view is updated with all the information.
  6. Similar to any other process or thread level debugging, you can insert breakpoints, step in, step out, watch variables, stack trace or perform other source level debugging tasks.

Xen Aware Debugging

Xen aware debug helps users in visualizing the hypervisor specific information such as different domains (Dom-0 and Dom-Us), virtual processors (VCPUs) on each domain.

This feature enables debugging following Xen components:

  • Hypervisor
  • Dom-0/Dom-U kernel
  • Dom-0/Dom-U user space processes
  • Dom-U standalone applications

Enabling Xen Awareness

This section describes setting up the Xen aware debug for Zynq UltraScale+ MPSoC devices running Linux from SD card, using the Vitis IDE. It is assumed that the following prerequisites have been satisfied:

  • You have the ZCU102 board running a Xen and Dom-0.
  • You have the Xen symbol file (xen-syms).
For details on how to boot Xen and Dom-0, refer to PetaLinux Tools Documentation: Reference Guide (UG1144).
  1. Launch the Vitis IDE.
  2. Select Window > Open Perspective > Debug.
  3. Select Debug As > Debug Configurations.
  4. In the Debug Configurations dialog box, select Launch on Hardware (Single Application Debug).
  5. Click New ().
  6. Select Attach to running target debug type and click Debug. Debugging begins with the processors in the running state.
  7. Right click Cortex-A53 #0 target and select Symbol Files.
  8. Select the symbol file (xen-syms).
  9. Select the OS awareness checkbox.

Debugging Hypervisor

  1. Boot Xen and Dom-0. For details on how to boot Xen and Dom-0, refer to PetaLinux Tools Documentation: Reference Guide (UG1144).
  2. Enable Xen awareness by enabling OS aware debug for Xen symbol file. Symbol files are added to a process context to enable source level debugging. For details on how to enable Xen awareness, refer to Enabling Xen Awareness.
  3. The Debug view is updated with the list of processes running on the Linux kernel when OS-aware debugging is enabled. The processes list is updated for the first time when the processor core is halted, and is updated dynamically thereafter (new processes are added to the list and terminated processes are removed).
  4. Click Edit Source Lookup Path to set the path mappings for the selected debug configuration. The debugger uses path map to search and load symbols files for all executable files and shared libraries in the system.

    Note: Path Map is used for both symbols and source lookups.
  5. Add a breakpoint or suspend the core. As soon as the breakpoint is hit, the debug view is updated with all the information.
  6. You can now insert breakpoints, step in, step out, watch variables, stack trace or perform other source level debugging tasks.

Debugging a Dom-0/Dom-U Kernel

  1. Boot Xen and Dom-0. For details on how to boot Xen and Dom-0, refer to PetaLinux Tools Documentation: Reference Guide (UG1144).
  2. Enable Xen awareness by enabling OS aware debug for Xen symbol file. Symbol files are added to a process context to enable source level debugging. For details on how to enable Xen awareness, refer to Enabling Xen Awareness.
  3. Debug Dom-0 kernel.
    1. Enable OS awareness on the Linux symbol file in the Debug view for Dom-0 VCPU context. For details on OS aware debug, refer to OS Aware Debugging.
    2. Suspend the Dom-0 VCPU#0 core. You can now insert breakpoints, step in, step out, watch variables, stack trace or perform other source level debugging tasks.

  4. Debug the Dom-U Kernel:
    1. Copy the guest Linux images to Dom-0 file system.
    2. Create a Dom-U guest.
    3. Enable OS awareness on the Linux symbol file in the Debug view for Dom-U VCPU context. For details on OS aware debug, refer OS Aware Debugging.
    4. Suspend the Dom-U VCPU#0 core. You can now insert breakpoints, step in, step out, watch variables, stack trace or perform other source level debugging tasks.

Debugging Dom-0/Dom-U User Space Processes

  1. Boot Xen and Dom-0. For details on how to boot Xen and Dom-0, refer to PetaLinux Tools Documentation: Reference Guide (UG1144).
  2. Enable Xen awareness by enabling OS aware debug for Xen symbol file. Symbol files are added to a process context to enable source level debugging. For details on how to enable Xen awareness, refer to Enabling Xen Awareness.
  3. Create a Linux application project. For details on how to create a Linux application project, refer Creating a Linux Application Project.
  4. Configure the Dom-0 user space process by adding the symbol file of the application running on Linux for the debug context of the virtual CPU (VCPU#) of the host domain (Dom-0).
  5. Configure Dom-U user space process.
    1. Copy the guest Linux images to Dom-0 file system.
    2. Create the Linux guests with para-virtual networking.
          name = "guest 0"
          kernel = "/boot/Image"
          extra = "console=hvc0 rdinit=/sbin/init"
          memory = 256
          vcpus = 2
          vif = [ 'bridge=xenbr0' ]
    3. Add the symbol file of the application running on Linux for the debug context of the virtual cpu (VCPU#) of the guest domain (Dom-U).
  6. When the symbol files are set, you can insert breakpoints, step in, step out, watch variables, stack trace or perform other source level debugging tasks.

Debugging a Dom-U Standalone Application

  1. Create a new standalone hypervisor guest application.
    1. Click File > New > Application Project. The New Application Project dialog box appears.
      Note: This is equivalent to clicking on File > New > Project to open the New Project wizard, selecting Xilinx > Application Project, and clicking Next.
    2. Type a project name into the Project Name field.
    3. Select the location for the project. You can use the default location as displayed in the Location field by leaving the Use default location check box selected. Otherwise, click the check box and type or browse to the directory location.
    4. The OS Platform allows you to select which operating system you will be writing code for. Select standalone.
      Note: This selection alters what templates you view in the next screen and what supporting code is provided in your project.
    5. In platform selection window, select Create a New Platform from Hardware (XSA). Select zcu102 design and click Next to proceed.
    6. Choose the preferred CPU and OS.
    7. Click Next to advance to the Templates screen
    8. From the Hypervisor Guest drop-down list, select Yes to create an application with a pre-defined linker script suitable to run the Xen.
    9. Specify a board support package or domain. You can create a new customizable domain, or select an existing domain. The domain created by the wizard will have the hypervisor_guest parameter set to true. It will also ensure that the stdin and stdout are pointing to psu_uart_1.
    10. Click Next to advance to the Templates screen.
    11. The Vitis software platform provides useful sample applications listed in Templates dialog box that you can use to create your project. The Description box displays a brief description of the selected sample application. When you use a sample application for your project, the Vitis software platform creates the required source and header files and linker script.
    12. Select the desired template. If you want to create a blank project, select the Empty Application. You can then add C files to the project, after the project is created.
    13. Click Finish to create your application project and board support package (if it does not exist).
      Note: Xilinx recommends that you use Managed Make flow rather than Standard Make C/C++ unless you are comfortable working with make files.
  2. Build the newly created hypervisor guest standalone application to generate a .bin file. This file is needed to work with Xen.
  3. Boot Xen and Dom-0. For details on how to boot Xen and Dom-0, refer to PetaLinux Tools Documentation: Reference Guide (UG1144).
  4. Enable Xen awareness by enabling OS aware debug for Xen symbol file. Symbol files are added to a process context to enable source level debugging. For details on how to enable Xen awareness, refer to Enabling Xen Awareness.
  5. Copy the application to Dom-0 file system.
  6. Create the guest domain hello using the Xen configuration file.
        name = "hello"
        kernel = "/boot/hello.bin"
        memory = 8
        vcpus = 1
        cpus = [1]
        irqs = [ 54 ]
        iomem = [ "0xff010,1" ]
  7. Suspend the Dom-U VCPU#0 core. You can now insert breakpoints, step in, step out, watch variables, stack trace, or perform other source level debugging tasks.

Debugging Self-Relocating Programs

System debugger supports source level debugging of self-relocating programs such as U-boot. A self-relocating program is a program which relocates its own code and data sections during runtime. The debug information available in such files does not provide details about where the program sections have been relocated. For this reason, you must supply to the debugger the address where the program sections have been relocated. This can be done in two ways.

  1. Update the system debugger launch configuration to provide the address to which program sections are relocated.
    1. Select Debug As > Debug Configurations to launch the system debugger launch configuration.
    2. Click the Application tab and select the application you wish to download.
    3. Select the This is a self-relocating application checkbox.
    4. Enter the address where all the program sections are to be relocated in the Relative address to which the program sections are relocated textbox.
    5. Launch the debug configuration. When the program sections are relocated during runtime, the debugger will have enough information to support source level debugging of the relocated sections.

    Note: This method is supported only when the Debug Type is set to Standalone' in the Target Setup tab of the debug configuration.
  2. Alternatively, you can also use the memmap command in XSDB to provide the address where the program sections are relocated. memmap command in XSDB can be used to add symbol files to the debugger. This is useful for debugging the applications which are already running on the target. For example, boot from flash. In case of relocatable ELF files, you can use the -relocate-section-map option, to provide the relocation address.
    xsdb% targets 2
     1 APU
       2 ARM Cortex-A9 MPCore #0 (Suspended)
       3 ARM Cortex-A9 MPCore #1 (Suspended)
     4 xc7z020
    xsdb% targets 2
    xsdb% memmap -reloc 0x3bf37000 -file u-boot
    
    xsdb% stop
    Info: ARM Cortex-A9 MPCore #0 (target 2) Stopped at 0x3ff7b478 (Suspended)
    xsdb% bt
     0 0x3ff7b478 __udelay()+1005809800: lib/time.c, line 91
     1 0x3ff7b4ac udelay()+1005809696: lib/time.c, line 104
     2 0x3ff5d878 genphy_update_link()+1005809860: drivers/net/phy/phy.c, line 250
     3 0x3ff5df84 m88e1118_startup()+1005809712: drivers/net/phy/marvell.c, line 356
     4 0x3ff5d154 zynq_gem_init()+1005810192: drivers/net/zynq_gem.c, line 402
     5 0x3ff7dc58 eth_init()+1005809720: net/eth.c, line 886
     6 0x3ff7e0e4 net_loop()+1005809728: net/net.c, line 407
     7 0x3ff46330 netboot_common()+1005809972: common/cmd_net.c, line 230
     8 0x3ff46520 do_tftpb()+1005809708: common/cmd_net.c, line 33
     9 0x3ff5295c cmd_process()+1005809824: common/command.c, line 493
     10 0x3ff5295c cmd_process()+1005809824: common/command.c, line 493
     11 0x3ff3b710 run_list_real()+1005811444: common/cli_hush.c, line 1656
     12 0x3ff3b710 run_list_real()+1005811444: common/cli_hush.c, line 1656
     13 0x3ff3be3c parse_stream_outer()+1005811244: common/cli_hush.c, line 2003
     14 0x3ff3be3c parse_stream_outer()+1005811244: common/cli_hush.c, line 2003
     15 0x3ff3b008 parse_string_outer()+1005809872: common/cli_hush.c, line 3254
     16 0x3ff3b6b8 run_list_real()+1005811356: common/cli_hush.c, line 1617
     17 0x3ff3b6b8 run_list_real()+1005811356: common/cli_hush.c, line 1617
     18 0x3ff3be3c parse_stream_outer()+1005811244: common/cli_hush.c, line 2003
     19 0x3ff3be3c parse_stream_outer()+1005811244: common/cli_hush.c, line 2003
     20 0x3ff3afd0 parse_string_outer()+1005809816: common/cli_hush.c, line 3248
     21 0x3ff5140c do_run()+1005809740: common/cli.c, line 131
     22 0x3ff5295c cmd_process()+1005809824: common/command.c, line 493
     23 0x3ff5295c cmd_process()+1005809824: common/command.c, line 493
     24 0x3ff3b710 run_list_real()+1005811444: common/cli_hush.c, line 1656
     25 0x3ff3b710 run_list_real()+1005811444: common/cli_hush.c, line 1656
     26 0x3ff3be3c parse_stream_outer()+1005811244: common/cli_hush.c, line 2003
     27 0x3ff3be3c parse_stream_outer()+1005811244: common/cli_hush.c, line 2003
     28 0x3ff3b008 parse_string_outer()+1005809872: common/cli_hush.c, line 3254
     29 0x3ff3b6b8 run_list_real()+1005811356: common/cli_hush.c, line 1617
     30 0x3ff3b6b8 run_list_real()+1005811356: common/cli_hush.c, line 1617
     31 0x3ff3be3c parse_stream_outer()+1005811244: common/cli_hush.c, line 2003
     32 0x3ff3be3c parse_stream_outer()+1005811244: common/cli_hush.c, line 2003
     33 0x3ff3afd0 parse_string_outer()+1005809816: common/cli_hush.c, line 3248
     34 0x3ff39ab4 main_loop()+1005809724: common/main.c, line 85
     35 0x3ff3c4f4 run_main_loop()+1005809672: common/board_r.c, line 675
     36 0x3ff73b54 initcall_run_list()+1005809716: lib/initcall.c, line 27
     37 0x3ff3c66c board_init_r()+1005809676: common/board_r.c, line 908
     38 0x3ff3837c clbss_l()+1005809688: arch/arm/lib/crt0.S, line 174
     39 unknown-pc