LTS (2.0.1) Debug Build

Hey guys,

Using a particle Electron with Device OS 2.0.1
I’m working on debugging a nasty I2C bug. Monolithic builds have proven to be tricky to debug.
I can get open OCD to connect to device, but I can’t seem to hit any breakpoints, and it seems pretty confused about FreeRTOS threads. See the logs included with this post.

I attempted to build a modular debug build, but apparently System-Part 3 overflows APP_FLASH by 3056 bytes when build in debug mode.
I’m building locally on Linux (without workbench, my application is too complex to build in the particle source tree).

I’m building the particle system parts from the modules directory with the following command line (host system is Ubuntu 20.04 LTS)

make clean all program-dfu DEBUG_BUILD=y PARTICLE_DEVELOP=y USE_SWD=y PLATFORM=electron

Is it just impossible to create a modular debug build?

When using a monolithic application build MODULAR=n openocd starts and connects initially.

openocd -f interface/cmsis-dap.cfg -f target/stm32f2x.cfg -c "telnet_port 4444" -c "gdb_port 3333" -c "\$_TARGETNAME configure -rtos FreeRTOS"

I can start arm-none-eabi-gdb and load the elf produced alongside my app bin, here is the script I use to set this up automatically.

READELF=arm-none-eabi-readelf
GDB=arm-none-eabi-gdb
PLATFORM=electron
BIN_PATH=bin/electron

USER_APP=$1

function elf {
	echo $BIN_PATH/$1.elf
}

function bin {
	echo $BIN_PATH/$1-debug.bin
}

function get_addr {
	$READELF $1 --headers | grep .text | head -n 1 | sed "s/.*PROGBITS *\\([^ ]*\\).*/0x\\1/"
}

function load_string {
	ELF=$(elf $1)
	echo "add-symbol-file $ELF $(get_addr $ELF)"
}

$GDB $(elf $USER_APP) -nx \
	-ex "target remote localhost:3333" \
	-ex "monitor reset halt" \
	-ex "set confirm off" \
	-ex "$(load_string $USER_APP)" \
	-ex "set confirm on"

Running this script results in the following output.

Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
none separate
cortex_m reset_config sysresetreq
Error: couldn't bind tcl to socket: Address already in use
GNU gdb (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 8.3.0.20190709-git
Copyright (C) 2019 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=x86_64-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bin/electron/diagnostic-message-tests.elf...
Remote debugging using localhost:3333
Info : accepting 'gdb' connection on tcp/3333
Info : SWD DPIDR 0x2ba01477
Error: Failed to read memory at 0x41080064
Error: Error reading first thread item location in FreeRTOS thread list
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x0800019c msp: 0x20020000
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x0800019c msp: 0x20020000
add symbol table from file "bin/electron/diagnostic-message-tests.elf" at
        .text_addr = 0x80201a0
Reading symbols from bin/electron/diagnostic-message-tests.elf...
Info : SWD DPIDR 0x2ba01477
Error: Failed to read memory at 0x41080064
Error: Error reading first thread item location in FreeRTOS thread list

Trying to set a breakpoint in setup doesn’t really work. When I send gdb the command break setup it sets 3 breakpoints (which I think is just fuzzy-matching or similar symbols?), but then running with continue doesn’t run:

(gdb) break setup
Breakpoint 1 at 0x80294d4: setup. (3 locations)
(gdb) c
Cannot execute this command without a live selected thread.
(gdb) 

I’m at a bit of a loss here. I know that opencd can program the device, is there a specific location that the monolithic builds needs to be programmed to? I’ve been using the particle cli to flash with particle flash --usb my-debug-app.bin

Seems like the issue goes away if I remove the FREERTOS config from Openocd.
If I’m using SYSTEM_THREAD will I be able to break into other threads?

Yes, you will just not get as many details from the FreeRTOS side, and you probably don’t need it anyway.

I was able to debug normally using the same config. Also, you probably want to add this to the code of interest:

#pragma GCC optimize ("O0")