Debugging Guest Applications with QEMU, XSDB, and XSCT
This page will cover the commands that can be used when debugging a guest application with QEMU and XSDB.
Some content from debugging with GDB will be restated here for convenience.
Some commands will be omitted from this page; the full documentation for XSDB can be found here.
Differences Between Zynq UltraScale+ MPSoC and Versal Adaptive SoC
The examples on this page are done on the Zynq UltraScale+ MPSoC platform.
On Versal Adaptive SoC, the differences are:
- 2 ARM-A72 CPUs instead of 4 ARM-A53 CPUs.
Acquiring the Tools
XSDB is bundled with Vitis and can be downloaded here.
Enabling an XSDB connection to QEMU
QEMU contains a GDB server that you can connect to, allowing you to debug your QEMU application.
To enable connection to the GDB server, you need to pass in a parameter to QEMU that specify the hostname and port it should listen on.
QEMU parameter | Details |
---|---|
-gdb tcp:<hostname>:<port> | Makes QEMU's GDB server listen on host hostname on port port. Generally the hostname is "localhost" and the port can be anything, as long as you can connect to it. |
-gdb tcp:<hostname>:<port> -S | Makes QEMU's GDB server listen on host hostname on port port and makes emulation start in a paused state. To un-pause emulation, connect to QEMU using GDB and use the continue command. |
-gdb tcp:localhost:9000
If booting QEMU using Petalinux, the primary machine will typically listen on localhost:9000
.
For example, if booting a ZCU102 machine using Petalinux, the ARM machine will listen on localhost:9000
, while the Microblaze machine will not have remote debugging enabled.
To simultaneously debug both Microblaze and ARM machines in a multi-arch environment, you must build QEMU from source.
Once built from source, pass in the -gdb
argument for each machine when booting QEMU.
Connecting XSDB to QEMU
XSDB Command | Details |
---|---|
gdbremote connect <hostname>:<port> | Connects to a GDB remote server with host hostname and port port. |
gdbremote disconnect | Disconnects from a GDB remote server. |
exit | Exits XSDB |
xsdb% gdbremote connect :9000 attempting to launch tcfgdbclient xsdb% Info: Cortex-A53 #0 (target 3) Stopped at 0xffffff80086824a0 (Suspended) xsdb% Info: Cortex-A53 #1 (target 4) Stopped at 0xffffff8008112eb4 (Suspended) xsdb% Info: Cortex-A53 #2 (target 5) Stopped at 0xffffff8008112eb4 (Suspended) xsdb% Info: Cortex-A53 #3 (target 6) Stopped at 0xffffff8008112eb4 (Suspended) xsdb% Info: Cortex-R5 #0 (target 8) Stopped at 0xffff0000 (Suspended) xsdb% Info: Cortex-R5 #1 (target 9) Stopped at 0xffff0000 (Suspended)
Loading Debugging Symbols
XSDB requires symbols from the program being executed, otherwise it won't know anything about the program and won't be able to debug.
XSDB Command | Details |
---|---|
memmap -file <file.elf> | Loads the symbols from file.elf into XSDB. If file.elf does not contain debugging symbols, it must be recompiled with the -g flag passed into gcc. |
xsdb% memmap -file test-arm.elf xsdb%
Connecting to a Target
XSDB Command | Details |
---|---|
target [id] | Lists all available targets. If id is specified, XSDB connects to target id. |
xsdb% ta 1 GdbClient (127.0.0.1:9000) 2 p1 3* Cortex-A53 #0 (Suspended) 4 Cortex-A53 #1 (Suspended) 5 Cortex-A53 #2 (Suspended) 6 Cortex-A53 #3 (Suspended) 7 p2 8 Cortex-R5 #0 (Suspended) 9 Cortex-R5 #1 (Suspended) xsdb% ta 3
Controlling Execution
XSDB Command | Details |
---|---|
state | Gives the current execution state. |
stop | Stops execution. |
con | Resumes execution. |
stp [count] | Steps through one line of your program. If count is specified, it will go step through count lines. This will go inside functions, including library functions. |
nxt [count] | Steps through one line of your program. |
stpi [count] | Steps through one instruction of your program. If count is specified, it will go step through count lines. This will go inside functions, including library functions. |
nxti [count] | Steps through one instruction of your program. |
stpout [count] | Executes until the end of the current function. If count is specified, this will be repeated count times. |
xsdb% Info: Cortex-A53 #0 (target 3) Stopped at 0x400730 (Breakpoint) main() at test.c: 22 22: { xsdb% Info: Cortex-A53 #1 (target 4) Stopped at 0xffffff8008802be8 (Suspended) xsdb% Info: Cortex-A53 #2 (target 5) Stopped at 0xffffff8008112eb4 (Suspended) xsdb% Info: Cortex-A53 #3 (target 6) Stopped at 0xffffff8008101aac (Suspended) xsdb% Info: Cortex-R5 #0 (target 8) Stopped at 0xffff0000 (Suspended) xsdb% Info: Cortex-R5 #1 (target 9) Stopped at 0xffff0000 (Suspended) xsdb% nxt Info: Cortex-A53 #0 (target 3) Stopped at 0x40074c (Step) 25: foo(&s); Info: Cortex-A53 #1 (target 4) Stopped at 0xffffff800809da98 (Suspended) Info: Cortex-A53 #2 (target 5) Stopped at 0xffffff80087d82a8 (Suspended) Info: Cortex-A53 #3 (target 6) Stopped at 0xffffff8008103fe8 (Suspended) Info: Cortex-R5 #0 (target 8) Stopped at 0xffff0000 (Suspended) Info: Cortex-R5 #1 (target 9) Stopped at 0xffff0000 (Suspended) xsdb% stp Info: Cortex-A53 #0 (target 3) Stopped at 0x400780 (Breakpoint) foo() at test.c: 31 31: { Info: Cortex-A53 #1 (target 4) Stopped at 0xffffff800809da98 (Suspended) Info: Cortex-A53 #2 (target 5) Stopped at 0xffffff80087d82a8 (Suspended) Info: Cortex-A53 #3 (target 6) Stopped at 0xffffff8008103fe8 (Suspended) Info: Cortex-R5 #0 (target 8) Stopped at 0xffff0000 (Suspended) Info: Cortex-R5 #1 (target 9) Stopped at 0xffff0000 (Suspended) xsdb% nxt 3 Info: Cortex-A53 #0 (target 3) Stopped at 0x4007b0 (Step) 34: s->var = 1234; Info: Cortex-A53 #1 (target 4) Stopped at 0xffffff8008113ed8 (Suspended) Info: Cortex-A53 #2 (target 5) Stopped at 0xffffff80087d7a90 (Suspended) Info: Cortex-A53 #3 (target 6) Stopped at 0xffffff8008113458 (Suspended) Info: Cortex-R5 #0 (target 8) Stopped at 0xffff0000 (Suspended) Info: Cortex-R5 #1 (target 9) Stopped at 0xffff0000 (Suspended) xsdb% nxt Info: Cortex-A53 #0 (target 3) Stopped at 0x4007bc (Step) 36: global_var = 0xCC33CC33; Info: Cortex-A53 #1 (target 4) Stopped at 0xffffff80087d7954 (Suspended) Info: Cortex-A53 #2 (target 5) Stopped at 0xffffff80087d7b10 (Suspended) Info: Cortex-A53 #3 (target 6) Stopped at 0xffffff8008113458 (Suspended) Info: Cortex-R5 #0 (target 8) Stopped at 0xffff0000 (Suspended) Info: Cortex-R5 #1 (target 9) Stopped at 0xffff0000 (Suspended) xsdb% stpout Info: Cortex-A53 #0 (target 3) Stopped at 0x400754 (Step) main() at test.c: 27 27: return 0; Info: Cortex-A53 #1 (target 4) Stopped at 0xffffff800809da98 (Suspended) Info: Cortex-A53 #2 (target 5) Stopped at 0xffffff8008112eb4 (Suspended) Info: Cortex-A53 #3 (target 6) Stopped at 0xffffff8008112eb4 (Suspended) Info: Cortex-R5 #0 (target 8) Stopped at 0xffff0000 (Suspended) Info: Cortex-R5 #1 (target 9) Stopped at 0xffff0000 (Suspended) xsdb% con Info: Cortex-A53 #0 (target 3) Running Info: Cortex-A53 #1 (target 4) Running Info: Cortex-A53 #2 (target 5) Running Info: Cortex-A53 #3 (target 6) Running Info: Cortex-R5 #0 (target 8) Running Info: Cortex-R5 #1 (target 9) Running xsdb% stop Info: Cortex-A53 #0 (target 3) Stopped at 0xffffff80080ced88 (Suspended) Info: Cortex-A53 #1 (target 4) Stopped at 0xffffff8008802c00 (Suspended) Info: Cortex-A53 #2 (target 5) Stopped at 0xffffff80080817c8 (Suspended) Info: Cortex-A53 #3 (target 6) Stopped at 0xffffff8008112eb4 (Suspended) Info: Cortex-R5 #0 (target 8) Stopped at 0xffff0000 (Suspended) Info: Cortex-R5 #1 (target 9) Stopped at 0xffff0000 (Suspended) xsdb%
Breakpoints and Watchpoints
XSDB Command | Details |
---|---|
bpadd <-addr <addr> | -file <name> -line <lineno>> | Adds a breakpoint to either address addr or line lineno in file name, depending if the -addr or -file option is provided. addr can also be the address of a function. If -target-id is specified, id corresponds to a target ID. If -type is specified, type can be one of the following values:
If -mode is specified, mode is a bitfield that consists of the following values:
If -enable is specified, mode can be one of the following values:
|
bpremove <breakpoints> | -all | Removes each breakpoint in the list breakpoints. If -all is specified, all breakpoints are removed. |
bpenable <breakpoints> | -all | Enables each breakpoint in the list breakpoints. If -all is specified, all breakpoints are enabled. |
bpdisable <breakpoints> | -all | Disables each breakpoint in the list breakpoints. If -all is specified, all breakpoints are disabled. |
bplist | Lists all breakpoints along with the status of each breakpoint. |
bpstatus <id> | Prints the status of breakpoint id. |
xsdb% gdbremote connect :9000 attempting to launch tcfgdbclient xsdb% Info: Cortex-A53 #0 (target 3) Stopped at 0xffffff8008112eb4 (Suspended) xsdb% Info: Cortex-A53 #1 (target 4) Stopped at 0xffffff8008112eb4 (Suspended) xsdb% Info: Cortex-A53 #2 (target 5) Stopped at 0xffffff8008112eb4 (Suspended) xsdb% Info: Cortex-A53 #3 (target 6) Stopped at 0xffffff8008112eb4 (Suspended) xsdb% Info: Cortex-R5 #0 (target 8) Stopped at 0xffff0000 (Suspended) xsdb% Info: Cortex-R5 #1 (target 9) Stopped at 0xffff0000 (Suspended) xsdb% ta 3 xsdb% memmap -file test.elf xsdb% bpadd -addr main 0 xsdb% Info: Breakpoint 0 status: target 3: {Address: 0x400730 Type: Hardware} xsdb% con Info: Cortex-A53 #0 (target 3) Running Info: Cortex-A53 #1 (target 4) Running Info: Cortex-A53 #2 (target 5) Running Info: Cortex-A53 #3 (target 6) Running Info: Cortex-R5 #0 (target 8) Running Info: Cortex-R5 #1 (target 9) Running xsdb% Info: Cortex-A53 #0 (target 3) Stopped at 0x400730 (Breakpoint) main() at test.c: 22 22: { xsdb% Info: Cortex-A53 #1 (target 4) Stopped at 0xffffff8008112eb4 (Suspended) xsdb% Info: Cortex-A53 #2 (target 5) Stopped at 0xffffff8008112eb4 (Suspended) xsdb% Info: Cortex-A53 #3 (target 6) Stopped at 0xffffff8008112eb4 (Suspended) xsdb% Info: Cortex-R5 #0 (target 8) Stopped at 0xffff0000 (Suspended) xsdb% Info: Cortex-R5 #1 (target 9) Stopped at 0xffff0000 (Suspended) xsdb%
Stack and Frame Information
XSDB Command | Details |
---|---|
locals [-defs|-dict] [var [val]] | Returns the values of all local variables. If var is specified, the value of local variable var is returned. If var and val are specified, local variable var is set to val. If -defs is specified, the definition (type, size, address, RW flags) of the locals are returned. If -dict is specified, the local variables are returned in Tcl dict format, with variable names as dict keys and values as dict values. |
backtrace | Prints the call stack, in the order that functions were called, as a list of frames. |
xsdb% backtrace 0 0x400730 main(): test.c, line 22 1 0x7f7fa90ce4 xsdb% locals s : <Structure> var : 4196440 arr : uint8_t[8] str : 549723915792 p : 547602631848 c : 88 num : 0.0 xsdb%
Printing and Modifying Variables
XSDB command | Details |
---|---|
print [-add|-defs|-dict|-remove|-set <var>] <expr> | Prints the expression expr. expr can be a single variable or multiple variables combined with operators in a way that's syntactically valid. If -add is specified, expr is added to the auto expression list. Expressions in the auto expression list are printed every time print is called. If -defs is specified, the definition (type, size, address, RW flags) of expr is returned. If -dict is specified, the result of the expression is returned in Tcl dict format, with variable names as dict keys and values as dict values. If -remove is specified, an expression that was previously added to the auto expression list via add is removed. If -set is specified, var is set to the value of expr. |
mrd [-force|-size <access-size>|-value|-bin -file <name>| | Prints 1 word from address addr. If num is specified, num values are printed. If -force is specified, access protection is overrided, allowing access to reserved and invalid address ranges. If -size is specified, the amount of data read is determined by access-size, where access-size is one of the following:
If -value is specified, a Tcl list of values is returned. If -bin is specified, the data is written in binary format to the file name on the host machine. If -address-space is specified, the address space name is accessed instead of the default address space. For ARM DAP targets, the address spaces are as follows:
If unaligned-access is specified, memory access is not aligned to access size. |
mwr [-force|-size <access-size>|-bin -file <name>| | Writes a list of values values to address addr sequentially. If num is specified, num values are written. If -force is specified, access protection is overrided, allowing access to reserved and invalid address ranges. If -size is specified, the amount of data written is determined by access-size, where access-size is one of the following:
If -bin is specified, the data is read from file name and written to addr in binary format. If -address-space is specified, the address space name is accessed instead of the default address space. For ARM DAP targets, the address spaces are as follows:
If unaligned-access is specified, memory access is not aligned to access size. |
xsdb% nxt Info: Cortex-A53 #0 (target 3) Stopped at 0x40079c (Step) 33: memset(s->arr, 0xAA, sizeof(s->arr)); Info: Cortex-A53 #1 (target 4) Stopped at 0xffffff80087d6a58 (Suspended) Info: Cortex-A53 #2 (target 5) Stopped at 0xffffff80080d4a40 (Suspended) Info: Cortex-A53 #3 (target 6) Stopped at 0xffffff8008082280 (Suspended) Info: Cortex-R5 #0 (target 8) Stopped at 0xffff0000 (Suspended) Info: Cortex-R5 #1 (target 9) Stopped at 0xffff0000 (Suspended) xsdb% nxt Info: Cortex-A53 #0 (target 3) Stopped at 0x4007b0 (Step) 34: s->var = 1234; Info: Cortex-A53 #1 (target 4) Stopped at 0xffffff80087d7b84 (Suspended) Info: Cortex-A53 #2 (target 5) Stopped at 0xffffff80080992c8 (Suspended) Info: Cortex-A53 #3 (target 6) Stopped at 0xffffff80080df010 (Suspended) Info: Cortex-R5 #0 (target 8) Stopped at 0xffff0000 (Suspended) Info: Cortex-R5 #1 (target 9) Stopped at 0xffff0000 (Suspended) xsdb% nxt Info: Cortex-A53 #0 (target 3) Stopped at 0x4007bc (Step) 36: global_var = 0xCC33CC33; Info: Cortex-A53 #1 (target 4) Stopped at 0xffffff80087d7b84 (Suspended) Info: Cortex-A53 #2 (target 5) Stopped at 0xffffff80080992c8 (Suspended) Info: Cortex-A53 #3 (target 6) Stopped at 0xffffff80080df024 (Suspended) Info: Cortex-R5 #0 (target 8) Stopped at 0xffff0000 (Suspended) Info: Cortex-R5 #1 (target 9) Stopped at 0xffff0000 (Suspended) xsdb% print s->var s->var : 1234 xsdb% print s->arr s->arr : uint8_t[8] xsdb% print -defs s->arr Name Type Address Size Flags ======== ======== =========== ==== ===== s->arr uint8_t[8] 0x7ff62aa424 8 RW xsdb% mrd 0x7ff62aa424 2 7FF62AA424: AAAAAAAA 7FF62AA428: AAAAAAAA
Lower Level Examining
XSDB command | Details |
---|---|
rrd [-defs|-no-bits] [reg] | Reads all registers. If reg is provided, only register reg is read. If -defs is specified the register definitions are read instead of the values. If -no-bits is specified, bit f ields are not shown along with the register values. |
rwr <reg> <val> | Writes value val to register reg. |
dis [addr] [num] | Disassembles 1 instruction at the current PC value. |
xsdb% dis pc 10 ffffff8008112ec4: ldr w1, [x22] ffffff8008112ec8: cmp w1, w21 ffffff8008112ecc: b.ne -13 ; addr=0xffffff8008112e98 ffffff8008112ed0: sub x0, x0, x6 ffffff8008112ed4: mov w2, w2 ffffff8008112ed8: and x0, x0, x5 ffffff8008112edc: ldp x19, x20, [sp, #16] ffffff8008112ee0: mul x0, x0, x2 ffffff8008112ee4: ldp x21, x22, [sp, #32] ffffff8008112ee8: lsr x0, x0, x4 xsdb% rrd x0: 0000000247ad3bf0 x1: ffffffc87ff6c040 x2: 0000000003d89d8a x3: 00000000009d7053 x4: 0000000000000016 x5: 00ffffffffffffff x6: 0000000006334e7e x7: 0000000000000012 x8: ffffffc87ff6b2d0 x9: ffffffc87ff6b2b0 x10: 071c71c71c71c71c x11: 00000000000136f9 x12: 0000000000000044 x13: 00000000000001d6 x14: 00000000000000ff x15: 0000000000000400 x16: 0000000000000000 x17: 0000000001fd9034 x18: 0000000000000400 x19: ffffff80145dd008 x20: 0000000000000000 x21: 0000000000000004 x22: ffffff80145dd000 x23: ffffff80145dd008 x24: 0000000000000028 x25: ffffffc86e8e4000 x26: 0000000000000000 x27: ffffffc86e8e4400 x28: 0000000001050018 x29: ffffff80145c3e50 x30: ffffff8008112eb4 sp: ffffff80145c3e50 pc: ffffff8008112ec4 # ... xsdb% rwr pc 0xffffff8008112ec0
© Copyright 2019 - 2022 Xilinx Inc. Privacy Policy