74 lines
2.5 KiB
ReStructuredText
74 lines
2.5 KiB
ReStructuredText
=========================
|
|
Run time stack statistics
|
|
=========================
|
|
|
|
Introduce
|
|
=========
|
|
When debugging code, it is often necessary to focus on how to track
|
|
the maximum stack usage of the calling functions in order to optimize
|
|
the code structure and reduce stack usage. This article will introduce
|
|
a method based on the running state to track the deepest call stack of all tasks.
|
|
|
|
Configuration
|
|
=============
|
|
.. code-block:: c
|
|
|
|
CONFIG_SCHED_STACKRECORD=32
|
|
CONFIG_ARCH_INSTRUMENT_ALL=y
|
|
|
|
```CONFIG_SCHED_STACKRECORD``` is used to record the maximum stack usage of all tasks
|
|
```CONFIG_ARCH_INSTRUMENT_ALL``` is used to instrument all code.
|
|
|
|
Please note that CONFIG_ARCH_INSTRUMENT_ALL is not necessary.
|
|
This configuration option will instrument all code,
|
|
but if you only want to instrument specific functions,
|
|
you can add '-finstrument-functions' to the corresponding makefile.
|
|
|
|
Example
|
|
=======
|
|
1. ```./tools/configure.sh esp32c3-devkit:stack```
|
|
2. ```make -j20```
|
|
3. flash the image to your board
|
|
.. code-block :: bash
|
|
|
|
nsh> cat /proc/1/stack
|
|
StackAlloc: 0x3fc8b5b0
|
|
StackBase: 0x3fc8b5e0
|
|
StackSize: 2000
|
|
MaxStackUsed:1344
|
|
Backtrace Size
|
|
0x42009198 32
|
|
0x42009200 48
|
|
0x420081a0 128
|
|
0x42008d18 64
|
|
0x4201da60 80
|
|
0x420199e0 80
|
|
0x42018c6c 48
|
|
0x420194f4 48
|
|
0x42017d30 32
|
|
0x4201634c 32
|
|
0x420163ac 48
|
|
0x42016408 32
|
|
0x420132c0 48
|
|
0x42010598 32
|
|
0x4200fd98 48
|
|
0x4200f5dc 80
|
|
0x4200f8e0 160
|
|
|
|
Implementation details
|
|
======================
|
|
The specific principle is based on the instrumentation of gcc.
|
|
In the TCB (Thread Control Block) of the corresponding task,
|
|
the maximum value of the stack pointer (sp) is recorded at the entry of each function.
|
|
If it is the maximum value, the backtrace is recorded.
|
|
|
|
Notice
|
|
======
|
|
Be cautious when using the CONFIG_ARCH_INSTRUMENT_ALL option:
|
|
1. It will instrument every function, which may have a risk of recursion.
|
|
2. It will also instrument entry functions, such as _start(). At this point,
|
|
the bss segment and data segment have not been initialized,
|
|
which may cause errors. The current implementation uses a magic number to avoid this,
|
|
but it performs poorly during hot start. The solution is to mark
|
|
the entry function with the noinstrument_function flag to prevent instrumentation.
|