Skip to content

source level debugging via serial port #4336

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 45 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
843919f
Create gdb-debug
freeck Feb 9, 2018
6323017
Delete gdb-debug
freeck Feb 9, 2018
d6ff725
Create GDB-DEBUG
freeck Feb 9, 2018
ca468ae
Delete GDB-DEBUG
freeck Feb 9, 2018
ea3dfba
Create readme.txt
freeck Feb 9, 2018
b128089
Delete readme.txt
freeck Feb 9, 2018
a4119f5
Create README.txt
freeck Feb 9, 2018
783c871
Create gdbcmds
freeck Feb 9, 2018
136b594
Update gdbcmds
freeck Feb 9, 2018
765fe41
Create library.properties
freeck Feb 9, 2018
3792c02
Update library.properties
freeck Feb 9, 2018
2ffd636
Update library.properties
freeck Feb 9, 2018
52b3cec
Update library.properties
freeck Feb 9, 2018
fa5451c
Update library.properties
freeck Feb 9, 2018
7e6a4ef
Update library.properties
freeck Feb 9, 2018
dbf6ae3
Create readme.txt
freeck Feb 9, 2018
461220a
Delete readme.txt
freeck Feb 9, 2018
99c4bef
Create readme.txt
freeck Feb 9, 2018
3f9158c
Add files via upload
freeck Feb 9, 2018
54b1dc1
Create read
freeck Feb 9, 2018
b13bbec
Add files via upload
freeck Feb 9, 2018
6eb174a
Update README.txt
freeck Feb 9, 2018
6ea79a6
Create read
freeck Feb 9, 2018
309ebaa
Add files via upload
freeck Feb 9, 2018
66be5d3
Delete read
freeck Feb 9, 2018
d3c5c3d
Add files via upload
freeck Feb 9, 2018
967bcc4
Update Instructions.rst
freeck Feb 9, 2018
30f2322
Update Instructions.rst
freeck Feb 9, 2018
d5193f2
Delete Blink.ino
freeck Feb 9, 2018
ed806ee
Delete read
freeck Feb 9, 2018
14aa837
Update README.txt
freeck Feb 9, 2018
ad0dcdd
Update library.properties
freeck Feb 9, 2018
8de6b02
Add files via upload
freeck Feb 10, 2018
f3ce176
Delete Instructions.rst
freeck Feb 10, 2018
b683ed7
Add files via upload
freeck Feb 10, 2018
501ed90
Update instructions.rst
freeck Feb 10, 2018
b6bddab
Update instructions.rst
freeck Feb 10, 2018
e626334
Update instructions.rst
freeck Feb 10, 2018
fdf6a21
Add files via upload
freeck Feb 10, 2018
fa20c18
Update instructions.rst
freeck Feb 10, 2018
767c2c6
Update instructions.rst
freeck Feb 10, 2018
decb996
Update instructions.rst
freeck Feb 10, 2018
f7fade5
Update instructions.rst
freeck Feb 10, 2018
951e38e
Update instructions.rst
freeck Feb 10, 2018
4b6abeb
Update instructions.rst
freeck Feb 11, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions libraries/GDBStub-source-level-debug/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
This library contains all files needed for source level debugging.
As from v2.0 of esp8266-Arduino this option was not available.

The scope of the instruction is limited to preparing and testing a command-line gdb-debugging session.
It does not contain an instruction on how to install an IDE for the esp8266 nor the tool chain itself.  
The primary source of the tools and gdbstub-code is  http://gnutoolchains.com/download/.

Compared to the sources supplied by VisualGDB a few modifications have been made to the sources: some IRAM-instructions have
placed to FLASH, and some assembly-functions have been alignment to 4 bytes (in order to enable the code being called via a long-call).


56 changes: 56 additions & 0 deletions libraries/GDBStub-source-level-debug/bin/Blink.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@


#include "Arduino.h"
int s_Tick=0;
int number = 0;
#define RAMFUNC __attribute__((section(".entry.text")))
#include "gdbstub.h"

int RAMFUNC add(int a, int b)
{
int c;
c = a+b;
return c;
}
int RAMFUNC mult(int a, int b){
int c;
c = a*b;
return c;
}
int RAMFUNC calculate(int a, int b, int c){
a = add(a,b);
c = mult(a,c);
return c;
}
void RAMFUNC function(){
int val;
//toggleIoPins();
val = calculate(number++,2,3);
ets_printf("Tick: %d Value:%d\r\n", ++s_Tick, val);
delay(1000);
}

