Debug Application Project
Using the Standalone Debug Flow
The Vitis IDE lets you open the debug tool for projects that have been built using the command line flow.
Launching Standalone Debug for Embedded Platforms
The standalone debug flow supports both the embedded processor
application acceleration flow (embedded_accel
) or
the embedded processor software development flow (embedded
). For embedded platforms, the application is running on the
Arm processor of the device, the files
that are required to boot the system, and load the application and kernel, are on a
remote system, but the debug tools are running on the local system, and the data and
reports generated need to be moved from the embedded system to the local system. The
process for debugging in that environment requires more setup and configuration.
Running standalone debug in
the Vitis IDE for the embedded_accel
flow is a two-step process.
- You must first launch the QEMU emulator environment using the
launch_sw_emu.sh or the launch_hw_emu.sh script, that is generated
during the
--package
process. - Then you must launch the Vitis IDE in standalone debug mode using the
-debug
option.
To run standalone debug in the Vitis IDE for the embedded
flow,
you must first launch the QEMU emulator environment using the launch_hw_emu.sh script, that is generated during
the --package
process.
The files required for emulation of the system are also defined by
the --package
command. This means that launching
the standalone debug process for embedded platforms is reliant on the output of the
package process, including the emulation script. An example command to launch the
emulation environment would include the following.
launch_hw_emu.sh -pid-file emulation.pid -no-reboot -forward-port 1440 1534 \
-enable-debug
Where:
-enable-debug
- Opens two different command shells to launch QEMU and XSIM, and enables the GDB connection to the QEMU shell.
-forward-port
- Forwards the TCP port from target to host for connecting
to the QEMU shell. The QEMU port default is 1440. You can change it if
necessary, for example, to 1446, but you must specify it for both the
launch_emulation
command or script and in thevitis -debug
command line. Also, there is support for multiple forward ports enabled. For example,launch_sw_emu.sh -forward-port
1440 1534-forward-port
9455 1560. -no-reboot
- Exit the QEMU environment when done.
-pid-file
- Write the process ID to the specified file, used to kill the process, if necessary.
For hardware emulation, this launches two terminal windows running the QEMU system mode, and the Vivado simulator for simulating the PL kernel.
After the terminals and emulation are up and running, you can launch the Vitis IDE in standalone debug mode in a separate command shell:
vitis -debug -flow embedded_accel -target hw_emu -exe vadd.elf \
-program-args vadd.xclbin -kernels vadd
Where:
vitis -debug
- Launches the Vitis IDE in standalone debug mode.
-flow embedded_accel
- Specifies the application acceleration flow on an embedded processor platform.
-target hw_emu
- Indicates the target build being debugged.
-exe vadd.elf
- Indicates the executable application to run and debug.
-program-args vadd.xclbin
- Specifies the .xclbin file to be loaded as an argument to the executable.
The default for embedded systems
searches for the executable and the .xclbin
file, and any other required input files, on the /mnt folder of the emulation environment, or the embedded system.
You can change this by specifying the -target-work-dir
when launching the tool. This launches the Vitis IDE with the Debug perspective enabled, running a
debug configuration for the specified executable application and kernel code. From
this point you can do all the debug activities like step in/step over/viewing
variables/adding break points within the GUI-based debug environment.
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.
- Create a sample Hello World project.
- Select the application and click
Linux Application Debugging with System Debugger
- Launch the Vitis software platform.
- Create a Linux application.
- Select the application you want to debug.
- Right-click on the application and select .
- Click Launch on Hardware (Single Application Debug) to create a new configuration.
- In the Debug Configuration view:
- Click the Target Setup view.
- From the Debug Type drop-down list, select Linux Application Debug.
- Provide the Linux host name or IP address in the Host Name field.
- 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.
- In the Application Page, click Browse and select the project name. The
Vitis software platform
automatically fills the information in the application.
- In the Remote File Path field, specify the path where
you want to download the application in Linux.
- If your application is expecting some arguments,
specify them in the Arguments view.
- If your application is expecting to set some
environment variables, specify them in the Environments view.
- Click the Debug
button. A separate console automatically opens for process standard I/O
operations.
- 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?
- In the Application view of System Debugger, leave the Project Name and Local File Path fields empty.
- 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.
- Compile the kernel source using the following configuration options:
CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_INFO=y
- Launch the Vitis software platform.
- Click .
- Right-click on the application and select .
- In the Debug Configurations page, select Launch on Hardware (Single Application Debug) and click the New button ().
- Name the configuration Zynq_Linux_Kernel_Debug.
- Debugging begins, with the processors in the running state.
- Click the Pause button to suspend the processor:. Debug starts in the Disassembly mode.
- Add vmlinux symbol files to both processor cores:
- Right-click on ARM Cortex-A9 MPCore#0 and select Symbol Files.
- Click add and add vmlinux symbol files.
- Click OK.
- Right-click on ARM Cortex-A9 MPCore#1 and select Symbol Files.
- Click add and add vmlinux symbol files.
- Click OK.
- You must set up Source Lookup if you built the code on a Linux machine and try to run the debugger on Windows.
- Select the debug configuration Zynq_Linux_Kernel_Debug, then right-click it and select Edit Source Lookup.
- Click Add.
- Select Path Mapping from the Add Source page.
- Add the Compilation path and local file system path by clicking Add.
- Successful source lookup takes you to the source code debug.
- You can add function breakpoints using the Breakpoints view toolbar.
- Add a breakpoint at the
start_kernel
function. - 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
- Launch the Vitis software platform.
- Create a standalone application project. Alternatively, you can also select an existing project.
- Select .
- Double-click Launch on Emulator (Single Application
Debug) and select the Emulation check
box on the Main Page to create a new configuration. Note: Only hardware platforms based on Zynq and Zynq UltraScale+ MPSoC can be selected for standalone application debugging.
- In the Debug Configuration page:
- If your application is expecting some arguments, specify them in the Arguments view.
- If your application is expecting to set some environment variables, specify them in the Environments view.
- Click Debug.
- You can also launch the Emulation Console by selecting
qemu%
prompt. Output is displayed in the area above the input text.
. 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
Debugging an Application on Hardware Using GDB
- Create the application project and build it.
- Right-click on the application project and select to launch the Application debug on GDB.
- Select the Debug configuration and customize the options when debugging as
shown in the following figure.
Debugging an Application on the Emulator (QEMU)
- Create the application project and build it.
- Right-click the application project and select
This opens a pop-up window.
. - Click Start Emulator and Debug.
Running and Debugging Applications under a System Project Together
- Right-click the system project in the Explorer view, select Run as or Debug as, then select Launch on Hardware (System Project Debug).
- Double-click the XSCT Console view at the bottom right
of the IDE to see the detailed commands and logs.
Using a Remote Host with System Debugger
-
Setting Up the Remote System Environment
- 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
- Make sure your board is correctly connected.
- In a cmd window of the host machine, check the IP Address:
- 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:
- Setting Up the Local System for Remote Debug:
- Launch the Vitis software platform.
- Select the application to debug remotely.
- Select .
- Create a new system debugger configuration.
- In the Target Setup view, click New to create a new target
connection.
- In the New Target Connection wizard, add the required details for the remote host that is connected to the target.
- Target Name: Type a name for the target.
- Host: IP address or name of the host machine.
- Port: Port on which the hardware server was launched, such as 3121.
- 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.
- Click OK.
- Now you can see that there are two available connections. In this case,
remote_zc702_1 is the remote connection.
- Select or add the remaining debug configuration details and click Debug.
Exporting Registers from the Vitis IDE
- Create an embedded application project and build it. See Applications for more details about application projects.
- After building the project, launch the debugger. You can debug using System Debugger, or by using the emulator.
- When the program stops at the main breakpoint, click Step Over to move to the required point for debug.
- Click Export Registers.
- Add the following information in the view that appears:
- Location
- Provide the location where you want to save the register dump file.
- Command
- This is based on the selection in the debug perspective.
- Select registers/groups to export
- Select the list of registers to be dumped. You can uncheck any registers that are not required.
- Click OK to dump the registers to the location you specified in the previous step.
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.
For practical use cases and more details about OS aware debugging, see the Vitis Embedded Software Debugging Guide (UG1515).
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.
-
Compile the kernel source using the following configuration options:
CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_INFO=y
- Launch the Vitis software platform.
- Click .
- Click .
- In the Debug Configurations page, select Single Application Debug and click the New button ().
- Click Debug.
- Debugging begins, with the processors in the running state.
- Select the Enable Linux OS Awareness option from the Debug view in the processor context.
-
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.
- 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.
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()
:
- Select a project in the Project Explorer view.
- Select . The Debug Configurations view appears.
- Click the Path Map view 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.
- 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 themain()
function is found in the symbols. - Run the application from the terminal.
- As soon as the control hits a breakpoint, the Debug view is updated with the information of the process.
- 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.
- 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:
- Select a project in the Project Explorer view.
- Select . The Debug Configurations view appears.
- Click the Path Map view to set the path mappings for the selected debug configuration.
- Click Add to insert the kernel module.
- 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.
- 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).
- Launch the Vitis IDE.
- Select .
- Select .
- In the Debug Configurations page, select Launch on Hardware (Single Application Debug).
- Click New ().
- Select Attach to running target debug type and click Debug. Debugging begins with the processors in the running state.
- Right click Cortex-A53 #0 target and select Symbol Files.
- Select the symbol file (xen-syms).
- Select the OS awareness checkbox.
Debugging Hypervisor
- Boot Xen and Dom-0. For details on how to boot Xen and Dom-0, refer to PetaLinux Tools Documentation: Reference Guide (UG1144).
- 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.
- 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).
- 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. - Add a breakpoint or suspend the core. As soon as the breakpoint is hit, the debug view is updated with all the information.
- 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
- Boot Xen and Dom-0. For details on how to boot Xen and Dom-0, refer to PetaLinux Tools Documentation: Reference Guide (UG1144).
- 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.
-
Debug Dom-0 kernel.
- 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.
- 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.
- Debug the Dom-U Kernel:
- Copy the guest Linux images to Dom-0 file system.
- Create a Dom-U guest.
- 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.
- 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
- Boot Xen and Dom-0. For details on how to boot Xen and Dom-0, refer to PetaLinux Tools Documentation: Reference Guide (UG1144).
- 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.
- Create a Linux application project. For details on how to create a Linux application project, refer Creating a Linux Application Project.
- 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).
-
Configure Dom-U user space process.
- Copy the guest Linux images to Dom-0 file system.
-
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' ]
- 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).
- 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 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.
- Update the system debugger launch configuration to provide the
address to which program sections are relocated.
- Select to launch the system debugger launch configuration.
- Click the Application view and select the application you wish to download.
- Select the This is a self-relocating application checkbox.
- Enter the address where all the program sections are to be relocated in the Relative address to which the program sections are relocated textbox.
- 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 view of the debug configuration. - 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
Debugging an Application Project Using the Emulator (Command-Line Flow)
The Vitis tool supports both a GUI and a command-line flow to debug embedded applications. This section explains how to debug an embedded application from the command line using the emulator.
- Source the Vitis settings.csh/settings.sh file.
- Launch XSCT and create an embedded application project.
- Build the application project and make sure the ELF file is generated successfully.
- Open the new terminal and move to the application project debug directory.
- Execute the following command to start the
QEMU/emulation:
launch_emulator -device-family 7series -pid-file emulation.pid -t sw_emu -gdb-port 1137
Note:- For Zynq devices,
the
-device-family
argument is7series
. - For Zynq
UltraScale devices, the
-device-family
argument isUltrascale
. - For Versal ACAP, the
-device-family
argument isversal
.
- For Zynq devices,
the
- Open another terminal and run the following command to start the
xrt_server
:xrt_server -I100 -S -s tcp::4352
- Open XSCT and try to connect to the emulation target using the following
command:
gdbremote connect localhost:1137
- Run the
targets
command to see the list of targets present in this particular connection. - Download the ELF file and proceed with further debugging.