How to debug MicroPython using gdb ?

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
Post Reply
User avatar
shazz
Posts: 46
Joined: Tue Apr 30, 2019 6:35 pm
Contact:

How to debug MicroPython using gdb ?

Post by shazz » Fri Jul 12, 2019 9:33 am

Hi,

I tried to debug some SPI/TFT driver code for the SAMD port and I never used gdb for remote debugging.

My first wish was to "only" see my printf somwhere (occuring before the REPL comes to life) but... nothing showed up.
I'm using the J-Link EDU Mini connected to the SWD port of my Adafruit Pygamer on Ubuntu 19.04.

What I did :

Code: Select all

JLinkGDBServer -select USB -device ATSAMD51J19 -endian little -if SWD -speed auto -noir -noLocalhostOnly
SEGGER J-Link GDB Server V6.46d Command Line Version

JLinkARM.dll V6.46d (DLL compiled Jun  7 2019 17:26:52)

Command line: -select USB -device ATSAMD51J19 -endian little -if SWD -speed auto -noir -noLocalhostOnly
-----GDB Server start settings-----
GDBInit file:                  none
GDB Server Listening port:     2331
SWO raw output listening port: 2332
Terminal I/O port:             2333
Accept remote connection:      yes
Generate logfile:              off
Verify download:               off
Init regs on start:            off
Silent mode:                   off
Single run mode:               off
Target connection timeout:     0 ms
------J-Link related settings------
J-Link Host interface:         USB
J-Link script:                 none
J-Link settings file:          none
------Target related settings------
Target device:                 ATSAMD51J19
Target interface:              SWD
Target interface speed:        auto
Target endian:                 little