void setup() {
//uart_div_modify(0, UART_CLK_FREQ / 115200);
Serial.begin(115200);
Serial.print("program started");
gdbstub_init();
pinMode(4, OUTPUT); // Initialize the pin as an output
pinMode(5, OUTPUT); // Initialize the pin as an output
}

void RAMFUNC toggleIoPins() {
digitalWrite(4, LOW);
digitalWrite(5, LOW);
delay(100);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
delay(200);
}
int loopCount=0;
// the loop function runs over and over again forever
void RAMFUNC loop() {
loopCount++;
function();
ets_printf("Loopcount: %d",loopCount);
}
Binary file not shown.
5 changes: 5 additions & 0 deletions libraries/GDBStub-source-level-debug/bin/gdbcmds
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
set remote hardware-breakpoint-limit 1
set remote hardware-watchpoint-limit 1
set debug xtensa 4
target remote \\.\COM9
thb loop
Binary file not shown.
5 changes: 5 additions & 0 deletions libraries/GDBStub-source-level-debug/gdbcmds
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
set remote hardware-breakpoint-limit 1
set remote hardware-watchpoint-limit 1
set debug xtensa 4
target remote \\.\COM9
thb loop
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
166 changes: 166 additions & 0 deletions libraries/GDBStub-source-level-debug/instructions.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
**Instructions command line debugging ESP8266**

+----+----------------+------------------------------------------------------------------------+-----------+--------+-------------+
| | Author | Fred Kuijper | Version | 0.1 | 25-1-2018 |
+====+================+========================================================================+===========+========+=============+
| | | Translation to English | Version | 0.2 | 1-02-2018 |
+----+----------------+------------------------------------------------------------------------+-----------+--------+-------------+
| | | Minor modifications | Version | 0.21 | 4-2-2018 |
+----+----------------+------------------------------------------------------------------------+-----------+--------+-------------+

Status: under construction!

Scope
======
The scope is limited to preparing and testing a command-line gdb-debugging session for the esp8266 processor. It does not contain an instruction on how to install an IDE for the esp8266 nor the tool chain itself.
The instruction is based on a Windows-environment. The primary source of the tools and gdbstub-code is http://gnutoolchains.com/download/.
A few modifications have been made to the sources: some IRAM-instructions have placed to FLASH, and some assembly-functions have been alignment to 4 bytes (in order to enable the code being called via
a long-call).

Command line debugging
======================
The next steps should be followed to start command line debugging.
1: Download the files from github.
*The directory should look like this:*

.. figure:: gdbstub-lib.png

Directory “\ *bin*\ ” contains all the files necessary to execute a
command line debug-session.:

.. figure:: gdbstub-dir.png
Copy the files of directory “\ *bin”* to a location of your choice.
Copy the library in directory “\ *gdbstub*\ ” to a location where you normally put your libraries.
**Mind you**: The original files from *VisualGDB* have been modified in order to reduce the IRAM-usage, and also have set the some #defines in file *gdbstub-cfg.h*.

2: Prepare your own sketch or use the example-sketch provided by the repository. In case you use your own sketch, the following lines have to be added.

1.Add #include "gdbstub.h"

2.Add to function setup():
Serial.begin(115200);

gdbstub_init();

**Mind you**: After this **Serial.printf()** doesn’t work anymore as
gdbstub\_init() takes over the UART-interrupt, instead use function
**ets\_printf** for output of messages!

4: Build the example app using compiler/linker options: “-\ *ggdb –Og
–mlongcalls*\ ”.
https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html#Debugging-Options.
After a new build, be sure to copy the latest application elf-file to
the directory where the bin-files reside.
The Arduino\_IDE compiler/linker compiles with options: “\ *-Os -g
–mlongcalls”* (*I do not know how and where to set these options*) , for
“Eclipse-Sloeber “ set the options to “–\ *ggdb –Og –mlongcalls*\ ” ,
*“–Og”* generates easier to debug code (see
`*https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html* <https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html>`__
*). *

5: File “\ *gdbcmds”* is the configuration-file containing the arguments for starting the debug-session:
1.set remote hardware-breakpoint-limit 1

2.set remote hardware-watchpoint-limit 1

3.set debug xtensa 4

4.target remote `\\\\.\\COM9 <file:///\\.\COM9>`__ (**change to your own com-port**)

5.file blink.ino.elf (**the application of choice, add complete path if elf-file resides somewhere else**)

6.thb loop (or any location you want your program to start the debug-session).

6: Open a command shell and go to the working directory where *the files
xtensa-lx106-elf-gdb* and *gdbcmds* reside. Copy the latest ELF-file to
this directory.

