Debugging Guest Applications with QEMU, XSDB, and XSCT

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

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.
This can allow you to debug the boot sequence of your virtual machine.

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

XSDB Command

Details

gdbremote connect <hostname>:<port>
gdbremote connect :<port>

Connects to a GDB remote server with host hostname and port port.
If hostname is left blank, it will connect to localhost.

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

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

XSDB Command

Details

target [id]
ta [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

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.
If count is specified, it will go step over count lines.
This will not go inside functions.

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.
If count is specified, it will go step over count lines.
This will not go inside functions.

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

XSDB Command

Details

bpadd <-addr <addr> | -file <name> -line <lineno>>
[ -target-id <id> -type <type>|-mode <mode> |
-enable <mode>]

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.
To add a breakpoint that targets all targets, use all as the target ID.

If -type is specified, type can be one of the following values:

  • auto - The breakpoint type is determined by the hw_server or TCF agent. (default)

  • hw - hardware breakpoint

  • sw - software breakpoint

If -mode is specified, mode is a bitfield that consists of the following values:

  • 0x01 - Triggered by a read from the breakpoint location

  • 0x02 - Triggered by a write to the breakpoint location

  • 0x04 - Triggered by an instruction execution at the breakpoint location (default)

  • 0x08 - Triggered by a data change at the breakpoint location

If -enable is specified, mode can be one of the following values:

  • 0 - The breakpoint is disabled

  • 1 - The breakpoint is enabled (default)

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

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

XSDB command

Details

print [-add|-defs|-dict|-remove|-set <var>] <expr>

Prints the expression exprexpr 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>|
-address-space <name>|-unaligned-access] <addr> [num]

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:

  • b - Read a byte

  • h - Read a half word

  • w - Read a word (default)

  • d - Read a double word

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:

  • DPR - DP registers

  • APR - AP registers

  • AP<n> - MEM-AP<n> registers

If unaligned-access is specified, memory access is not aligned to access size.

mwr [-force|-size <access-size>|-bin -file <name>|
-address-space <name>|-unaligned-access] <addr> <values> [num]

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:

  • b - Read a byte

  • h - Read a half word

  • w - Read a word (default)

  • d - Read a double word

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:

  • DPR - DP registers

  • APR - AP registers

  • AP<n> - MEM-AP<n> registers

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

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.
If addr and num are specified, num instructions are decoded at addr.
The keyword pc can be used instead of an address to disassemble num instructions at pc.

 

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

 

© 2025 Advanced Micro Devices, Inc. Privacy Policy