Connecting to J-Link...
J-Link is connected.
Firmware: J-Link EDU Mini V1 compiled May 27 2019 15:50:07
Hardware: V1.00
S/N: 801010356
Feature(s): FlashBP, GDB
Checking target voltage...
Target voltage: 3.30 V
Listening on TCP/IP port 2331
Connecting to target...Connected to target
Waiting for GDB connection...
So until now it seems ok.
Then I started gdb-multiarch (I'm using Ubuntu 19.04, no more specific gdb versions):

Code: Select all

gdb-multiarch -ex "set arch arm" -ex "set endian little" -ex "target extended-remote :2331"
The target architecture is assumed to be arm
The target is assumed to be little endian
Remote debugging using :2331
0xdeadbeee in ?? ()
What is displayed in the GDB server window:

Code: Select all

Connected to 127.0.0.1
Reading all registers
Read 4 bytes @ address 0x00001108 (Data = 0x7828786B)
Read 4 bytes @ address 0x00001104 (Data = 0x461DD052)
Read 4 bytes @ address 0x00001108 (Data = 0x7828786B)
Read 4 bytes @ address 0x00001104 (Data = 0x461DD052)
Read 2 bytes @ address 0x00001108 (Data = 0x786B)
Read 2 bytes @ address 0x00001106 (Data = 0x461D)
Read 2 bytes @ address 0x00001104 (Data = 0xD052)
Read 2 bytes @ address 0x00001108 (Data = 0x786B)
Read 2 bytes @ address 0x00001106 (Data = 0x461D)
Read 2 bytes @ address 0x00001104 (Data = 0xD052)
Read 4 bytes @ address 0x00001108 (Data = 0x7828786B)
Read 4 bytes @ address 0x00001104 (Data = 0x461DD052)
Read 4 bytes @ address 0x00001108 (Data = 0x7828786B)
Read 4 bytes @ address 0x00001104 (Data = 0x461DD052)
Read 4 bytes @ address 0x00001108 (Data = 0x7828786B)
Read 4 bytes @ address 0x00001108 (Data = 0x7828786B)
Read 4 bytes @ address 0x00001108 (Data = 0x7828786B)
Read 2 bytes @ address 0x00001108 (Data = 0x786B)
But nothing more, even if I reboot the board, my printf don't show up.

I tried to start the firmware from gdb using:

Code: Select all

gdb-multiarch -ex "set arch arm" -ex "set endian little" -ex "target extended-remote :2331" build-ADAFRUIT_PYGAMER/firmware.elf
but like that it crashes.

Any advice ? Anything I should do at compilation time to redirect printf to the debugger ?

Thanks!
Last edited by shazz on Fri Jul 12, 2019 10:06 am, edited 3 times in total.
8bits should be enough...

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: How to debug MicroPython using gdb ?

Post by jimmo » Fri Jul 12, 2019 10:04 am

shazz wrote:
Fri Jul 12, 2019 9:33 am
My first wish was to "only" see my printf somwhere (occuring before the REPL comes to life) but... nothing showed up.
Can you clarify what you mean by "see my printf". I can think of two ways to achieve this using gdb:
- You put a breakpoint on printf, and inspect the arguments to see their contents. (Or similarly, a breakpoint on something lower-level than printf to see the formatted string).
- Using semihosting. This is a super neat feature, I've used it on the Black Magic Probe for example. https://github.com/blacksphere/blackmag ... IO-Support
shazz wrote:
Fri Jul 12, 2019 9:33 am
Then I started gdb-multiarch (I'm using Ubuntu 19.04, no more specific gdb versions):
Do you have `arm-none-eabi-gdb` ? What cross compiler did you use to build the firmware? (likely arm-none-eabi-gcc?)

I don't know much about gdb-multiarch, does it work for bare-metal arm-eabi?
shazz wrote:
Fri Jul 12, 2019 9:33 am
I tried to start the firmware from gdb using: (command line)
That just tells gdb what the firmware is (e.g. for symbols or for loading). You want the "load" and "run" commands (in conjunction with passing the elf file on the command line).
shazz wrote:
Fri Jul 12, 2019 9:33 am
Anything I should do at compilation time to redirect printf to the debugger ?
Sounds like you want semihosting.

User avatar
shazz
Posts: 46
Joined: Tue Apr 30, 2019 6:35 pm
Contact:

Re: How to debug MicroPython using gdb ?

Post by shazz » Fri Jul 12, 2019 10:16 am

Ah! I was thinking that was magic, any printf output would be redirected to the debugger :)
So yes if this is not magic I guess I need semi-hosting.
Do you know in the samd makefile where I should add those linker directives :

Code: Select all

-specs=rdimon.specs and -lrdimon
And where (+ includes ?) to add :

Code: Select all

void initialise_monitor_handles(void);
initialise_monitor_handles();
Is it enough ? Would it work with J-Link ?
I have a black magic probe but it doesn't support the SAMD51...



Yes I used arm-none-eabi-gcc
But with ubuntu 18.04 and after, arm-none-eabi-gdb doesn't exist anymore, only gdb-multiarch (link: How to install “gdb-arm-none-eabi” on Ubuntu 18.04?). It looks it can support all architectures:

Code: Select all

(gdb) set arch
Requires an argument. Valid arguments are i386, ... , aarch64:ilp32, arm, armv2, armv2a, armv3, armv3m, armv4, armv4t, armv5, armv5t, armv5te, xscale, ep9312, iwmmxt, iwmmxt2, armv5tej, armv6, armv6kz, armv6t2, armv6k, armv7, armv6-m, armv6s-m, armv7e-m, armv8-a, armv8-r, armv8-m.base, armv8-m.main, arm_any, alpha, ....
I'll try again (using armv7e-m which looks to be the good arch said readelf) but using load and run, it was crashing (load, monitor reset, c)

EDIT: with load, run (restart, it works!), so now, need semi-hosting :D
8bits should be enough...

User avatar
shazz
Posts: 46
Joined: Tue Apr 30, 2019 6:35 pm
Contact:

Re: How to debug MicroPython using gdb ?

Post by shazz » Fri Jul 12, 2019 10:32 am

I tried to add in the samd Makefile

Code: Select all

LDFLAGS += --gc-sections --specs=rdimon.specs -lrdimon
but got:

Code: Select all

LINK build-ADAFRUIT_PYGAMER/firmware.elf
arm-none-eabi-ld: unrecognized option '--specs=rdimon.specs'
and l could not find librdimon.a in the toolchain...

humm
8bits should be enough...

Post Reply