7: Then download the application and verify that the debug-stub is actually
present and has started:

.. figure:: gdbstub-start.png

You should see: **“$ST05#b9”** on the debug-port of the esp8266.

8: Then execute command: “\ *xtensa-lx106-elf-gdb.exe -x gdbcmds*\ ”. If
everything goes well the application will start and stop at location
“\ *loop*\ ”.
Output on the debug-port:

.. figure:: gdbstub-comport-output.png

Output from the target:

.. figure:: gdbstub-breakpoint1.png

Then execute command “\ *info break*\ ”:

.. figure:: gdbstub-info-break.png
And the breakpoints defined in file *gdbcmds* are shown.

9: Continue the program by entering “\ *continue*\ ”

.. figure:: gdbstub-thb-loop.png
After 1000 milliseconds the program will stop at function “\ *loop*\ ”.

*Add a watchpoint*
1: Define a *watchpoint* and an *expression*
2: Continue executing and wait.
*Condition reached*

For more extensive info about *command-line gdb* I refer to
http://sourceware.org/gdb/onlinedocs/gdb/index.html#SEC_Contents

This was it! I hope this may inspire you to use source level
debugging. I personally prefer and would recommend using Eclipse-Sloeber
as IDE.

Issues, tips and tricks
=======================

1. Put the code to be debugged preferably in IRAM, you can then put
multiple breakpoints in a function (the esp8266 has only one hardware
breakpoint).

2. Since esp8266 has only 1 hardware-breakpoint, it is useful to define a
so-called hardware temporary breakpoint (*thb*). *thb* or *hb*
can also be used to set a breakpoint in Flash code. A temporary
breakpoint is deactivated after each hit, so a next hardware
breakpoint may be set.

3. Always check whether the target actually contains *gdbstub*. Start a
terminal program (for example *RealTerm*), connect with the com port,
reset the target. If all goes well, a message from *gdbstub* will
appear on the screen: **“$T05#B9**\ ”. If not, the application is not
properly built.

4. Sometimes the debugger doesn’t stop at a certain location: this may
be caused by the compiler’s optimizer, the optimizer could generate
inline code (see the function calculate () as shown below)! To
minimize these effects compile with flag “–Og” .

.. figure:: gdbstub-watchpoint-setcondition-reached.png

5. Function **ets\_printf()** and **Serial.printf()** behave
differently. The serial-IO for the Arduino-IDE is based on *class
Serial* , the debugger uses the standard-IO library...

**Serial.prinf()** is disabled by *gdbstub*, so use **ets\_printf()**
instead.

References
==========

1. https://github.com/espressif/esp-gdbstub

2. https://github.com/esp8266/Arduino/tree/master/libraries/GDBStub/

3. https://espressif.com/sites/default/files/documentation/esp8266_reset_causes_and_common_fatal_exception_causes_en.pdf

4. https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

5. http://sourceware.org/gdb/onlinedocs/gdb/index.html#SEC_Contents

6. https://visualgdb.com/tutorials/esp8266/gdbstub/

7. http://gnutoolchains.com/download/
9 changes: 9 additions & 0 deletions libraries/GDBStub-source-level-debug/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=GDBStub
version=0
author=ESPRESSIF/VisualGDB
maintainer=Fred Kuijper
sentence=GDB server stub by Espressif/VisualGDB
paragraph=GDB server stub helps debug source level debug via the serial port.
category=Uncategorized
url=https://github.com/espressif/esp-gdbstub
architectures=esp8266
24 changes: 24 additions & 0 deletions libraries/GDBStub-source-level-debug/src/License
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
ESPRESSIF MIT License

Copyright (c) 2015 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>

Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, it is free of charge, to any person obtaining a copy of this software and associated documentation files (the ��Software��), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED ��AS IS��, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


���� MIT ����֤

��Ȩ (c) 2015 <������Ϣ�Ƽ����Ϻ������޹�˾>

������֤��Ȩ������������Ϣ�Ƽ� ESP8266 ��Ʒ��Ӧ�ÿ������ڴ�����£�������֤�����Ȩ�κλ�ø�������������ĵ���ͳ��Ϊ�������������������Ƶؾ�Ӫ�����������������Ƶ�ʹ�á����ơ��޸ġ��ϲ������淢�С�ɢ��������Ȩ������������������������Ȩ��������Ȩ����������ЩȨ����ͬʱ������������������

�����������������и����ж�����������ϵİ�Ȩ��������Ȩ������

