Skip to content

Commit e67c95c

Browse files
committed
Update documentation
Describe how to improve Exception Decoder results. Updated build option details.
1 parent e25f9e9 commit e67c95c

File tree

4 files changed

+78
-59
lines changed

4 files changed

+78
-59
lines changed

cores/esp8266/debug.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
#ifdef DEBUG_ESP_CORE
88
#define DEBUGV(fmt, ...) ::printf((PGM_P)PSTR(fmt), ##__VA_ARGS__)
9+
#define DEBUG_LEAF_FUNCTION(...) __asm__ __volatile__("" ::: "a0", "memory")
10+
#else
11+
#define DEBUG_LEAF_FUNCTION(...)
912
#endif
1013

1114
#ifndef DEBUGV

doc/Troubleshooting/stack_dump.rst

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,42 +12,42 @@ Example:
1212

1313
Exception (0): epc1=0x402103f4 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
1414

15-
ctx: sys
15+
ctx: sys
1616
sp: 3ffffc10 end: 3fffffb0 offset: 01a0
1717

1818
>>>stack>>>
19-
3ffffdb0: 40223e00 3fff6f50 00000010 60000600
20-
3ffffdc0: 00000001 4021f774 3fffc250 4000050c
21-
3ffffdd0: 400043d5 00000030 00000016 ffffffff
22-
3ffffde0: 400044ab 3fffc718 3ffffed0 08000000
23-
3ffffdf0: 60000200 08000000 00000003 00000000
24-
3ffffe00: 0000ffff 00000001 04000002 003fd000
25-
3ffffe10: 3fff7188 000003fd 3fff2564 00000030
26-
3ffffe20: 40101709 00000008 00000008 00000020
27-
3ffffe30: c1948db3 394c5e70 7f2060f2 c6ba0c87
28-
3ffffe40: 3fff7058 00000001 40238d41 3fff6ff0
29-
3ffffe50: 3fff6f50 00000010 60000600 00000020
30-
3ffffe60: 402301a8 3fff7098 3fff7014 40238c77
31-
3ffffe70: 4022fb6c 40230ebe 3fff1a5b 3fff6f00
32-
3ffffe80: 3ffffec8 00000010 40231061 3fff0f90
33-
3ffffe90: 3fff6848 3ffed0c0 60000600 3fff6ae0
34-
3ffffea0: 3fff0f90 3fff0f90 3fff6848 3fff6d40
35-
3ffffeb0: 3fff28e8 40101233 d634fe1a fffeffff
36-
3ffffec0: 00000001 00000000 4022d5d6 3fff6848
37-
3ffffed0: 00000002 4000410f 3fff2394 3fff6848
38-
3ffffee0: 3fffc718 40004a3c 000003fd 3fff7188
39-
3ffffef0: 3fffc718 40101510 00000378 3fff1a5b
40-
3fffff00: 000003fd 4021d2e7 00000378 000003ff
41-
3fffff10: 00001000 4021d37d 3fff2564 000003ff
42-
3fffff20: 000003fd 60000600 003fd000 3fff2564
43-
3fffff30: ffffff00 55aa55aa 00000312 0000001c
44-
3fffff40: 0000001c 0000008a 0000006d 000003ff
45-
3fffff50: 4021d224 3ffecf90 00000000 3ffed0c0
46-
3fffff60: 00000001 4021c2e9 00000003 3fff1238
47-
3fffff70: 4021c071 3ffecf84 3ffecf30 0026a2b0
48-
3fffff80: 4021c0b6 3fffdab0 00000000 3fffdcb0
49-
3fffff90: 3ffecf40 3fffdab0 00000000 3fffdcc0
50-
3fffffa0: 40000f49 40000f49 3fffdab0 40000f49
19+
3ffffdb0: 40223e00 3fff6f50 00000010 60000600
20+
3ffffdc0: 00000001 4021f774 3fffc250 4000050c
21+
3ffffdd0: 400043d5 00000030 00000016 ffffffff
22+
3ffffde0: 400044ab 3fffc718 3ffffed0 08000000
23+
3ffffdf0: 60000200 08000000 00000003 00000000
24+
3ffffe00: 0000ffff 00000001 04000002 003fd000
25+
3ffffe10: 3fff7188 000003fd 3fff2564 00000030
26+
3ffffe20: 40101709 00000008 00000008 00000020
27+
3ffffe30: c1948db3 394c5e70 7f2060f2 c6ba0c87
28+
3ffffe40: 3fff7058 00000001 40238d41 3fff6ff0
29+
3ffffe50: 3fff6f50 00000010 60000600 00000020
30+
3ffffe60: 402301a8 3fff7098 3fff7014 40238c77
31+
3ffffe70: 4022fb6c 40230ebe 3fff1a5b 3fff6f00
32+
3ffffe80: 3ffffec8 00000010 40231061 3fff0f90
33+
3ffffe90: 3fff6848 3ffed0c0 60000600 3fff6ae0
34+
3ffffea0: 3fff0f90 3fff0f90 3fff6848 3fff6d40
35+
3ffffeb0: 3fff28e8 40101233 d634fe1a fffeffff
36+
3ffffec0: 00000001 00000000 4022d5d6 3fff6848
37+
3ffffed0: 00000002 4000410f 3fff2394 3fff6848
38+
3ffffee0: 3fffc718 40004a3c 000003fd 3fff7188
39+
3ffffef0: 3fffc718 40101510 00000378 3fff1a5b
40+
3fffff00: 000003fd 4021d2e7 00000378 000003ff
41+
3fffff10: 00001000 4021d37d 3fff2564 000003ff
42+
3fffff20: 000003fd 60000600 003fd000 3fff2564
43+
3fffff30: ffffff00 55aa55aa 00000312 0000001c
44+
3fffff40: 0000001c 0000008a 0000006d 000003ff
45+
3fffff50: 4021d224 3ffecf90 00000000 3ffed0c0
46+
3fffff60: 00000001 4021c2e9 00000003 3fff1238
47+
3fffff70: 4021c071 3ffecf84 3ffecf30 0026a2b0
48+
3fffff80: 4021c0b6 3fffdab0 00000000 3fffdcb0
49+
3fffff90: 3ffecf40 3fffdab0 00000000 3fffdcc0
50+
3fffffa0: 40000f49 40000f49 3fffdab0 40000f49
5151
<<<stack<<<
5252

