ESP8266 SDK: how to debug with gdb

by kacang bawang

Not long ago, to little fanfare, Espressif (the makers of ESP8266) released gdbstub – a library that allows use of gdb on ESP8266. It works with both non-OS and RTOS SDKs, and works over UART, not JTAG. You get 1 breakpoint for RAM and 1 breakpoint for FLASH. Is this awesome, or what!? Authorship is unattributed, but is believed to have been written by Sprite_tm.

In this post, I will show you how to add gdb support to your project. This example will use the RTOS SDK, but applies just the same to the non-OS SDK.

First, let’s talk a little bit about project organization. We will use esp-open-sdk on Linux. See previous articles about setting up non-os and rtos sdks.

I will skip over parts of the setup that have been discussed in the previous articles. You can find the exact copy of this project here, to use as a reference.

First, clone the git repository for the gdbstub somewhere locally. Then, set up the following folder structure.

Each directory inside src is compiled into its own .a. Then, the outer makefile rolls them into flash.bin and irom0text.bin.

Thus, gdbstub is added as a module, inside its own directory. Now, we need to connect it to the rest of the project.

First, we need a “module makefile” inside the directory. As a base, we will use the one found inside src/user/. I realize that there is already a Makefile inside the gdbstub, but it gives errors with the latest RTOS SDK.

Take src/user/Makefile copy (and overwrite) into src/gdbstub/, and within, change the GEN_LIBS line to look like:

1

2

//results in building of this static library, placed in .output/ directory

GEN_LIBS=libgdbstub.a

Then, edit the “inner makefile” in src/Makefile to look like:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

...

//added gdbstub as one of the directories that needs to be built

SUBDIRS=\

user\

gdbstub

...

//need to let linker know about gdb via -ggdb

TARGET_LDFLAGS=\

-ggdb\

-nostdlib\

-Wl,-EL\

--longcalls\

--text-section-literals

...

//I think these were switched around, should

//end up like this:

ifeq($(FLAVOR),release)

TARGET_LDFLAGS+=-g-O2

endif

ifeq($(FLAVOR),debug)

TARGET_LDFLAGS+=-g-O1

endif

...

//This is in the "don't touch" part.

//Allows to include from src/ directory

INCLUDES:=$(INCLUDES)-I$(PDIR)include-I$(PDIR)

...

Now let’s take a look at some small tweaks to the source of gdbstub. The only file we need to modify is gdbstub.c

1

2

3

4

5

6

7

8

9

10

11

12

13

...

// clean up double include, reorder, get rid of unused

//#include "gdbstub.h"

#include "espressif/c_types.h"

#include "espressif/esp8266/ets_sys.h"

#include "espressif/esp8266/eagle_soc.h"

//#include "gpio.h"

#include "xtensa/corebits.h"

#include "gdbstub.h"

#include "gdbstub-entry.h"

#include "gdbstub-cfg.h"

...

Lastly, let’s add an instruction to wait for debugger to attach into user_main.c.

1

2

3

4

5

6

7

8

9

10

...

voiduser_init(void)

{

...

uart_div_modify(0,UART_CLK_FREQ/115200);

//only after we set uart frequency

gdbstub_init();

...

}

Now we can compile by running make on the “outer makefile” and flash the resulting output from ./bin.

Ok, but how to we launch into a debug session? Use gdbcmds file from gdbstub like this:

1

$xtensa-lx106-elf-gdb-xgdbcmds-b115200

Make sure that /dev/ttyUSBx specified in gdbcmds matches what is found /dev. Now we find ourselves at a gdb prompt:

1

2

3

4

...

gdbstub_do_break_breakpoint_addr()at gdbstub-entry.S:399

399break0,0

(gdb)

We can either just continue (c) or set a breakpoint in RAM or FLASH. Breakpoints in RAM are set with br, while breakpoints in FLASH are set with hbr. Remember, we only have 1 of each.

My dev box died a couple of days ago, so unfortunately I cannot give a definitive answer right now, but I believe the .out file is a concatenation of binaries produced by compilation. That is, it is generated by the compiler/linker.

I solved it. The gdbstub.c was looking for some header files including core-isa.h that was present in the ESP_RTOS_SDK. Then just added core-isa in the gdbstub.c and it compiled fine. Have to still test on the hardware though.