diff --git a/Readme.md b/Readme.md index 5acd9f49d6..0942998e97 100644 --- a/Readme.md +++ b/Readme.md @@ -66,6 +66,7 @@ n/a = The selected SDK is not available on that OS - Custom heap allocation: (default: OFF) If your application is experiencing heap fragmentation then you can try the [umm_malloc](https://github.com/rhempel/umm_malloc) heap allocation. To enable it compile Sming with `ENABLE_CUSTOM_HEAP=1`. In order to use it in your sample/application make sure to compile the sample with `ENABLE_CUSTOM_HEAP=1`. **Do not enable custom heap allocation and -mforce-l32 compiler flag together**. - Debug information log level and format: There are four debug levels: debug=3, info=2, warn=1, error=0. Using `DEBUG_VERBOSE_LEVEL` you can set the desired level (0-3). For example `DEBUG_VERBOSE_LEVEL=2` will show only info messages and above. Another make directive is `DEBUG_PRINT_FILENAME_AND_LINE=1` which enables printing the filename and line number of every debug line. This will require extra space on flash. Note: you can compile the Sming library with a set of debug directives and your project with another settings, this way you can control debugging sepparately for sming and your application code. - Debug information for custom LWIP: If you use custom LWIP (see above) some debug information will be printed for critical errors and situations. You can enable debug information printing altogether using `ENABLE_LWIPDEBUG=1`. To increase debugging for certain areas you can modify debug options in `third-party/esp-open-lwip/include/lwipopts.h`. +- Interactive debugging on the device: (default: OFF) In order to be able to debug live directly on the ESP8266 microcontroller you should re-compile your application and the Sming library with `ENABLE_GDB=1` directive. See [Basic_Debug](https://github.com/SmingHub/Sming/tree/develop/samples/Basic_Debug) sample for more details. - CommandExecutor feature: (default: ON) This feature enables execution of certain commands by registering token handlers for text received via serial, websocket or telnet connection. If this feature is not used additional RAM/Flash can be obtained by setting `ENABLE_CMD_EXECUTOR=0`. This will save ~1KB RAM and ~3KB of flash memory.

diff --git a/Sming/Makefile b/Sming/Makefile index 49fbf68dfa..28e4ba65fc 100644 --- a/Sming/Makefile +++ b/Sming/Makefile @@ -152,7 +152,9 @@ TARGET = app CUSTOM_TARGETS ?= # which modules (subdirectories) of the project to include in compiling -MODULES = system system/helpers Wiring appinit $(shell find SmingCore -type d) $(filter %/, $(wildcard Services/*/)) $(filter %/, $(wildcard Libraries/*/)) +MODULES = system system/helpers Wiring appinit \ + $(sort $(dir $(wildcard SmingCore/*/ SmingCore/*/*/ SmingCore/*/*/*/))) \ + $(filter %/, $(wildcard Services/*/)) $(filter %/, $(wildcard Libraries/*/)) EXTRA_INCDIR = include system/include Wiring Libraries SmingCore $(SDK_BASE)/../include # Place a file that should exist in a submodule that is fetched separately diff --git a/Sming/SmingCore/Network/Http/HttpRequest.cpp b/Sming/SmingCore/Network/Http/HttpRequest.cpp index 614c3b7f35..26cd7607d6 100644 --- a/Sming/SmingCore/Network/Http/HttpRequest.cpp +++ b/Sming/SmingCore/Network/Http/HttpRequest.cpp @@ -185,12 +185,12 @@ uint32_t HttpRequest::getSslOptions() { return sslOptions; } -HttpRequest* HttpRequest::pinCertificate(SSLFingerprints fingerprints) { +HttpRequest* HttpRequest::pinCertificate(const SSLFingerprints& fingerprints) { sslFingerprint = fingerprints; return this; } -HttpRequest* HttpRequest::setSslClientKeyCert(SSLKeyCertPair clientKeyCert) { +HttpRequest* HttpRequest::setSslClientKeyCert(const SSLKeyCertPair& clientKeyCert) { this->sslClientKeyCert = clientKeyCert; return this; } diff --git a/Sming/SmingCore/Network/Http/HttpRequest.h b/Sming/SmingCore/Network/Http/HttpRequest.h index 35f7807c1b..23aac97ae3 100644 --- a/Sming/SmingCore/Network/Http/HttpRequest.h +++ b/Sming/SmingCore/Network/Http/HttpRequest.h @@ -94,7 +94,7 @@ class HttpRequest { * * @return bool true of success, false or failure */ - HttpRequest* pinCertificate(SSLFingerprints fingerprints); + HttpRequest* pinCertificate(const SSLFingerprints& fingerprints); /** * @brief Sets client private key, certificate and password from memory @@ -103,7 +103,7 @@ class HttpRequest { * * @return HttpRequest pointer */ - HttpRequest* setSslClientKeyCert(SSLKeyCertPair clientKeyCert); + HttpRequest* setSslClientKeyCert(const SSLKeyCertPair& clientKeyCert); #endif HttpRequest* setBody(const String& body); diff --git a/samples/Basic_Debug/README.md b/samples/Basic_Debug/README.md index 10ca427d7d..3d42e0deec 100644 --- a/samples/Basic_Debug/README.md +++ b/samples/Basic_Debug/README.md @@ -3,32 +3,64 @@ It relies on the GDBStub project to do the heavy-lifting. Exception Handling ------------------ -If there is an exception in your code usually ESP prints a message like the following one: +Sming comes with a built-in exception handling that takes care to display the stack trace +leading to the issue. Usually it looks like this ``` -Fatal exception (0): -epc1=0x4020997c, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000 +***** Fatal exception 28 +pc=0x40100e96 sp=0x3ffff640 excvaddr=0x000015b8 +ps=0x00000033 sar=0x00000018 vpri=0x000000f0 +r00: 0x40100d69=1074793833 r01: 0x3ffff640=1073739328 r02: 0x3fff3900=1073690880 +r03: 0x2b265ed4= 723934932 r04: 0x3fffbff0=1073725424 r05: 0x000015b8= 5560 +r06: 0x000015b8= 5560 r07: 0x14a8433b= 346571579 r08: 0x00000008= 8 +r09: 0x14a842f3= 346571507 r10: 0x3fff22d0=1073685200 r11: 0x00000003= 3 +r12: 0x00000048= 72 r13: 0x3fff38c0=1073690816 r14: 0x3ffe9da0=1073651104 +r15: 0x3fff1138=1073680696 + +Stack dump: +To decode the stack dump call from command line: + python $SMING_HOME/../tools/decode-stacktrace.py out/build/app.out +and copy & paste the text enclosed in '===='. +================================================================ +3ffff640: 40100e96 00000033 00000018 000000f0 +3ffff650: 40100d69 3fff3900 2b265ed4 3fffbff0 +3ffff660: 000015b8 000015b8 14a8433b 00000008 +3ffff670: 14a842f3 3fff22d0 00000003 00000048 +3ffff680: 3fff38c0 3ffe9da0 3fff1138 0000001c +3ffff690: 002222fb c0fb5c01 0bc10000 facfd1fb +3ffff6a0: 620020c0 6162802d 0020c004 59062c52 +3ffff6b0: 0020c051 61492c48 210020c0 7c38fb50 +... + +================================================================ ``` -That information can help you discover the function call that caused the exception. -Using the value of epc1 and executing a command like the one below: +With the help of `decode-stacktrace.py` you can decode the stack trace to something readable like: -```bash -xtensa-lx106-elf-objdump -dtr out/build/app.out | grep 4020997c -``` - -can give you an idea about the function. In my test case this is: ``` -4020997c: fffe61 l32r a6, 40209974 +0x40100e96: pvPortRealloc at ??: ? +0x40100d69: pvPortMalloc at ??:? +0x402455f0: ax_port_malloc at C:\tools\Sming-3.1.2\Sming/third-party/axtls-8266/ replacements/mem.c:51 +0x4024561a: ax_port_calloc at C:\tools\Sming-3.1.2\Sming/third-party/axtls-8266/ replacements/mem.c:63 +0x40230acc: x509_new at c:\tools\Sming-3.1.2\Sming\third-party\axtls-8266/ssl/x5 09.c:81 +0x4023d3e4: m_vsnprintf at C:\tools\Sming-3.1.2\Sming/system/m_printf.cpp:69 +0x4023d4a6: m_vprintf at C:\tools\Sming-3.1.2\Sming/system/m_printf.cpp:83 +0x40000a39: ?? ??:0 +0x4021418a: pp_attach at ??:? +0x40221d60: pbuf_alloc at ??:? +0x40221f0a: pbuf_copy at ??:? +0x4023d3e4: m_vsnprintf at C:\tools\Sming-3.1.2\Sming/system/m_printf.cpp:69 ``` -But that information might not be enough to find the issue. And finding the +Using the information about the type of the exception (ex: `***** Fatal exception 28`) +and the sequence of commands might help us figure out the issue. + +But that information might not be enough. And finding the root cause may take quite some time. GDB Debugging ------------- -Debugging is a powerful technique giving better understanding of the code and -the things that went wrong. +Debugging is a powerful technique allowing you to interactively run your code and be able to see much more information about the things that went wrong. There is already existing GDBStub that tries to make it easier to use software debugger. And this project is an example of what you need to do in order to @@ -36,25 +68,17 @@ integrate it. Here are the commands that you need to execute: -1. Fetch the [GDBStub](https://github.com/espressif/esp-gdbstub) by -executing the following commands ( usually needs to be done only once). - -```bash -git submodule init -git submodule update --recursive -``` - -2. You will need a version of the sming library with enabled GDBStub functionality. +1. You will need a version of the Sming library with enabled GDBStub functionality. For that purpose you should compile Sming with ENABLE_GDB flag. Under Linux you should do the following: ```bash -cd /Sming -make clean +cd $SMING_HOME +make dist-clean ENABLE_GDB=1 make ``` -3. In you project inside of you Makefile-user.mk file you should add the following +2. In your project inside of your Makefile-user.mk file you should add the following variable: ```make @@ -64,13 +88,13 @@ ENABLE_GDB=1 If you are looking for an example then take a look at the Makefile-user.mk file that is in the same directory as this README.md file. -4. Now compile your project and flash it to the board. +3. Now compile your project and flash it to the board. ```bash -make +make ENABLE_GDB=1 make flash ``` -5. Run gdb immediately after resetting the board or after it has run into an exception. +4. Run gdb 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: ```bash xtensa-lx106-elf-gdb -x /Basic_Debug/gdbcmds -b 115200 @@ -79,7 +103,7 @@ xtensa-lx106-elf-gdb -x /Basic_Debug/gdbcmds -b 115200 115200 stands for the baud rate your program is using. Change it accordingly. You may also need to change the gdbcmds script to fit the configuration of your hardware and build environment. -6. Software breakpoints ('br') only work on code that is in RAM. During development you can use the GDB_IRAM_ATTR attribute in your function declarations. +5. Software breakpoints ('br') only work on code that is in RAM. During development you can use the GDB_IRAM_ATTR attribute in your function declarations. Code in flash can only have a hardware breakpoint ('hbr'). Read the [Notes](https://github.com/espressif/esp-gdbstub#notes) for more information.