�������������������ṩ��û���κ���ȷ�򰵺��ĵ������������������ڹ��������ԡ��ʺ�ijһ�ض���;�ͷ���Ȩ�ı�֤�����ߺͰ�Ȩ���������κ�����¾�����������������ʹ��������Ժ�ͬ��ʽ��������Ȩ��������ʽ������κ����⡢�𺦻��������θ���




69 changes: 69 additions & 0 deletions libraries/GDBStub-source-level-debug/src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@

GDBSTUB
=======

Intro
-----

While the ESP8266 supports the standard Gnu set of C programming utilities, for now the choice of debuggers
has been limited: there is an attempt at [OpenOCD support](https://github.com/projectgus/openocd), but at
the time of writing, it doesn't support hardware watchpoints and breakpoints yet, and it needs a separate
JTAG adapter connecting to the ESP8266s JTAG pins. As an alternative, [Cesanta](https://www.cesanta.com/)
has implemented a barebones[GDB stub](https://blog.cesanta.com/esp8266-gdb) in their Smart.js solution -
unfortunately, this only supports exception catching and needs some work before you can use it outside of
the Smart.js platform. Moreover, it also does not work with FreeRTOS.

For internal use, we at Espressif desired a GDB stub that works with FreeRTOS and is a bit more capable,
so we designed our own implementation of it. This stub works both under FreeRTOS as well as the OS-less
SDK and is able to catch exceptions and do backtraces on them, read and write memory, forward [os_]printf
statements to gdb, single-step instructions and set hardware break- and watchpoints. It connects to the
host machine (which runs gdb) using the standard serial connection that's also used for programming.

In order to be useful the gdbstub has to be used in conjunction with an xtensa-lx106-elf-gdb, for example
as generated by the [esp-open-sdk](https://github.com/pfalcon/esp-open-sdk) project.

Usage
-----
* Grab the gdbstub project and put the files in a directory called 'gdbstub' in your project. You can do this
either by checking out the Git repo, or adding the Git repo as a submodule to your project if it's already
in Git.
* Modify your Makefile. You'll need to include the gdbstub sources: if your Makefile is structured like the
ones in the Espressif examples, you can add `gdbstub` to the `SUBDIRS` define and `gdbstub/libgdbstub.a` to the
`COMPONENTS_eagle.app.v6` define. Also, you probably want to add `-ggdb` to your compiler flags (`TARGET_LDFLAGS`)
and, if you are debugging, change any optimation flags (-Os, -O2 etc) into `-Og`. Finally, make sure your Makefile
also compiles .S files.
* Configure gdbstub by editting `gdbstub-cfg.h`. There are a bunch of options you can tweak: FreeRTOS or bare SDK,
private exception/breakpoint stack, console redirection to GDB, wait till debugger attachment etc. You can also
configure the options by including the proper -Dwhatever gcc flags in your Makefiles.
* In your user_main.c, add an `#include <../gdbstub/gdbstub.h>` and call `gdbstub_init();` somewhere in user_main.
* Compile and flash your board.
* Run gdb, depending on your configuration immediately after resetting the board or after it has run into
an exception. The easiest way to do it is to use the provided script: xtensa-lx106-elf-gdb -x gdbcmds -b 38400
Change the '38400' into the baud rate your code uses. You may need to change the gdbcmds script to fit the
configuration of your hardware and build environment.

Notes
-----
* Using software breakpoints ('br') only works on code that's in RAM. Code in flash can only have a hardware
breakpoint ('hbr').
* Due to hardware limitations, only one hardware breakpount and one hardware watchpoint are available.
* Pressing control-C to interrupt the running program depends on gdbstub hooking the UART interrupt.
If some code re-hooks this afterwards, gdbstub won't be able to receive characters. If gdbstub handles
the interrupt, the user code will not receive any characters.
* Continuing from an exception is not (yet) supported in FreeRTOS mode.
* The WiFi hardware is designed to be serviced by software periodically. It has some buffers so it
will behave OK when some data comes in while the processor is busy, but these buffers are not infinite.
If the WiFi hardware receives lots of data while the debugger has stopped the CPU, it is bound
to crash. This will happen mostly when working with UDP and/or ICMP; TCP-connections in general will
not send much more data when the other side doesn't send any ACKs.

License
-------
This gdbstub is licensed under the Espressif MIT license, as described in the License file.


Thanks
------
* Cesanta, for their initial ESP8266 exception handling only gdbstub,
* jcmvbkbc, for providing an incompatible but interesting gdbstub for other Xtensa CPUs,
* Sysprogs (makers of VisualGDB), for their suggestions and bugreports.
Loading