5353
The first number after ``Exception`` gives the cause of the reset. a
@@ -63,3 +63,5 @@ It's possible to decode the Stack to readable information. For more info see the
6363
:alt: ESP Exception Decoder
6464

6565
ESP Exception Decoder
66+
67+
For more on troubleshooting, read `My ESP Crashes <../faq/a02-my-esp-crashes.rst>`__.

doc/faq/a02-my-esp-crashes.rst

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ If you don't have any code for troubleshooting, use the example below:
236236

237237
void loop(){}
238238

239+
239240
Enable the Out-Of-Memory (*OOM*) debug option (in the *Tools > Debug Level*
240241
menu), compile/flash/upload this code to your ESP (Ctrl+U) and start Serial
241242
Monitor (Ctrl+Shift+M). You should shortly see ESP restarting every couple
@@ -270,31 +271,50 @@ Decoder <https://github.com/me-no-dev/EspExceptionDecoder>`__ you can
270271
track down where the module is crashing whenever you see the stack trace
271272
dropped. The same procedure applies to crashes caused by exceptions.
272273

273-
Note: To decode the exact line of code where the application
274+
Notes:
275+
276+
To decode the exact line of code where the application
274277
crashed, you need to use ESP Exception Decoder in context of sketch
275278
you have just loaded to the module for diagnosis. Decoder is not
276279
able to correctly decode the stack trace dropped by some other
277280
application not compiled and loaded from your Arduino IDE.
278281

282+
To improve the results of the Exception Decoder, you can add
283+
`-fno-optimize-sibling-calls` to your build options. For details on how
284+
to do this, review `Global Build Options <a06-global-build-options.rst>`__.
285+
Turning off this optimization allows more caller addresses to be written
286+
to the stack aiding in crash decoding. Because of the limited stack space,
287+
there is the potential that removing this optimization could overflow the
288+
stack and cause a crash.
289+
290+
A crash in a leaf function may not leave the caller's address on the stack.
291+
The return address can stay in a register for the duration of the call.
292+
Resulting in a crash report identifying the crashing function without a
293+
trace of who called. You can encourage the compiler to save the caller's
294+
return address by adding an inline assembly trick
295+
`__asm__ __volatile__("" ::: "a0", "memory");` at the beginning of the
296+
function's body. Or instead, for a debug build conditional option, use the
297+
macro `DEBUG_LEAF_FUNCTION()` from `#include <debug.h>`.
298+
279299

280300
Other Causes for Crashes
281301
~~~~~~~~~~~~~~~~~~~~~~~~
282302

283303
Interrupt Service Routines
284-
By default, all functions are compiled into flash, which means that the
285-
cache may kick in for that code. However, the cache currently can't be used
286-
during hardware interrupts. That means that, if you use a hardware ISR, such as
287-
attachInterrupt(gpio, myISR, CHANGE) for a GPIO change, the ISR must have the
288-
IRAM_ATTR attribute declared. Not only that, but the entire function tree
304+
By default, all functions are compiled into flash, which means that the
305+
cache may kick in for that code. However, the cache currently can't be used
306+
during hardware interrupts. That means that, if you use a hardware ISR, such as
307+
attachInterrupt(gpio, myISR, CHANGE) for a GPIO change, the ISR must have the
308+
IRAM_ATTR attribute declared. Not only that, but the entire function tree
289309
called from the ISR must also have the IRAM_ATTR declared.
290310
Be aware that every function that has this attribute reduces available memory.
291311

