Post topics, source code that relate to the Arduino Platform

User avatar
By McChubby007
#39909 I thought I would share this with you, as I have spent two days trying to get gdb and gdbstub working using Arduino IDE (or Eclipse IDE with Arduino libraries; same thing in this case)...

I saw this post :http://hackaday.com/2015/12/12/squash-your-esp-8266-bugs-with-esp-gdbstub/ and thought I would try using the approach with my Eclipse IDE with Arduino libs setup...

I modified core_esp8266_main.c adding a call to gdbstub_init() after the call to uart_div_modify(). Changed the compiler flags etc, etc. Compiled fine.

Using gdb on /dev/ttyUSB0, the initial startup looked correct and I could view the breakpoint, see where gdbstub_init had been called. However once I did a 'continue' gdb seemed to hang and it would report 'putpkt .... Junk' received errors if I had set a watch or breakpoint which got executed. Gdb would never return to a prompt and I had to crtl-C to exit.

This is a case of me not knowing enough about the Arduino IDE library config and integration aspects of the esp8266, as well as how gdb and the stub operate, but eventually I found out what the problem was.

Subsequent to the gdbstub_init() call in core_esp8266_main.c, a call is then made to init() which in turn calls initPins() in core_esp8266_wiring.c. initPins() disables the UART interrupts, thus disabling gdbstub's hook into the uart's interrupts, this is what causes the problem since the gdbstub never gets triggered on a uart interrupt and gdb just hangs waiting.

My temporary solution for now, is to remove the disabling in initPins() when I am debugging. I could instead just ensure that the interrupts are re-enabled after initPins() is called, but I'm not entirely sure how to do that and it's bedtime now ;-)

So, I just thought I would document this in case anyone else has problems or wants to use gdb with Arduino core software.
User avatar
By Ravi S Kashi
#40157 Hi,

I am using Mikhail Grigorev's "Project Unofficial Development Kit for Espressif ESP8266" as my compiler tool chain and using eclipse as my GUI.

With this set up - what debugging options to I have? I too use NodeMCU Amica board

Thanks in Advance
Ravi
User avatar
By McChubby007
#40205 If you take gdbstub from here: https://github.com/esp8266/Arduino/tree/master/libraries/GDBStub

See if you can compile it. Compile with -Og and -ggdb flags to include symbolic debug info, which provides source intermixed with assembler in the gdb output.

Then it's a matter of including a call to gdbstub_init() in your initialisation/setup code. #ifdef Options in gdbstub-cfg.h also need you to look over and enable the ones you want to use. There are quite a few steps to the process and it took me quite a while to figure it out, but it's worth the ability to debug over serial.

Care needs to be taken as to where/when this is called as you need to ensure no other code takes control of the UART 0 interrupts. Also using the UART for serial printing etc., needs to be disabled/stopped.

By all means ask more questions, as it is tricky getting all the parts knitted together, or at least it was for me. If I can remember all the steps I will try and write something more definitive.

Oh, and you need to use xtensa's version of gdb too, the regular one won't work. However if you have the sdk and all you will have that already.

Good luck.
User avatar
By McChubby007
#40231 Here's more detail I just wrote:

I saw this post, which got me interested in setting-up my Eclipse IDE with Arduino SDK : http://hackaday.com/2015/12/12/squash-y ... p-gdbstub/

1. Download Espressif's gdbstub : https://github.com/espressif/esp-gdbstub

2. Compiler/assembler/linker flags:

Change -O and -g flags to include symbolic information:
-ggdb -Og # C/C++ compiler, linker (possibly optional in linker I'm unsure)
-ggdb # assembler (possibly optional here too I'm unsure)

3. Look through gdbstub-cfg.h and decide which of the options you want to enable when compiling, add those defines to the compiler
flags to enable the options when compiling, I used:
-DGDBSTUB_REDIRECT_CONSOLE_OUTPUT -DGDBSTUB_CTRLC_BREAK -DGDBSTUB_BREAK_ON_INIT

These options do the following:
GDBSTUB_REDIRECT_CONSOLE_OUTPUT : Allows os_printf to be sent to gdb which will be echod by gdb on-screen without interference.
This works well when using command-line gdb, however when using Eclipse it would not work
I think it broke something internal to Eclipse if I remember rightly.
GDBSTUB_CTRLC_BREAK : Ctrl-c in gdb session will stop esp8266 cpu wherever it is at the time of the Ctrl-c
GDBSTUB_BREAK_ON_INIT : The gdb stub will pause your code within it's init function, thus allowing you time to
attach gdb at your leisure, whereupon you will find your code stopped in the gdb stub
init function, allowing you to set breaks/watches etc and then continue to your main body
of code.

4. Include a call to gdbstub_init() in your setup/init code.
Ensure there are no calls to Serial.begin or anything else that changes the interrupt handler that gdbstub_init will have
attached to.
Ensure the serial UART is initialised before calling gdbstub_init(), by calling uart_div_modify(0, ...), then call gdbstub_init()

e.g. In the case of Arduino-based sdk, modify core_esp8266_main.cpp and place a call to gdbstub_init() immediately after the
call to uart_div_modify(0, ...). In addition I then #ifdef'd out the UART 0 disabling in
core_esp8266_wiring_digital.cpp (function initPins), which would otherwise cancel gdbstub's ability to catch UART interrupts.

5. The version of gdb to use (from command-line or Eclipse IDE) should be xtensa-lx106-elf-gdb or your own locally built
esp8266 sdk version of gdb. Standard (Linux) gdb will not work.

6. Configure gdb settings on gdb startup, I used a command file, with the following:
file ./Debug/esp_gdb.elf
set remotelogfile gdb_rsp_logfile.txt
set remote hardware-breakpoint-limit 1
set remote hardware-watchpoint-limit 1
#set debug remote 1
set debug xtensa 4
set remotebaud 115200
target remote /dev/ttyUSB0

These can by entered manually at the gdb command prompt or put into a file and executed with "gdb -x <commandfile>".
Uncomment the "set debug remote 1" line for additional logging if your gdb session isn't working as you expect, it can
help to solve the problem - it did for me.

7. If using Eclipse IDE with gdb:

a. Create a new debug configuration by creating a new C/C++ Remote Application:

b. "Main" tab:
"C/C++ Application" -- enter the name of the compiled .elf file e.g. "./Debug/esp_gdb.elf"

In order to select the serial port for gdb to use, at the bottom of the main dialog, press "Select Other..."
and select:
"GDB (DSF) Manual Remote Debugging Launcher"

c. "Debugger" tab:
Tick "Stop on startup at", and enter "user_init" ... assuming you are using -DGDBSTUB_BREAK_ON_INIT in compile.
"GDB debugger:" -- Enter the path for the xtensa gdb

c.i. "Connection" sub-tab:
"Type:" dropdown -- select "Serial"
"Device:" -- enter your USB port
"Speed:" -- enter serial speed

8. Start gdb.

If you have used the same gdbstub settings as me, then your code will have stopped at a "break" instruction within
the gdbstub_init function.

If gdb seems to hang, with no prompt then ensure your code has not messed around with the uart and that the gdbstub_init
call is in the right place. gdb hangs in my experience are where it has not received anything back from the serial port
and this is because gdbstub never attached to the uart.