PX4 GDB Cheatsheet

This page contains a quick reference of the most useful commands for arm-none-eabi-gdb.

1) Open a binary

Typical Binary Locations
  • PX4FLOW: px4_flow/px4_flow.elf
  • PX4FMU: Firmware/Build/px4fmu-v1_default.build/firmware.elf (without any file extension! use Firmware/Images/px4fmu.px4 for flashing with the USB upload tools)
  • PX4IO: Firmware/Build/px4io-v1_default.build/firmware.elf (without any file extension!, after having built with make configure_px4io && make)
$ cd ~/src/Firmware
### $ arm-none-eabi-gdb <binary>, e.g.:
$ arm-none-eabi-gdb Build/px4fmu-v1_default.build/firmware.elf

GDB will reply with:

GNU gdb (GNU Tools for ARM Embedded Processors) 7.3.1.20120613-cvs
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-linux-gnu --target=arm-none-eabi".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/user/src/Firmware/Build/px4fmu-v1_default.build/firmware.elf...done.
(gdb) 

2) Connect to the board/target

A board / chip is called “target” in debugging terms.

Start OpenOCD

openocd -f interface/stlink-v2.cfg -f target/stm32f1x_stlink.cfg
openocd -f interface/stlink-v2.cfg -f target/stm32f4x_stlink.cfg

Connect to OpenOCD with GDB

The command below connects GDB to the hardware target for a debug session or to flash new code.

tar ext :3333

Connect using Black Magic Probe

Assuming arm-none-eabi-gdb is already started and the binary loaded, type inside GDB:

# /dev/ttyACM0 on Linux, /dev/tty.usbmodemXXXXXX on Mac OS X, or \\.\COMn on Windows
target extended-remote /dev/ttyACM0
mon swdp_scan
attach 1

To reset and run the board, type:

kill

3) Flash binary

This command flashes the current binary into the flash memory.

load

If the load fails, try to disconnect the board from all power sources, and reconnect it while holding down the reset button. Run load and shortly after release the reset button.

4) Run the code

mon reset init

Running

Non-interruptable

run

Interruptable with ^C:

continue

Stepping

s

Finding out the line

After it crashed, try:

mon halt
(gdb) where
#0  blocking_handler () at vector.c:238
#1  0xfffffff8 in ?? ()
#2  0xfffffff8 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
^Cblocking_handler () at vector.c:238
238	{
(gdb) info line
Line 238 of "vector.c" starts at address 0x80061c0 <blocking_handler> and ends at 0x80061c2 <null_handler>.

Disable the Stack Dump

NuttX prints a dump of the stack on taking hard faults, which is not what you want when stepping through the code with GDB. Set the configuration option below to disable it (disable stack dump in NuttX docs):

CONFIG_ARCH_STACKDUMP=n

Inspecting Stack Dumps after Crashes

NuttX will output a stack dump, similar to this:

up_hardfault: PANIC!!! Hard fault: 40000000
Assertion failed at file:armv7-m/up_hardfault.c line: 142 error code: 32771
sp:         100029fc
stack base: 10002c48
stack size: 000007fc
100029e0: 00000015 10002c48 100029fc 100029e0 100029e0 10002a0c 00000000 00000000
10002a00: 00000000 10002a0c 08005de1 100029fc 10001bb0 000007fc 10002c48 10002a24
10002a20: 08005ea3 10002a3c 00008003 0000008e 0802da34 10002a3c 08006093 10002a8c
10002a40: 00000003 10002a4c 681b0003 080248e8 10002a8c 10002a5c 0800937f 10002a8c
10002a60: 00000003 10002a6c 08006009 10002a74 08005fb9 10002a8c 00000003 10002b58
10002a80: 00000000 10002b68 0800547f 10002b60 00000000 00000000 00000000 00000000
10002aa0: 10002b68 00000000 00000000 00000000 00000000 ffffffe9 00000000 00000000
10002ac0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
10002ae0: 00000000 00000000 00000000 00000000 00000000 00000000 10002bf0 10002bf0
10002b00: 00000006 df41bdfa 00000000 080249c1 080248ea 21000000 00000000 00000000
10002b20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
10002b40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000ffff
10002b60: 00000000 10002b68 00001c58 10002bf0 10002b80 080096bf 10001bb0 000093fb
10002b80: 00000000 00000000 10002b90 080249c1 10001bb0 00000006 10002bf0 10001da0
10002ba0: 10002ba8 08018bbd 10001bb0 00000006 10002bf0 00000003 10001aa0 10001da0
10002bc0: 10001d60 fffffff7 10002bd0 08018c13 00000000 00000006 10002bf0 00000003
10002be0: 10002be8 08015f37 10001bf4 00000001 00000000 08010000 0802f6dc 00000003
10002c00: 10002c08 08015fff 10001bf4 00000001 10002c68 00000000 10002c20 08015b13
10002c20: 10001bf0 00000002 00000000 00000000 10002c38 080087dd 10001bb0 00000002
10002c40: 00000000 00000000 00000000 00000000 00000003 10002c5c 00000010 80000810
R0: 10002bf0 10002bf0 00000006 df41bdfa 00000000 00000000 00000000 10002b68
R8: 00000000 00000000 00000000 00000000 00000000 10002b60 080249c1 080248ea
xPSR: 21000000 PRIMASK: 00000000

To find the function call that caused the crash, inspect the LR and PC registers in the R8: line at the end.

R8: 00000000 00000000 00000000 00000000 00000000 10002b60 080249c1 080248ea

The two registers have these values:

  • LR: 080249c1
  • PC: 080248ea

Current Line

To get the line information of the calling function, ask GDB for the function name of this address. Prepend *0x to the printed address of the PC register: *0x080248ea.

info line *0x080248ea

GDB will print the line information.

Peripheral Register

To print a peripheral register, use x/x, where the first x is an abbreviation for examine and /x is the format specifier. This e.g. allows to look at the current state of an on-chip peripheral and determine if it has been set to the desired state.

x/x 0xABCD0000

Cortex M3/M4 Frames

(gdb)  p/x *(struct cm3_frame *)$r0
$3 = {
r0 = 0xc0038d70,
r1 = 0x4,
r2 = 0xc0038d70,
r3 = 0xc0038d70,
r12 = 0x0,
lr = 0x80333b3,
pc = 0x803213c,
psr = 0x81000000
}

Common Mistakes

  • Error message: “monitor” command not supported by this target. → No connection to JTAG adapter, missing “tar ext :1234” for STLink

Inspect NuttX Tasks

Source the Python debug script:

source Nuttx.py
Translations of this page:


Quick Links

QR Code: URL of current page