292-
In addition, it is not possible to execute delay() or yield() from an ISR,
312+
In addition, it is not possible to execute delay() or yield() from an ISR,
293313
or do blocking operations, or operations that disable the interrupts, e.g.: read
294314
a DHT.
295315

296316
Finally, an ISR has very high restrictions on timing for the executed code, meaning
297-
that executed code should not take longer than a very few microseconds. It is
317+
that executed code should not take longer than a very few microseconds. It is
298318
considered best practice to set a flag within the ISR, and then from within the loop()
299319
check and clear that flag, and execute code.
300320

@@ -303,16 +323,16 @@ Asynchronous Callbacks
303323
than ISRs, but some restrictions still apply.
304324
It is not possible to execute delay() or yield() from an asynchronous callback.
305325
Timing is not as tight as an ISR, but it should remain below a few milliseconds. This
306-
is a guideline. The hard timing requirements depend on the WiFi configuration and
326+
is a guideline. The hard timing requirements depend on the WiFi configuration and
307327
amount of traffic. In general, the CPU must not be hogged by the user code, as the
308328
longer it is away from servicing the WiFi stack, the more likely that memory corruption
309329
can happen.
310330

311331
Memory, memory, memory
312332
Running out of heap is the **most common cause for crashes**. Because the build process for
313333
the ESP leaves out exceptions (they use memory), memory allocations that fail will do
314-
so silently. A typical example is when setting or concatenating a large String. If
315-
allocation has failed internally, then the internal string copy can corrupt data, and
334+
so silently. A typical example is when setting or concatenating a large String. If
335+
allocation has failed internally, then the internal string copy can corrupt data, and
316336
the ESP will crash.
317337

318338
In addition, doing many String concatenations in sequence, e.g.: using operator+()
@@ -348,9 +368,9 @@ Memory, memory, memory
348368
* If you use std libs like std::vector, make sure to call its ::reserve() method before filling it. This allows allocating only once, which reduces mem fragmentation, and makes sure that there are no empty unused slots left over in the container at the end.
349369

350370
Stack
351-
  The amount of stack in the ESP is tiny at only 4KB. For normal development in large systems, it
371+
  The amount of stack in the ESP is tiny at only 4KB. For normal development in large systems, it
352372
is good practice to use and abuse the stack, because it is faster for allocation/deallocation, the scope of the object is well defined, and deallocation automatically happens in reverse order as allocation, which means no mem fragmentation. However, with the tiny amount of stack available in the ESP, that practice is not really viable, at least not for big objects.
353-
373+
354374
* Large objects that have internally managed memory, such as String, std::string, std::vector, etc, are ok on the stack, because they internally allocate their buffers on the heap.
355375
* Large arrays on the stack, such as uint8_t buffer[2048] should be avoided on the stack and should be dynamically allocated instead (consider smart pointers).
356376
* Objects that have large data members, such as large arrays, should also be avoided on the stack, and should be dynamically allocated (consider smart pointers).
@@ -392,7 +412,7 @@ or `esp8266 / Arduino <https://github.com/esp8266/Arduino>`__ core,
392412
types and versions of O/S, you need to provide exact information on what
393413
your application is about. Only then, people willing to look into your
394414
issue may be able to compare it to a configuration they are familiar with.
395-
If you are lucky, they may even attempt to reproduce your issue on their
415+
If you are lucky, they may even attempt to reproduce your issue on their
396416
own equipment!
397417
This will be far more difficult if you provide only vague details,
398418
so somebody would need to ask you to find out what is really happening.

doc/faq/a06-global-build-options.rst

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
:orphan:
2-
31
How to specify global build defines and options
42
===============================================
53

@@ -181,10 +179,10 @@ their builds.
181179

182180
There are two solutions to this issue:
183181

184-
1. Turn off the “Aggressively Cache Compiled core” feature, by setting
182+
1. Do nothing, and rely on aggressive cache workaround built into the
183+
script.
184+
2. Turn off the “Aggressively Cache Compiled core” feature, by setting
185185
``compiler.cache_core=false``.
186-
2. Rely on the not ideal fail-safe, aggressive cache workaround built
187-
into the script.
188186

189187
Using “compiler.cache_core=false”
190188
---------------------------------
@@ -253,14 +251,10 @@ problem would be cleared after a reboot. Or you can manually cleanup the
253251

254252
**Arduino command-line option overrides**
255253

256-
The script needs to know the working value of ``compiler.cache_core``
257-
that the Arduino IDE uses when building. This script can learn the state
258-
through documented locations; however, the Arduino IDE has two
259-
command-line options that can alter the results the Arduino IDE uses
260-
internally. And, the Arduino IDE does not provide a means for a script
261-
to learn the override value.
254+
If you are building with ``compiler.cache_core=true`` no action is
255+
needed. If ``false`` the script would benefit by knowing that.
262256

263-
These two command-line options are the problem:
257+
When using either of these two command-line options:
264258

265259
::
266260

0 commit comments

Comments
 (0)