You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/12/11 10:06:57 UTC

(nuttx) branch master updated (404616d621 -> 1295ccdd0e)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


    from 404616d621 linux_Dockerfile: only copy gn binary into docker
     new 7dfbd14eba libc: add instrument api support
     new d932e0af2a sched/procfs:use instrument to statistics run time max stack
     new 94d449e722 arch:Mark key functions to prohibit instrumentation to prevent recursive calls
     new 25f599fe31 add demo for record stack defconfig
     new 1295ccdd0e Documentation:add Documentation for stack statistics

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Documentation/guides/index.rst                     |   1 +
 Documentation/guides/stackrecord.rst               |  73 +++++++++++++
 arch/Kconfig                                       |   7 ++
 arch/arm/include/armv7-a/irq.h                     |   4 +-
 arch/arm/include/armv7-m/irq.h                     |   6 +-
 arch/arm/include/armv8-m/irq.h                     |   6 +-
 arch/arm/include/irq.h                             |   3 +-
 arch/arm/src/armv7-a/sctlr.h                       |   1 +
 arch/arm/src/armv7-m/arm_stackcheck.c              |  26 +++--
 arch/arm/src/armv8-m/arm_stackcheck.c              |  26 +++--
 arch/arm/src/cmake/armv7-a.cmake                   |   4 +
 arch/arm/src/cmake/armv7-m.cmake                   |   4 +
 arch/arm/src/cmake/armv8-m.cmake                   |   4 +
 arch/arm/src/common/Toolchain.defs                 |   6 +
 arch/arm/src/common/arm_internal.h                 |   4 +
 arch/arm/src/eoss3/eoss3_start.c                   |   4 +
 arch/arm/src/gd32f4/gd32f4xx_start.c               |   4 +
 arch/arm/src/imxrt/imxrt_start.c                   |   4 +
 arch/arm/src/kinetis/kinetis_start.c               |   4 +
 arch/arm/src/lpc17xx_40xx/lpc17_40_start.c         |   4 +
 arch/arm/src/nrf52/nrf52_start.c                   |   4 +
 arch/arm/src/nrf53/nrf53_start.c                   |   4 +
 arch/arm/src/rtl8720c/ameba_start.c                |   5 +
 arch/arm/src/sam34/sam_start.c                     |   4 +
 arch/arm/src/samd5e5/sam_start.c                   |   4 +
 arch/arm/src/samv7/sam_start.c                     |   4 +
 arch/arm/src/stm32/stm32_start.c                   |   4 +
 arch/arm/src/stm32f7/stm32_start.c                 |   4 +
 arch/arm/src/stm32h7/stm32_start.c                 |   4 +
 arch/arm/src/stm32l4/stm32l4_start.c               |   4 +
 arch/arm/src/stm32l5/stm32l5_start.c               |   4 +
 arch/arm/src/stm32u5/stm32_start.c                 |   4 +
 arch/arm/src/stm32wb/stm32wb_start.c               |   4 +
 arch/arm/src/xmc4/xmc4_start.c                     |   4 +
 arch/arm64/src/Toolchain.defs                      |   6 +
 arch/risc-v/include/irq.h                          |   6 +-
 arch/risc-v/src/common/Toolchain.defs              |   6 +
 arch/sim/include/irq.h                             |   1 +
 arch/xtensa/include/irq.h                          |  10 +-
 arch/xtensa/src/esp32s3/esp32s3_start.c            |   6 +-
 arch/xtensa/src/lx6/Toolchain.defs                 |   6 +
 arch/xtensa/src/lx7/Toolchain.defs                 |   6 +
 .../stm32/stm32f429i-disco/configs/stack/defconfig |  56 ++++++++++
 boards/sim/sim/sim/scripts/Make.defs               |   4 +
 .../esp32s3/esp32s3-devkit/configs/stack/defconfig |  51 +++++++++
 drivers/note/note_driver.c                         |  66 +++++++----
 fs/procfs/fs_procfsproc.c                          |  53 +++++++++
 include/nuttx/compiler.h                           |   9 ++
 include/nuttx/instrument.h                         |  68 ++++++++++++
 include/nuttx/irq.h                                |   4 +-
 include/nuttx/sched.h                              |  11 ++
 libs/libc/misc/CMakeLists.txt                      |   3 +-
 libs/libc/misc/Make.defs                           |   2 +-
 libs/libc/misc/lib_instrument.c                    | 121 +++++++++++++++++++++
 sched/Kconfig                                      |  13 +++
 sched/Makefile                                     |   1 +
 sched/init/nx_start.c                              |   5 +
 sched/instrument/CMakeLists.txt                    |  27 +++++
 sched/instrument/Make.defs                         |  30 +++++
 sched/instrument/instrument.c                      |  58 ++++++++++
 sched/instrument/instrument.h                      |  44 ++++++++
 sched/instrument/stack_record.c                    | 112 +++++++++++++++++++
 sched/sched/sched.h                                |   2 +-
 63 files changed, 975 insertions(+), 64 deletions(-)
 create mode 100644 Documentation/guides/stackrecord.rst
 create mode 100644 boards/arm/stm32/stm32f429i-disco/configs/stack/defconfig
 create mode 100644 boards/xtensa/esp32s3/esp32s3-devkit/configs/stack/defconfig
 create mode 100644 include/nuttx/instrument.h
 create mode 100644 libs/libc/misc/lib_instrument.c
 create mode 100644 sched/instrument/CMakeLists.txt
 create mode 100644 sched/instrument/Make.defs
 create mode 100644 sched/instrument/instrument.c
 create mode 100644 sched/instrument/instrument.h
 create mode 100644 sched/instrument/stack_record.c


(nuttx) 03/05: arch:Mark key functions to prohibit instrumentation to prevent recursive calls

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 94d449e7226120f90ce7b222a5411e17eca84a44
Author: anjiahao <an...@xiaomi.com>
AuthorDate: Wed Oct 25 20:11:20 2023 +0800

    arch:Mark key functions to prohibit instrumentation to prevent recursive calls
    
    Signed-off-by: anjiahao <an...@xiaomi.com>
---
 arch/arm/include/armv7-a/irq.h          |  4 ++--
 arch/arm/include/armv7-m/irq.h          |  6 ++++--
 arch/arm/include/armv8-m/irq.h          |  6 ++++--
 arch/arm/include/irq.h                  |  3 ++-
 arch/arm/src/armv7-a/sctlr.h            |  1 +
 arch/risc-v/include/irq.h               |  6 +++---
 arch/xtensa/include/irq.h               | 10 +++++-----
 arch/xtensa/src/esp32s3/esp32s3_start.c |  6 +++---
 include/nuttx/irq.h                     |  4 ++--
 sched/sched/sched.h                     |  2 +-
 10 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/arch/arm/include/armv7-a/irq.h b/arch/arm/include/armv7-a/irq.h
index 6c12500911..d95e0b9545 100644
--- a/arch/arm/include/armv7-a/irq.h
+++ b/arch/arm/include/armv7-a/irq.h
@@ -350,7 +350,7 @@ static inline irqstate_t irqstate(void)
 
 /* Disable IRQs and return the previous IRQ state */
 
-static inline irqstate_t up_irq_save(void)
+noinstrument_function static inline irqstate_t up_irq_save(void)
 {
   unsigned int cpsr;
 
@@ -392,7 +392,7 @@ static inline irqstate_t up_irq_enable(void)
 
 /* Restore saved IRQ & FIQ state */
 
-static inline void up_irq_restore(irqstate_t flags)
+noinstrument_function static inline void up_irq_restore(irqstate_t flags)
 {
   __asm__ __volatile__
     (
diff --git a/arch/arm/include/armv7-m/irq.h b/arch/arm/include/armv7-m/irq.h
index f77ef08016..cfa94f44e5 100644
--- a/arch/arm/include/armv7-m/irq.h
+++ b/arch/arm/include/armv7-m/irq.h
@@ -394,7 +394,8 @@ static inline void up_irq_disable(void)
 
 /* Save the current primask state & disable IRQs */
 
-static inline irqstate_t up_irq_save(void) always_inline_function;
+static inline irqstate_t up_irq_save(void)
+always_inline_function noinstrument_function;
 static inline irqstate_t up_irq_save(void)
 {
 #ifdef CONFIG_ARMV7M_USEBASEPRI
@@ -437,7 +438,8 @@ static inline void up_irq_enable(void)
 
 /* Restore saved primask state */
 
-static inline void up_irq_restore(irqstate_t flags) always_inline_function;
+static inline void up_irq_restore(irqstate_t flags)
+always_inline_function noinstrument_function;
 static inline void up_irq_restore(irqstate_t flags)
 {
 #ifdef CONFIG_ARMV7M_USEBASEPRI
diff --git a/arch/arm/include/armv8-m/irq.h b/arch/arm/include/armv8-m/irq.h
index ed4620a265..a440a4da98 100644
--- a/arch/arm/include/armv8-m/irq.h
+++ b/arch/arm/include/armv8-m/irq.h
@@ -367,7 +367,8 @@ static inline void up_irq_disable(void)
 
 /* Save the current primask state & disable IRQs */
 
-static inline irqstate_t up_irq_save(void) always_inline_function;
+static inline irqstate_t up_irq_save(void)
+always_inline_function noinstrument_function;
 static inline irqstate_t up_irq_save(void)
 {
 #ifdef CONFIG_ARMV8M_USEBASEPRI
@@ -410,7 +411,8 @@ static inline void up_irq_enable(void)
 
 /* Restore saved primask state */
 
-static inline void up_irq_restore(irqstate_t flags) always_inline_function;
+static inline void up_irq_restore(irqstate_t flags)
+always_inline_function noinstrument_function;
 static inline void up_irq_restore(irqstate_t flags)
 {
 #ifdef CONFIG_ARMV8M_USEBASEPRI
diff --git a/arch/arm/include/irq.h b/arch/arm/include/irq.h
index 4d44388b75..69b47a3da1 100644
--- a/arch/arm/include/irq.h
+++ b/arch/arm/include/irq.h
@@ -116,7 +116,7 @@ EXTERN volatile uint32_t *g_current_regs[CONFIG_SMP_NCPUS];
  ****************************************************************************/
 
 #ifdef CONFIG_SMP
-int up_cpu_index(void);
+int up_cpu_index(void) noinstrument_function;
 #else
 #  define up_cpu_index() (0)
 #endif
@@ -134,6 +134,7 @@ int up_cpu_index(void);
  *
  ****************************************************************************/
 
+noinstrument_function
 static inline bool up_interrupt_context(void)
 {
 #ifdef CONFIG_SMP
diff --git a/arch/arm/src/armv7-a/sctlr.h b/arch/arm/src/armv7-a/sctlr.h
index c982a1080a..9f8b7cc24f 100644
--- a/arch/arm/src/armv7-a/sctlr.h
+++ b/arch/arm/src/armv7-a/sctlr.h
@@ -463,6 +463,7 @@ static inline unsigned int cp15_rdid(void)
 
 /* Get the Multiprocessor Affinity Register (MPIDR) */
 
+noinstrument_function
 static inline unsigned int cp15_rdmpidr(void)
 {
   return CP15_GET(MPIDR);
diff --git a/arch/risc-v/include/irq.h b/arch/risc-v/include/irq.h
index 54f0febbba..9d587b6d3d 100644
--- a/arch/risc-v/include/irq.h
+++ b/arch/risc-v/include/irq.h
@@ -680,7 +680,7 @@ int up_cpu_index(void);
  *
  ****************************************************************************/
 
-static inline irqstate_t up_irq_save(void)
+noinstrument_function static inline irqstate_t up_irq_save(void)
 {
   irqstate_t flags;
 
@@ -709,7 +709,7 @@ static inline irqstate_t up_irq_save(void)
  *
  ****************************************************************************/
 
-static inline void up_irq_restore(irqstate_t flags)
+noinstrument_function static inline void up_irq_restore(irqstate_t flags)
 {
   __asm__ __volatile__
     (
@@ -729,7 +729,7 @@ static inline void up_irq_restore(irqstate_t flags)
  *
  ****************************************************************************/
 
-static inline bool up_interrupt_context(void)
+noinstrument_function static inline bool up_interrupt_context(void)
 {
 #ifdef CONFIG_SMP
   irqstate_t flags = up_irq_save();
diff --git a/arch/xtensa/include/irq.h b/arch/xtensa/include/irq.h
index 9eaeb8ac97..ece60779f7 100644
--- a/arch/xtensa/include/irq.h
+++ b/arch/xtensa/include/irq.h
@@ -236,7 +236,7 @@ static inline uint32_t xtensa_getps(void)
 
 /* Set the value of the PS register */
 
-static inline void xtensa_setps(uint32_t ps)
+noinstrument_function static inline void xtensa_setps(uint32_t ps)
 {
   __asm__ __volatile__
   (
@@ -265,7 +265,7 @@ static inline uint32_t up_getsp(void)
 
 /* Restore the value of the PS register */
 
-static inline void up_irq_restore(uint32_t ps)
+noinstrument_function static inline void up_irq_restore(uint32_t ps)
 {
   __asm__ __volatile__
   (
@@ -279,7 +279,7 @@ static inline void up_irq_restore(uint32_t ps)
 
 /* Disable interrupts and return the previous value of the PS register */
 
-static inline uint32_t up_irq_save(void)
+noinstrument_function static inline uint32_t up_irq_save(void)
 {
   uint32_t ps;
 
@@ -313,7 +313,7 @@ static inline void up_irq_enable(void)
 
 /* Disable low- and medium- priority interrupts */
 
-static inline void up_irq_disable(void)
+noinstrument_function static inline void up_irq_disable(void)
 {
 #ifdef __XTENSA_CALL0_ABI__
   xtensa_setps(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM);
@@ -440,7 +440,7 @@ int up_cpu_index(void);
  ****************************************************************************/
 
 #ifndef __ASSEMBLY__
-static inline bool up_interrupt_context(void)
+noinstrument_function static inline bool up_interrupt_context(void)
 {
 #ifdef CONFIG_SMP
   irqstate_t flags = up_irq_save();
diff --git a/arch/xtensa/src/esp32s3/esp32s3_start.c b/arch/xtensa/src/esp32s3/esp32s3_start.c
index a42fcc2869..9b91277c03 100644
--- a/arch/xtensa/src/esp32s3/esp32s3_start.c
+++ b/arch/xtensa/src/esp32s3/esp32s3_start.c
@@ -170,7 +170,7 @@ uint32_t g_idlestack[IDLETHREAD_STACKWORDS]
  *
  ****************************************************************************/
 
-static void IRAM_ATTR configure_cpu_caches(void)
+noinstrument_function static void IRAM_ATTR configure_cpu_caches(void)
 {
   int s_instr_flash2spiram_off = 0;
   int s_rodata_flash2spiram_off = 0;
@@ -272,7 +272,7 @@ static void IRAM_ATTR disable_app_cpu(void)
  *
  ****************************************************************************/
 
-void noreturn_function IRAM_ATTR __esp32s3_start(void)
+noinstrument_function void noreturn_function IRAM_ATTR __esp32s3_start(void)
 {
   uint32_t sp;
 
@@ -508,7 +508,7 @@ static int map_rom_segments(void)
  *
  ****************************************************************************/
 
-void IRAM_ATTR __start(void)
+noinstrument_function void IRAM_ATTR __start(void)
 {
 #ifdef CONFIG_ESP32S3_APP_FORMAT_MCUBOOT
   if (map_rom_segments() != 0)
diff --git a/include/nuttx/irq.h b/include/nuttx/irq.h
index 7c3c4c1b52..2822f83e26 100644
--- a/include/nuttx/irq.h
+++ b/include/nuttx/irq.h
@@ -184,7 +184,7 @@ int irqchain_detach(int irq, xcpt_t isr, FAR void *arg);
  ****************************************************************************/
 
 #ifdef CONFIG_IRQCOUNT
-irqstate_t enter_critical_section(void);
+irqstate_t enter_critical_section(void) noinstrument_function;
 #else
 #  define enter_critical_section() up_irq_save()
 #endif
@@ -214,7 +214,7 @@ irqstate_t enter_critical_section(void);
  ****************************************************************************/
 
 #ifdef CONFIG_IRQCOUNT
-void leave_critical_section(irqstate_t flags);
+void leave_critical_section(irqstate_t flags) noinstrument_function;
 #else
 #  define leave_critical_section(f) up_irq_restore(f)
 #endif
diff --git a/sched/sched/sched.h b/sched/sched/sched.h
index 104d19ed8e..ceefc2b8c2 100644
--- a/sched/sched/sched.h
+++ b/sched/sched/sched.h
@@ -381,7 +381,7 @@ void nxsched_suspend(FAR struct tcb_s *tcb);
 #endif
 
 #ifdef CONFIG_SMP
-FAR struct tcb_s *this_task(void);
+FAR struct tcb_s *this_task(void) noinstrument_function;
 
 int  nxsched_select_cpu(cpu_set_t affinity);
 int  nxsched_pause_cpu(FAR struct tcb_s *tcb);


(nuttx) 05/05: Documentation:add Documentation for stack statistics

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 1295ccdd0e38930b5b9cdfc1ccf797654c499412
Author: anjiahao <an...@xiaomi.com>
AuthorDate: Wed Oct 25 22:30:26 2023 +0800

    Documentation:add Documentation for stack statistics
    
    Signed-off-by: anjiahao <an...@xiaomi.com>
---
 Documentation/guides/index.rst       |  1 +
 Documentation/guides/stackrecord.rst | 73 ++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+)

diff --git a/Documentation/guides/index.rst b/Documentation/guides/index.rst
index e8a8f5e253..9f092e140a 100644
--- a/Documentation/guides/index.rst
+++ b/Documentation/guides/index.rst
@@ -29,3 +29,4 @@ Guides
   automounter.rst
   stm32nullpointer.rst
   stm32ccm.rst
+  stackrecord.rst
diff --git a/Documentation/guides/stackrecord.rst b/Documentation/guides/stackrecord.rst
new file mode 100644
index 0000000000..13bad93b46
--- /dev/null
+++ b/Documentation/guides/stackrecord.rst
@@ -0,0 +1,73 @@
+=========================
+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.


(nuttx) 01/05: libc: add instrument api support

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 7dfbd14eba9253282a8fe5cbdb366602733d8672
Author: anjiahao <an...@xiaomi.com>
AuthorDate: Sun Oct 8 18:20:43 2023 +0800

    libc: add instrument api support
    
    Add registration function instrumentation API,
    which can achieve instrumentation of entering and
    exiting functions through the compiler's functionality.
    
    We can use CONFIG_ARCH_INSTRUMENT_ALL to add instrumentation for all
    source, or add '-finstrument-functions' to CFLAGS for Part of the
    source.
    
    Notice:
    1. use CONFIG_ARCH_INSTRUMENT_ALL must mark _start or entry noinstrument_function,
       becuase bss not set.
    2. Make sure your callbacks are not instrumented recursively.
    
    use instrument_register to register entry function and exit function.
    They will be called by the instrumented function
    
    Signed-off-by: anjiahao <an...@xiaomi.com>
---
 arch/Kconfig                               |   7 ++
 arch/arm/src/armv7-m/arm_stackcheck.c      |  26 ++++---
 arch/arm/src/armv8-m/arm_stackcheck.c      |  26 +++++--
 arch/arm/src/cmake/armv7-a.cmake           |   4 +
 arch/arm/src/cmake/armv7-m.cmake           |   4 +
 arch/arm/src/cmake/armv8-m.cmake           |   4 +
 arch/arm/src/common/Toolchain.defs         |   6 ++
 arch/arm/src/common/arm_internal.h         |   4 +
 arch/arm/src/eoss3/eoss3_start.c           |   4 +
 arch/arm/src/gd32f4/gd32f4xx_start.c       |   4 +
 arch/arm/src/imxrt/imxrt_start.c           |   4 +
 arch/arm/src/kinetis/kinetis_start.c       |   4 +
 arch/arm/src/lpc17xx_40xx/lpc17_40_start.c |   4 +
 arch/arm/src/nrf52/nrf52_start.c           |   4 +
 arch/arm/src/nrf53/nrf53_start.c           |   4 +
 arch/arm/src/rtl8720c/ameba_start.c        |   5 ++
 arch/arm/src/sam34/sam_start.c             |   4 +
 arch/arm/src/samd5e5/sam_start.c           |   4 +
 arch/arm/src/samv7/sam_start.c             |   4 +
 arch/arm/src/stm32/stm32_start.c           |   4 +
 arch/arm/src/stm32f7/stm32_start.c         |   4 +
 arch/arm/src/stm32h7/stm32_start.c         |   4 +
 arch/arm/src/stm32l4/stm32l4_start.c       |   4 +
 arch/arm/src/stm32l5/stm32l5_start.c       |   4 +
 arch/arm/src/stm32u5/stm32_start.c         |   4 +
 arch/arm/src/stm32wb/stm32wb_start.c       |   4 +
 arch/arm/src/xmc4/xmc4_start.c             |   4 +
 arch/arm64/src/Toolchain.defs              |   6 ++
 arch/risc-v/src/common/Toolchain.defs      |   6 ++
 arch/xtensa/src/lx6/Toolchain.defs         |   6 ++
 arch/xtensa/src/lx7/Toolchain.defs         |   6 ++
 boards/sim/sim/sim/scripts/Make.defs       |   4 +
 drivers/note/note_driver.c                 |  66 ++++++++++------
 include/nuttx/instrument.h                 |  68 ++++++++++++++++
 libs/libc/misc/CMakeLists.txt              |   3 +-
 libs/libc/misc/Make.defs                   |   2 +-
 libs/libc/misc/lib_instrument.c            | 121 +++++++++++++++++++++++++++++
 37 files changed, 403 insertions(+), 43 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index fd0103cd13..deccaf4007 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -335,6 +335,13 @@ config ARCH_COVERAGE_ALL
 		will get image size increased and performance decreased
 		significantly.
 
+config ARCH_INSTRUMENT_ALL
+	bool "Instrument All"
+	default n
+	---help---
+		Add instrument to all source files. we can use instrument_register
+		to register the instrument function.
+
 comment "Architecture Options"
 
 config ARCH_NOINTC
diff --git a/arch/arm/src/armv7-m/arm_stackcheck.c b/arch/arm/src/armv7-m/arm_stackcheck.c
index d7167a9c55..0dee2604ab 100644
--- a/arch/arm/src/armv7-m/arm_stackcheck.c
+++ b/arch/arm/src/armv7-m/arm_stackcheck.c
@@ -48,6 +48,7 @@
 
 #include <stdint.h>
 
+#include <nuttx/instrument.h>
 #include "arm_internal.h"
 #include "nvic.h"
 
@@ -55,10 +56,19 @@
  * Private Functions
  ****************************************************************************/
 
-void __cyg_profile_func_enter(void *func, void *caller) naked_function;
-void __cyg_profile_func_exit(void *func, void *caller) naked_function;
+static void stack_check_enter(void *func, void *caller, void *arg)
+                              naked_function;
 void __stack_overflow_trap(void) naked_function;
 
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct instrument_s g_stack_check =
+{
+  .enter = stack_check_enter,
+};
+
 /****************************************************************************
  * Name: __stack_overflow_trap
  ****************************************************************************/
@@ -87,10 +97,10 @@ void __stack_overflow_trap(void)
 }
 
 /****************************************************************************
- * Name: __cyg_profile_func_enter
+ * Name: stack_check_enter
  ****************************************************************************/
 
-void __cyg_profile_func_enter(void *func, void *caller)
+static void stack_check_enter(void *func, void *caller, void *arg)
 {
     asm volatile (
             "   mrs r2, ipsr        \n" /* Check whether we are in interrupt mode */
@@ -112,12 +122,8 @@ void __cyg_profile_func_enter(void *func, void *caller)
     );
 }
 
-/****************************************************************************
- * Name: __cyg_profile_func_exit
- ****************************************************************************/
-
-void __cyg_profile_func_exit(void *func, void *caller)
+void noinstrument_function arm_stack_check_init(void)
 {
-    asm volatile("bx lr");
+  instrument_register(&g_stack_check);
 }
 #endif
diff --git a/arch/arm/src/armv8-m/arm_stackcheck.c b/arch/arm/src/armv8-m/arm_stackcheck.c
index cbe107ca00..1d05fdd5db 100644
--- a/arch/arm/src/armv8-m/arm_stackcheck.c
+++ b/arch/arm/src/armv8-m/arm_stackcheck.c
@@ -48,6 +48,7 @@
 
 #include <stdint.h>
 
+#include <nuttx/instrument.h>
 #include "arm_internal.h"
 #include "nvic.h"
 
@@ -55,9 +56,18 @@
  * Private Functions
  ****************************************************************************/
 
-void  __cyg_profile_func_enter(void *func, void *caller) naked_function;
-void  __cyg_profile_func_exit(void *func, void *caller) naked_function;
-void  __stack_overflow_trap(void) naked_function;
+static void stack_check_enter(void *func, void *caller, void *arg)
+                              naked_function;
+void __stack_overflow_trap(void) naked_function;
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct instrument_s g_stack_check =
+{
+  .enter = stack_check_enter,
+};
 
 /****************************************************************************
  * Name: __stack_overflow_trap
@@ -87,10 +97,10 @@ void __stack_overflow_trap(void)
 }
 
 /****************************************************************************
- * Name: __cyg_profile_func_enter
+ * Name: stack_check_enter
  ****************************************************************************/
 
-void __cyg_profile_func_enter(void *func, void *caller)
+static void stack_check_enter(void *func, void *caller, void *arg)
 {
     asm volatile (
             "   mrs r2, ipsr        \n" /* Check whether we are in interrupt mode */
@@ -113,11 +123,11 @@ void __cyg_profile_func_enter(void *func, void *caller)
 }
 
 /****************************************************************************
- * Name: __cyg_profile_func_exit
+ * Name: arm_stack_check_init
  ****************************************************************************/
 
-void __cyg_profile_func_exit(void *func, void *caller)
+void noinstrument_function arm_stack_check_init(void)
 {
-    asm volatile("bx lr");
+  instrument_register(&g_stack_check);
 }
 #endif
diff --git a/arch/arm/src/cmake/armv7-a.cmake b/arch/arm/src/cmake/armv7-a.cmake
index 8566b54539..58a08fbeef 100644
--- a/arch/arm/src/cmake/armv7-a.cmake
+++ b/arch/arm/src/cmake/armv7-a.cmake
@@ -65,4 +65,8 @@ else()
   list(APPEND PLATFORM_FLAGS -mfloat-abi=soft)
 endif()
 
+if(CONFIG_ARCH_INSTRUMENT_ALL AND NOT CONFIG_ARMV8M_STACKCHECK)
+  list(APPEND PLATFORM_FLAGS -finstrument-functions)
+endif()
+
 add_compile_options(${PLATFORM_FLAGS})
diff --git a/arch/arm/src/cmake/armv7-m.cmake b/arch/arm/src/cmake/armv7-m.cmake
index 74dcd06fd2..f04f8379c2 100644
--- a/arch/arm/src/cmake/armv7-m.cmake
+++ b/arch/arm/src/cmake/armv7-m.cmake
@@ -90,4 +90,8 @@ if(CONFIG_ARMV7M_STACKCHECK)
   list(APPEND PLATFORM_FLAGS -finstrument-functions -ffixed-r10)
 endif()
 
+if(CONFIG_ARCH_INSTRUMENT_ALL AND NOT CONFIG_ARMV7M_STACKCHECK)
+  list(APPEND PLATFORM_FLAGS -finstrument-functions)
+endif()
+
 add_compile_options(${PLATFORM_FLAGS})
diff --git a/arch/arm/src/cmake/armv8-m.cmake b/arch/arm/src/cmake/armv8-m.cmake
index 5b1adf0c2c..514006f5af 100644
--- a/arch/arm/src/cmake/armv8-m.cmake
+++ b/arch/arm/src/cmake/armv8-m.cmake
@@ -65,6 +65,10 @@ if(CONFIG_ARMV8M_STACKCHECK)
   list(APPEND PLATFORM_FLAGS -finstrument-functions -ffixed-r10)
 endif()
 
+if(CONFIG_ARCH_INSTRUMENT_ALL AND NOT CONFIG_ARMV8M_STACKCHECK)
+  list(APPEND PLATFORM_FLAGS -finstrument-functions)
+endif()
+
 if(CONFIG_ARMV8M_CMSE)
   list(APPEND PLATFORM_FLAGS -mcmse)
 endif()
diff --git a/arch/arm/src/common/Toolchain.defs b/arch/arm/src/common/Toolchain.defs
index 991ce31b81..1e0184abc5 100644
--- a/arch/arm/src/common/Toolchain.defs
+++ b/arch/arm/src/common/Toolchain.defs
@@ -86,6 +86,12 @@ ifeq ($(CONFIG_MM_KASAN_DISABLE_WRITES_CHECK),y)
   ARCHOPTIMIZATION += --param asan-instrument-writes=0
 endif
 
+# Instrumentation options
+
+ifeq ($(CONFIG_ARCH_INSTRUMENT_ALL),y)
+  ARCHOPTIMIZATION += -finstrument-functions
+endif
+
 ifeq ($(CONFIG_UNWINDER_ARM),y)
   ARCHOPTIMIZATION += -funwind-tables -fasynchronous-unwind-tables
 endif
diff --git a/arch/arm/src/common/arm_internal.h b/arch/arm/src/common/arm_internal.h
index 40b4b409f8..271aa05e28 100644
--- a/arch/arm/src/common/arm_internal.h
+++ b/arch/arm/src/common/arm_internal.h
@@ -531,6 +531,10 @@ int arm_gen_nonsecurefault(int irq, uint32_t *regs);
 # define arm_gen_nonsecurefault(i, r)  (0)
 #endif
 
+#if defined(CONFIG_ARMV7M_STACKCHECK) || defined(CONFIG_ARMV8M_STACKCHECK)
+void arm_stack_check_init(void) noinstrument_function;
+#endif
+
 #undef EXTERN
 #ifdef __cplusplus
 }
diff --git a/arch/arm/src/eoss3/eoss3_start.c b/arch/arm/src/eoss3/eoss3_start.c
index b1bcd96b37..560a3fe116 100644
--- a/arch/arm/src/eoss3/eoss3_start.c
+++ b/arch/arm/src/eoss3/eoss3_start.c
@@ -152,6 +152,10 @@ void __start(void)
 
   showprogress('C');
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
 #ifdef CONFIG_ARMV7M_ITMSYSLOG
   /* Perform ARMv7-M ITM SYSLOG initialization */
 
diff --git a/arch/arm/src/gd32f4/gd32f4xx_start.c b/arch/arm/src/gd32f4/gd32f4xx_start.c
index 0ea5e0a7c9..70a09d4924 100644
--- a/arch/arm/src/gd32f4/gd32f4xx_start.c
+++ b/arch/arm/src/gd32f4/gd32f4xx_start.c
@@ -237,6 +237,10 @@ void __start(void)
       *dest++ = *src++;
     }
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
   /* Configure the UART so that we can get debug output as soon as possible */
 
   gd32_clockconfig();
diff --git a/arch/arm/src/imxrt/imxrt_start.c b/arch/arm/src/imxrt/imxrt_start.c
index b5aa9c7fc0..cc51d70e4e 100644
--- a/arch/arm/src/imxrt/imxrt_start.c
+++ b/arch/arm/src/imxrt/imxrt_start.c
@@ -210,6 +210,10 @@ void __start(void)
     }
 #endif
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
   /* Configure the UART so that we can get debug output as soon as possible */
 
   imxrt_clockconfig();
diff --git a/arch/arm/src/kinetis/kinetis_start.c b/arch/arm/src/kinetis/kinetis_start.c
index 085adf9c1b..c46abe0bec 100644
--- a/arch/arm/src/kinetis/kinetis_start.c
+++ b/arch/arm/src/kinetis/kinetis_start.c
@@ -153,6 +153,10 @@ void __start(void)
     }
 #endif
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
   /* Perform clock and Kinetis module initialization (This depends on
    * RAM functions having been copied to RAM).
    */
diff --git a/arch/arm/src/lpc17xx_40xx/lpc17_40_start.c b/arch/arm/src/lpc17xx_40xx/lpc17_40_start.c
index 0fb65df0d0..eee92a234e 100644
--- a/arch/arm/src/lpc17xx_40xx/lpc17_40_start.c
+++ b/arch/arm/src/lpc17xx_40xx/lpc17_40_start.c
@@ -153,6 +153,10 @@ void __start(void)
 
   showprogress('C');
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
   /* Perform early serial initialization */
 
 #ifdef USE_EARLYSERIALINIT
diff --git a/arch/arm/src/nrf52/nrf52_start.c b/arch/arm/src/nrf52/nrf52_start.c
index 2e3bf74b61..bc34a93d38 100644
--- a/arch/arm/src/nrf52/nrf52_start.c
+++ b/arch/arm/src/nrf52/nrf52_start.c
@@ -188,6 +188,10 @@ void __start(void)
 
   showprogress('C');
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
 #if defined(CONFIG_ARCH_CHIP_NRF52832)
   /* Initialize the errdata work-around */
 
diff --git a/arch/arm/src/nrf53/nrf53_start.c b/arch/arm/src/nrf53/nrf53_start.c
index 07458a7659..b58c9112d7 100644
--- a/arch/arm/src/nrf53/nrf53_start.c
+++ b/arch/arm/src/nrf53/nrf53_start.c
@@ -236,6 +236,10 @@ void __start(void)
 
   showprogress('C');
 
+#ifdef CONFIG_ARMV8M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
 #ifdef CONFIG_ARCH_HAVE_FPU
   /* Initialize the FPU (if available) */
 
diff --git a/arch/arm/src/rtl8720c/ameba_start.c b/arch/arm/src/rtl8720c/ameba_start.c
index 3cafd0240a..df0cd4a11b 100644
--- a/arch/arm/src/rtl8720c/ameba_start.c
+++ b/arch/arm/src/rtl8720c/ameba_start.c
@@ -77,6 +77,11 @@ int promisc_recv_lens_func(void *padapter, uint8_t *payload, uint8_t plen)
 void app_start(void)
 {
   __asm volatile("MSR msplim, %0" : : "r"(0));
+
+#ifdef CONFIG_ARMV8M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
   arm_earlyserialinit();
 #ifdef CONFIG_MBEDTLS240_AMEBAZ_HARDWARE_CRYPTO
   extern int mbedtls_platform_set_calloc_free(
diff --git a/arch/arm/src/sam34/sam_start.c b/arch/arm/src/sam34/sam_start.c
index 553f665b80..dac801ef10 100644
--- a/arch/arm/src/sam34/sam_start.c
+++ b/arch/arm/src/sam34/sam_start.c
@@ -164,6 +164,10 @@ void __start(void)
     }
 #endif
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
   /* Configure the UART so that we can get debug output as soon as possible */
 
   sam_clockconfig();
diff --git a/arch/arm/src/samd5e5/sam_start.c b/arch/arm/src/samd5e5/sam_start.c
index 689108d911..443d0a7bea 100644
--- a/arch/arm/src/samd5e5/sam_start.c
+++ b/arch/arm/src/samd5e5/sam_start.c
@@ -167,6 +167,10 @@ void __start(void)
     }
 #endif
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
   /* Initialize clocking and the FPU.  Configure the console UART so that
    * we can get debug output as soon as possible.
    */
diff --git a/arch/arm/src/samv7/sam_start.c b/arch/arm/src/samv7/sam_start.c
index e2c4f1f4cb..a6c1c6170a 100644
--- a/arch/arm/src/samv7/sam_start.c
+++ b/arch/arm/src/samv7/sam_start.c
@@ -199,6 +199,10 @@ void __start(void)
     }
 #endif
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
   /* Configure the UART so that we can get debug output as soon as possible */
 
   sam_clockconfig();
diff --git a/arch/arm/src/stm32/stm32_start.c b/arch/arm/src/stm32/stm32_start.c
index c369d1c7db..973c752389 100644
--- a/arch/arm/src/stm32/stm32_start.c
+++ b/arch/arm/src/stm32/stm32_start.c
@@ -158,6 +158,10 @@ void __start(void)
 
   showprogress('C');
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
 #ifdef CONFIG_ARCH_PERF_EVENTS
   up_perf_init((void *)STM32_SYSCLK_FREQUENCY);
 #endif
diff --git a/arch/arm/src/stm32f7/stm32_start.c b/arch/arm/src/stm32f7/stm32_start.c
index e333385fed..a37e63e7e2 100644
--- a/arch/arm/src/stm32f7/stm32_start.c
+++ b/arch/arm/src/stm32f7/stm32_start.c
@@ -223,6 +223,10 @@ void __start(void)
     }
 #endif
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
   /* Configure the UART so that we can get debug output as soon as possible */
 
   stm32_clockconfig();
diff --git a/arch/arm/src/stm32h7/stm32_start.c b/arch/arm/src/stm32h7/stm32_start.c
index 9959d49f9d..7bd4013e48 100644
--- a/arch/arm/src/stm32h7/stm32_start.c
+++ b/arch/arm/src/stm32h7/stm32_start.c
@@ -239,6 +239,10 @@ void __start(void)
     }
 #endif
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
   /* Configure the UART so that we can get debug output as soon as possible */
 
   stm32_clockconfig();
diff --git a/arch/arm/src/stm32l4/stm32l4_start.c b/arch/arm/src/stm32l4/stm32l4_start.c
index c95e6e1225..7b5b9a7977 100644
--- a/arch/arm/src/stm32l4/stm32l4_start.c
+++ b/arch/arm/src/stm32l4/stm32l4_start.c
@@ -179,6 +179,10 @@ void __start(void)
 
   showprogress('C');
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
 #ifdef CONFIG_ARCH_PERF_EVENTS
   up_perf_init((void *)STM32_SYSCLK_FREQUENCY);
 #endif
diff --git a/arch/arm/src/stm32l5/stm32l5_start.c b/arch/arm/src/stm32l5/stm32l5_start.c
index 1f09ed1046..47efcf57e7 100644
--- a/arch/arm/src/stm32l5/stm32l5_start.c
+++ b/arch/arm/src/stm32l5/stm32l5_start.c
@@ -181,6 +181,10 @@ void __start(void)
 
   showprogress('C');
 
+#ifdef CONFIG_ARMV8M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
 #ifdef CONFIG_ARCH_PERF_EVENTS
   up_perf_init((void *)STM32_SYSCLK_FREQUENCY);
 #endif
diff --git a/arch/arm/src/stm32u5/stm32_start.c b/arch/arm/src/stm32u5/stm32_start.c
index cbb0c640f8..2f4572325e 100644
--- a/arch/arm/src/stm32u5/stm32_start.c
+++ b/arch/arm/src/stm32u5/stm32_start.c
@@ -181,6 +181,10 @@ void __start(void)
 
   showprogress('C');
 
+#ifdef CONFIG_ARMV8M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
 #ifdef CONFIG_ARCH_PERF_EVENTS
   up_perf_init((void *)STM32_SYSCLK_FREQUENCY);
 #endif
diff --git a/arch/arm/src/stm32wb/stm32wb_start.c b/arch/arm/src/stm32wb/stm32wb_start.c
index 6ab5605da8..2f829f8d03 100644
--- a/arch/arm/src/stm32wb/stm32wb_start.c
+++ b/arch/arm/src/stm32wb/stm32wb_start.c
@@ -199,6 +199,10 @@ void __start(void)
 
   showprogress('C');
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
 #ifdef CONFIG_ARCH_PERF_EVENTS
   up_perf_init((void *)STM32_SYSCLK_FREQUENCY);
 #endif
diff --git a/arch/arm/src/xmc4/xmc4_start.c b/arch/arm/src/xmc4/xmc4_start.c
index 4e55e7ec21..b40f5502dd 100644
--- a/arch/arm/src/xmc4/xmc4_start.c
+++ b/arch/arm/src/xmc4/xmc4_start.c
@@ -220,6 +220,10 @@ void __start(void)
     }
 #endif
 
+#ifdef CONFIG_ARMV7M_STACKCHECK
+  arm_stack_check_init();
+#endif
+
   /* Set FLASH wait states prior to the configuration of clocking */
 
   xmc4_flash_waitstates();
diff --git a/arch/arm64/src/Toolchain.defs b/arch/arm64/src/Toolchain.defs
index efebeb5651..214b481d5e 100644
--- a/arch/arm64/src/Toolchain.defs
+++ b/arch/arm64/src/Toolchain.defs
@@ -84,6 +84,12 @@ ifeq ($(CONFIG_MM_KASAN_ALL),y)
   ARCHOPTIMIZATION += -fsanitize=kernel-address
 endif
 
+# Instrumentation options
+
+ifeq ($(CONFIG_ARCH_INSTRUMENT_ALL),y)
+  ARCHOPTIMIZATION += -finstrument-functions
+endif
+
 ifeq ($(CONFIG_ARCH_FPU),y)
   ARCHCXXFLAGS += -D_LDBL_EQ_DBL
   ARCHCFLAGS   += -D_LDBL_EQ_DBL
diff --git a/arch/risc-v/src/common/Toolchain.defs b/arch/risc-v/src/common/Toolchain.defs
index 61d7f270c3..3d0e5296a9 100644
--- a/arch/risc-v/src/common/Toolchain.defs
+++ b/arch/risc-v/src/common/Toolchain.defs
@@ -251,6 +251,12 @@ ifeq ($(CONFIG_MM_UBSAN_TRAP_ON_ERROR),y)
   ARCHOPTIMIZATION += -fsanitize-undefined-trap-on-error
 endif
 
+# Instrumentation options
+
+ifeq ($(CONFIG_ARCH_INSTRUMENT_ALL),y)
+  ARCHOPTIMIZATION += -finstrument-functions
+endif
+
 # Default toolchain
 
 CC      = $(CROSSDEV)gcc
diff --git a/arch/xtensa/src/lx6/Toolchain.defs b/arch/xtensa/src/lx6/Toolchain.defs
index 1be4627c92..686dc70087 100644
--- a/arch/xtensa/src/lx6/Toolchain.defs
+++ b/arch/xtensa/src/lx6/Toolchain.defs
@@ -95,6 +95,12 @@ ifeq ($(CONFIG_ARCH_COVERAGE_ALL),y)
   ARCHOPTIMIZATION += -fprofile-generate -ftest-coverage
 endif
 
+# Instrumentation options
+
+ifeq ($(CONFIG_ARCH_INSTRUMENT_ALL),y)
+  ARCHOPTIMIZATION += -finstrument-functions
+endif
+
 ARCHCFLAGS += -fno-common
 ARCHCXXFLAGS += -fno-common -nostdinc++
 
diff --git a/arch/xtensa/src/lx7/Toolchain.defs b/arch/xtensa/src/lx7/Toolchain.defs
index 710b19677d..6d5da909cf 100644
--- a/arch/xtensa/src/lx7/Toolchain.defs
+++ b/arch/xtensa/src/lx7/Toolchain.defs
@@ -99,6 +99,12 @@ ifeq ($(CONFIG_ARCH_COVERAGE_ALL),y)
   ARCHOPTIMIZATION += -fprofile-generate -ftest-coverage
 endif
 
+# Instrumentation options
+
+ifeq ($(CONFIG_ARCH_INSTRUMENT_ALL),y)
+  ARCHOPTIMIZATION += -finstrument-functions
+endif
+
 ARCHCFLAGS += -fno-common
 ARCHCXXFLAGS += -fno-common -nostdinc++
 
diff --git a/boards/sim/sim/sim/scripts/Make.defs b/boards/sim/sim/sim/scripts/Make.defs
index 6c9a77b0ce..efc9dd9383 100644
--- a/boards/sim/sim/sim/scripts/Make.defs
+++ b/boards/sim/sim/sim/scripts/Make.defs
@@ -95,6 +95,10 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_ARCH_INSTRUMENT_ALL),y)
+  ARCHOPTIMIZATION += -finstrument-functions
+endif
+
 # Add -fno-common because macOS "ld -r" doesn't seem to pick objects
 # for common symbols.
 ARCHCFLAGS += -fno-common
diff --git a/drivers/note/note_driver.c b/drivers/note/note_driver.c
index ae1c979637..758f1c5a77 100644
--- a/drivers/note/note_driver.c
+++ b/drivers/note/note_driver.c
@@ -40,9 +40,14 @@
 #include <nuttx/note/notelog_driver.h>
 #include <nuttx/spinlock.h>
 #include <nuttx/sched_note.h>
+#include <nuttx/instrument.h>
 
 #include "sched/sched.h"
 
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
 #if defined(CONFIG_DRIVERS_NOTERAM) +  defined(CONFIG_DRIVERS_NOTELOG) + \
     defined(CONFIG_DRIVERS_NOTESNAP) + defined(CONFIG_DRIVERS_NOTERTT) + \
     defined(CONFIG_SEGGER_SYSVIEW) > CONFIG_DRIVERS_NOTE_MAX
@@ -150,6 +155,18 @@ struct note_taskname_s
  * Private Data
  ****************************************************************************/
 
+#ifdef CONFIG_SCHED_INSTRUMENTATION_FUNCTION
+static void note_driver_instrument_enter(FAR void *this_fn,
+            FAR void *call_site, FAR void *arg) noinstrument_function;
+static void note_driver_instrument_leave(FAR void *this_fn,
+            FAR void *call_site, FAR void *arg) noinstrument_function;
+static struct instrument_s g_note_instrument =
+{
+  .entry = note_driver_instrument_enter,
+  .exit = note_driver_instrument_leave,
+};
+#endif
+
 #ifdef CONFIG_SCHED_INSTRUMENTATION_FILTER
 static struct note_filter_s g_note_filter =
 {
@@ -1924,6 +1941,22 @@ FAR const char *note_get_taskname(pid_t pid)
 
 #endif
 
+#ifdef CONFIG_SCHED_INSTRUMENTATION_FUNCTION
+static void note_driver_instrument_enter(FAR void *this_fn,
+                                         FAR void *call_site,
+                                         FAR void *arg)
+{
+  sched_note_string_ip(NOTE_TAG_ALWAYS, (uintptr_t)this_fn, "B");
+}
+
+static void note_driver_instrument_leave(FAR void *this_fn,
+                                         FAR void *call_site,
+                                         FAR void *arg)
+{
+  sched_note_string_ip(NOTE_TAG_ALWAYS, (uintptr_t)this_fn, "E");
+}
+#endif
+
 /****************************************************************************
  * Name: note_driver_register
  ****************************************************************************/
@@ -1931,8 +1964,17 @@ FAR const char *note_get_taskname(pid_t pid)
 int note_driver_register(FAR struct note_driver_s *driver)
 {
   int i;
-  DEBUGASSERT(driver);
+#ifdef CONFIG_SCHED_INSTRUMENTATION_FUNCTION
+  static bool initialized;
 
+  if (!initialized)
+    {
+      instrument_register(g_note_instrument)
+      initialized = true;
+    }
+#endif
+
+  DEBUGASSERT(driver);
   for (i = 0; i < CONFIG_DRIVERS_NOTE_MAX; i++)
     {
       if (g_note_drivers[i] == NULL)
@@ -1945,25 +1987,3 @@ int note_driver_register(FAR struct note_driver_s *driver)
   return -ENOMEM;
 }
 
-#ifdef CONFIG_SCHED_INSTRUMENTATION_FUNCTION
-
-/****************************************************************************
- * Name: __cyg_profile_func_enter
- ****************************************************************************/
-
-void noinstrument_function
-__cyg_profile_func_enter(void *this_fn, void *call_site)
-{
-  sched_note_string_ip(NOTE_TAG_ALWAYS, (uintptr_t)this_fn, "B");
-}
-
-/****************************************************************************
- * Name: __cyg_profile_func_exit
- ****************************************************************************/
-
-void noinstrument_function
-__cyg_profile_func_exit(void *this_fn, void *call_site)
-{
-  sched_note_string_ip(NOTE_TAG_ALWAYS, (uintptr_t)this_fn, "E");
-}
-#endif
diff --git a/include/nuttx/instrument.h b/include/nuttx/instrument.h
new file mode 100644
index 0000000000..c39b9462ac
--- /dev/null
+++ b/include/nuttx/instrument.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+ * include/nuttx/instrument.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_INSTRUMENT_H
+#define __INCLUDE_NUTTX_INSTRUMENT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/compiler.h>
+#include <nuttx/queue.h>
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+typedef CODE void (instrument_fun_t)(FAR void *this_fn,
+                                     FAR void *call_site,
+                                     FAR void *arg);
+
+struct instrument_s
+{
+  sq_entry_t entry;
+  FAR instrument_fun_t *enter;
+  FAR instrument_fun_t *leave;
+  FAR void *arg;
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: instrument_register
+ *
+ * Description: register instrument, it will be called
+ *              when function enter or exit.
+ *
+ * Input Parameters:
+ *   entry - instrument entry structure.
+ * Notice:
+ *  use CONFIG_ARCH_INSTRUMENT_ALL must mark _start or entry
+ *  noinstrument_function, becuase bss not set.
+ *  Make sure your callbacks are not instrumented recursively.
+ *
+ ****************************************************************************/
+
+void instrument_register(FAR struct instrument_s *entry);
+
+#endif /* __INCLUDE_NUTTX_INSTRUMENT_H */
diff --git a/libs/libc/misc/CMakeLists.txt b/libs/libc/misc/CMakeLists.txt
index e24d3ef05c..dbbf69ca5d 100644
--- a/libs/libc/misc/CMakeLists.txt
+++ b/libs/libc/misc/CMakeLists.txt
@@ -79,7 +79,8 @@ list(
   lib_glob.c
   lib_execinfo.c
   lib_ftok.c
-  lib_err.c)
+  lib_err.c
+  lib_instrument.c)
 
 # Keyboard driver encoder/decoder
 
diff --git a/libs/libc/misc/Make.defs b/libs/libc/misc/Make.defs
index 5e71c0649d..605779e0d6 100644
--- a/libs/libc/misc/Make.defs
+++ b/libs/libc/misc/Make.defs
@@ -40,7 +40,7 @@ endif
 CSRCS += lib_dumpbuffer.c lib_dumpvbuffer.c lib_fnmatch.c lib_debug.c
 CSRCS += lib_crc64.c lib_crc32.c lib_crc16.c lib_crc16ccitt.c lib_crc8.c
 CSRCS += lib_crc8ccitt.c lib_crc8table.c lib_glob.c lib_execinfo.c
-CSRCS += lib_ftok.c lib_err.c
+CSRCS += lib_ftok.c lib_err.c lib_instrument.c
 
 # Keyboard driver encoder/decoder
 
diff --git a/libs/libc/misc/lib_instrument.c b/libs/libc/misc/lib_instrument.c
new file mode 100644
index 0000000000..e16af3b3b8
--- /dev/null
+++ b/libs/libc/misc/lib_instrument.c
@@ -0,0 +1,121 @@
+/****************************************************************************
+ * libs/libc/misc/lib_instrument.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/instrument.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Avoid instrument bootstrap */
+
+#define MAIGC_NUMBMER 0x5a5a5a5a
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Use static to avoid instrument bootstrap */
+
+static volatile uint32_t g_magic;
+static sq_queue_t g_instrument_queue;
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: __cyg_profile_func_enter
+ ****************************************************************************/
+
+void noinstrument_function
+__cyg_profile_func_enter(FAR void *this_fn, FAR void *call_site)
+{
+  FAR struct instrument_s *instrument;
+  FAR sq_entry_t *entry;
+
+  if (g_magic != MAIGC_NUMBMER)
+    {
+      return;
+    }
+
+  sq_for_every(&g_instrument_queue, entry)
+    {
+      instrument = (FAR struct instrument_s *)entry;
+      if (instrument->enter)
+        {
+          instrument->enter(this_fn, call_site, instrument->arg);
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: __cyg_profile_func_exit
+ ****************************************************************************/
+
+void noinstrument_function
+__cyg_profile_func_exit(FAR void *this_fn, FAR void *call_site)
+{
+  FAR struct instrument_s *instrument;
+  FAR sq_entry_t *entry;
+
+  if (g_magic != MAIGC_NUMBMER)
+    {
+      return;
+    }
+
+  sq_for_every(&g_instrument_queue, entry)
+    {
+      instrument = (FAR struct instrument_s *)entry;
+      if (instrument->leave)
+        {
+          instrument->leave(this_fn, call_site, instrument->arg);
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: instrument_register
+ *
+ * Description: register instrument, it will be called
+ *              when function enter or exit.
+ *
+ * Input Parameters:
+ *   entry - instrument entry structure.
+ * Notice:
+ *  use CONFIG_ARCH_INSTRUMENT_ALL must mark _start or entry
+ *  noinstrument_function, becuase bss not set.
+ *  Make sure your callbacks are not instrumented recursively.
+ *
+ ****************************************************************************/
+
+void noinstrument_function
+instrument_register(FAR struct instrument_s *entry)
+{
+  if (entry != NULL)
+    {
+      sq_addlast((FAR sq_entry_t *)entry, &g_instrument_queue);
+      g_magic = MAIGC_NUMBMER;
+    }
+}


(nuttx) 02/05: sched/procfs:use instrument to statistics run time max stack

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit d932e0af2a97dee406cd9156425da2bcaac7e655
Author: anjiahao <an...@xiaomi.com>
AuthorDate: Fri Oct 27 21:57:33 2023 +0800

    sched/procfs:use instrument to statistics run time max stack
    
    Usage:
    1. CONFIG_FS_PROCFS_MAX_STACK_RECORD > 0, such as 32,
    2. add '-finstrument-functions' to CFLAGS for What you want to check
       stack.
    3. mount porcfs
    4. cat /proc/<pid>/stack will print backtace & size
    
    Signed-off-by: anjiahao <an...@xiaomi.com>
---
 arch/sim/include/irq.h          |   1 +
 fs/procfs/fs_procfsproc.c       |  53 +++++++++++++++++++
 include/nuttx/compiler.h        |   9 ++++
 include/nuttx/sched.h           |  11 ++++
 sched/Kconfig                   |  13 +++++
 sched/Makefile                  |   1 +
 sched/init/nx_start.c           |   5 ++
 sched/instrument/CMakeLists.txt |  27 ++++++++++
 sched/instrument/Make.defs      |  30 +++++++++++
 sched/instrument/instrument.c   |  58 +++++++++++++++++++++
 sched/instrument/instrument.h   |  44 ++++++++++++++++
 sched/instrument/stack_record.c | 112 ++++++++++++++++++++++++++++++++++++++++
 12 files changed, 364 insertions(+)

diff --git a/arch/sim/include/irq.h b/arch/sim/include/irq.h
index 05942e5232..e5474e15fa 100644
--- a/arch/sim/include/irq.h
+++ b/arch/sim/include/irq.h
@@ -146,6 +146,7 @@ static inline uintptr_t up_getsp(void)
  *
  ****************************************************************************/
 
+noinstrument_function
 static inline bool up_interrupt_context(void)
 {
 #ifdef CONFIG_SMP
diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c
index d5f3532de2..0995985855 100644
--- a/fs/procfs/fs_procfsproc.c
+++ b/fs/procfs/fs_procfsproc.c
@@ -986,6 +986,9 @@ static ssize_t proc_stack(FAR struct proc_file_s *procfile,
   size_t linesize;
   size_t copysize;
   size_t totalsize;
+#if CONFIG_SCHED_STACK_RECORD > 0
+  int i;
+#endif
 
   remaining = buflen;
   totalsize = 0;
@@ -1033,6 +1036,56 @@ static ssize_t proc_stack(FAR struct proc_file_s *procfile,
   buffer    += copysize;
   remaining -= copysize;
 
+#if CONFIG_SCHED_STACK_RECORD > 0
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%zu\n",
+                              "StackMax: ",
+                              tcb->stack_base_ptr +
+                              tcb->adj_stack_size - tcb->sp_deepest);
+  copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
+                             &offset);
+
+  totalsize += copysize;
+  buffer    += copysize;
+  remaining -= copysize;
+
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%-s\n",
+                               "Size", "Backtrace");
+  copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
+                             &offset);
+
+  totalsize += copysize;
+  buffer    += copysize;
+  remaining -= copysize;
+
+  for (i = tcb->level_deepest - 1; i > 0; i--)
+    {
+      linesize = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                                 "%-12zu%-pS\n",
+                                 tcb->stackrecord_sp_deepest[i - 1] -
+                                 tcb->stackrecord_sp_deepest[i],
+                                 tcb->stackrecord_pc_deepest[i]);
+      copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
+                               &offset);
+      totalsize += copysize;
+      buffer    += copysize;
+      remaining -= copysize;
+    }
+
+  if (tcb->caller_deepest)
+    {
+      linesize = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                                 "Warning stack record buffer too small\n"
+                                 "Max: %u Overflow: %zu\n",
+                                 CONFIG_SCHED_STACK_RECORD,
+                                 tcb->caller_deepest);
+      copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
+                               &offset);
+      totalsize += copysize;
+      buffer    += copysize;
+      remaining -= copysize;
+    }
+#endif
+
 #ifdef CONFIG_STACK_COLORATION
   if (totalsize >= buflen)
     {
diff --git a/include/nuttx/compiler.h b/include/nuttx/compiler.h
index 74edd9f212..222f37c12c 100644
--- a/include/nuttx/compiler.h
+++ b/include/nuttx/compiler.h
@@ -251,6 +251,10 @@
 
 #  define noinstrument_function __attribute__((no_instrument_function))
 
+/* The nooptimiziation_function attribute no optimize */
+
+#  define nooptimiziation_function __attribute__((optimize(0)))
+
 /* The nosanitize_address attribute informs GCC don't sanitize it */
 
 #  define nosanitize_address __attribute__((no_sanitize_address))
@@ -555,6 +559,7 @@
 #  define always_inline_function
 #  define noinline_function
 #  define noinstrument_function
+#  define nooptimiziation_function
 #  define nosanitize_address
 #  define nosanitize_undefined
 #  define nostackprotect_function
@@ -698,6 +703,7 @@
 #  define always_inline_function
 #  define noinline_function
 #  define noinstrument_function
+#  define nooptimiziation_function
 #  define nosanitize_address
 #  define nosanitize_undefined
 #  define nostackprotect_function
@@ -809,6 +815,7 @@
 #  define always_inline_function
 #  define noinline_function
 #  define noinstrument_function
+#  define nooptimiziation_function
 #  define nosanitize_address
 #  define nosanitize_undefined
 #  define nostackprotect_function
@@ -899,6 +906,7 @@
 #  define always_inline_function
 #  define noinline_function
 #  define noinstrument_function
+#  define nooptimiziation_function
 #  define nosanitize_address
 #  define nosanitize_undefined
 #  define nostackprotect_function
@@ -964,6 +972,7 @@
 #  define always_inline_function
 #  define noinline_function
 #  define noinstrument_function
+#  define nooptimiziation_function
 #  define nosanitize_address
 #  define nosanitize_undefined
 #  define nostackprotect_function
diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h
index 3154a7d61a..a80af294e0 100644
--- a/include/nuttx/sched.h
+++ b/include/nuttx/sched.h
@@ -645,6 +645,17 @@ struct tcb_s
 #if CONFIG_TASK_NAME_SIZE > 0
   char name[CONFIG_TASK_NAME_SIZE + 1];  /* Task name (with NUL terminator  */
 #endif
+
+#if CONFIG_SCHED_STACK_RECORD > 0
+  FAR void *stackrecord_pc[CONFIG_SCHED_STACK_RECORD];
+  FAR void *stackrecord_sp[CONFIG_SCHED_STACK_RECORD];
+  FAR void *stackrecord_pc_deepest[CONFIG_SCHED_STACK_RECORD];
+  FAR void *stackrecord_sp_deepest[CONFIG_SCHED_STACK_RECORD];
+  FAR void *sp_deepest;
+  size_t caller_deepest;
+  size_t level_deepest;
+  size_t level;
+#endif
 };
 
 /* struct task_tcb_s ********************************************************/
diff --git a/sched/Kconfig b/sched/Kconfig
index 1746649a41..40512719b6 100644
--- a/sched/Kconfig
+++ b/sched/Kconfig
@@ -1221,6 +1221,19 @@ config SCHED_INSTRUMENTATION_FUNCTION
 endif # SCHED_INSTRUMENTATION
 endmenu # Performance Monitoring
 
+menu "System Auto Instrumentation"
+
+config SCHED_STACK_RECORD
+	int "Maximum stack backtrace to record"
+	default 0
+	---help---
+		Specifies the maximum number of stack backtrace to record in the
+		TCB.  Useful if scheduler instrumentation is selected.  Set to zero
+		to disable.Through instrumentation, record the backtrace at
+		the deepest point in the stack.
+
+endmenu
+
 menu "Files and I/O"
 
 config DEV_CONSOLE
diff --git a/sched/Makefile b/sched/Makefile
index ccd723f9d6..fcddb0c4c1 100644
--- a/sched/Makefile
+++ b/sched/Makefile
@@ -25,6 +25,7 @@ include clock/Make.defs
 include environ/Make.defs
 include group/Make.defs
 include init/Make.defs
+include instrument/Make.defs
 include irq/Make.defs
 include misc/Make.defs
 include mqueue/Make.defs
diff --git a/sched/init/nx_start.c b/sched/init/nx_start.c
index 176c010999..98a5f1cfb7 100644
--- a/sched/init/nx_start.c
+++ b/sched/init/nx_start.c
@@ -56,6 +56,7 @@
 #include "irq/irq.h"
 #include "group/group.h"
 #include "init/init.h"
+#include "instrument/instrument.h"
 #include "tls/tls.h"
 
 /****************************************************************************
@@ -564,6 +565,10 @@ void nx_start(void)
 
   sched_lock();
 
+  /* Initialize the instrument function */
+
+  instrument_initialize();
+
   /* Initialize the file system (needed to support device drivers) */
 
   fs_initialize();
diff --git a/sched/instrument/CMakeLists.txt b/sched/instrument/CMakeLists.txt
new file mode 100644
index 0000000000..08c4f1a34c
--- /dev/null
+++ b/sched/instrument/CMakeLists.txt
@@ -0,0 +1,27 @@
+# ##############################################################################
+# sched/instrument/CMakeLists.txt
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements.  See the NOTICE file distributed with this work for
+# additional information regarding copyright ownership.  The ASF licenses this
+# file to you under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License.  You may obtain a copy of
+# the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations under
+# the License.
+#
+# ##############################################################################
+
+set(SRCS instrument.c)
+
+if(NOT "${CONFIG_SCHED_STACK_RECORD}" STREQUAL "0")
+  list(APPEND SRCS stack_record.c)
+endif()
+
+target_sources(sched PRIVATE ${SRCS})
diff --git a/sched/instrument/Make.defs b/sched/instrument/Make.defs
new file mode 100644
index 0000000000..7f86322c8f
--- /dev/null
+++ b/sched/instrument/Make.defs
@@ -0,0 +1,30 @@
+############################################################################
+# sched/instrument/Make.defs
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+CSRCS += instrument.c
+
+ifneq ($(CONFIG_SCHED_STACK_RECORD),0)
+CSRCS += stack_record.c
+endif
+
+# Include instrument build support
+
+DEPPATH += --dep-path instrument
+VPATH += :instrument
diff --git a/sched/instrument/instrument.c b/sched/instrument/instrument.c
new file mode 100644
index 0000000000..a9581fd26e
--- /dev/null
+++ b/sched/instrument/instrument.c
@@ -0,0 +1,58 @@
+/****************************************************************************
+ * sched/instrument/instrument.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/instrument.h>
+
+/****************************************************************************
+ * External Definitions
+ ****************************************************************************/
+
+#if CONFIG_SCHED_STACK_RECORD > 0
+extern struct instrument_s g_stack_record;
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: instrument_initialize
+ *
+ * Description:
+ *   This function is called to initialize all the instrument functions
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Does not return.
+ *
+ ****************************************************************************/
+
+void instrument_initialize(void)
+{
+#if CONFIG_SCHED_STACK_RECORD > 0
+  instrument_register(&g_stack_record);
+#endif
+}
diff --git a/sched/instrument/instrument.h b/sched/instrument/instrument.h
new file mode 100644
index 0000000000..10a50082d8
--- /dev/null
+++ b/sched/instrument/instrument.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+ * sched/instrument/instrument.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __SCHED_INSTRUMENT_INSTRUMENT_H
+#define __SCHED_INSTRUMENT_INSTRUMENT_H
+
+/****************************************************************************
+ * Public Functions prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: instrument_initialize
+ *
+ * Description:
+ *   This function is called to initialize all the instrument functions
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Does not return.
+ *
+ ****************************************************************************/
+
+void instrument_initialize(void);
+
+#endif
diff --git a/sched/instrument/stack_record.c b/sched/instrument/stack_record.c
new file mode 100644
index 0000000000..69b1a0ffe1
--- /dev/null
+++ b/sched/instrument/stack_record.c
@@ -0,0 +1,112 @@
+/****************************************************************************
+ * sched/instrument/stack_record.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/instrument.h>
+#include <sys/param.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void stack_record_enter(FAR void *this_fn, FAR void *call_site,
+                               FAR void *arg) noinstrument_function
+                               nooptimiziation_function;
+static void stack_record_leave(FAR void *this_fn, FAR void *call_site,
+                               FAR void *arg) noinstrument_function
+                               nooptimiziation_function;
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+struct instrument_s g_stack_record =
+{
+  .enter = stack_record_enter,
+  .leave = stack_record_leave
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stack_statistics
+ ****************************************************************************/
+
+static void stack_record_enter(FAR void *this_fn, FAR void *call_site,
+                               FAR void *arg)
+{
+  FAR struct tcb_s *tcb = running_task();
+  FAR void *sp = &tcb;
+  size_t i;
+
+  if (tcb == NULL || sp < tcb->stack_base_ptr ||
+      sp >= tcb->stack_base_ptr + tcb->adj_stack_size)
+    {
+      return;
+    }
+
+  if (tcb->level < CONFIG_SCHED_STACK_RECORD)
+    {
+      tcb->stackrecord_sp[tcb->level] = sp;
+      tcb->stackrecord_pc[tcb->level++] = this_fn;
+    }
+  else if (tcb->caller_deepest < ++tcb->level)
+    {
+      tcb->caller_deepest = tcb->level;
+    }
+
+  if (tcb->sp_deepest == NULL || sp < tcb->sp_deepest)
+    {
+      tcb->level_deepest = MIN(tcb->level, CONFIG_SCHED_STACK_RECORD);
+      for (i = 0; i < tcb->level_deepest; i++)
+        {
+          tcb->stackrecord_pc_deepest[i] = tcb->stackrecord_pc[i];
+          tcb->stackrecord_sp_deepest[i] = tcb->stackrecord_sp[i];
+        }
+
+      tcb->sp_deepest = sp;
+    }
+}
+
+/****************************************************************************
+ * Name: stackrecord_leave
+ ****************************************************************************/
+
+static void stack_record_leave(FAR void *this_fn, FAR void *call_site,
+                               FAR void *arg)
+{
+  FAR struct tcb_s *tcb = running_task();
+  FAR void *sp = &tcb;
+
+  if (tcb == NULL || tcb->level == 0 || sp < tcb->stack_base_ptr ||
+      sp >= tcb->stack_base_ptr + tcb->adj_stack_size)
+    {
+      return;
+    }
+
+  tcb->level--;
+}


(nuttx) 04/05: add demo for record stack defconfig

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 25f599fe318959d95b67d660a80abdf8144726b7
Author: anjiahao <an...@xiaomi.com>
AuthorDate: Fri Oct 27 21:55:01 2023 +0800

    add demo for record stack defconfig
    
    xtensa: esp32s3-devkit:stack
    arm: stm32f429i-disco:stack
    
    Signed-off-by: anjiahao <an...@xiaomi.com>
---
 .../stm32/stm32f429i-disco/configs/stack/defconfig | 56 ++++++++++++++++++++++
 .../esp32s3/esp32s3-devkit/configs/stack/defconfig | 51 ++++++++++++++++++++
 2 files changed, 107 insertions(+)

diff --git a/boards/arm/stm32/stm32f429i-disco/configs/stack/defconfig b/boards/arm/stm32/stm32f429i-disco/configs/stack/defconfig
new file mode 100644
index 0000000000..11177a9a4c
--- /dev/null
+++ b/boards/arm/stm32/stm32f429i-disco/configs/stack/defconfig
@@ -0,0 +1,56 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_ARCH_FPU is not set
+# CONFIG_STM32_FLASH_PREFETCH is not set
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="stm32f429i-disco"
+CONFIG_ARCH_BOARD_STM32F429I_DISCO=y
+CONFIG_ARCH_BUTTONS=y
+CONFIG_ARCH_CHIP="stm32"
+CONFIG_ARCH_CHIP_STM32=y
+CONFIG_ARCH_CHIP_STM32F429Z=y
+CONFIG_ARCH_INSTRUMENT_ALL=y
+CONFIG_ARCH_INTERRUPTSTACK=4096
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_FULLOPT=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_HEAP2_BASE=0xD0000000
+CONFIG_HEAP2_SIZE=8388608
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INTELHEX_BINARY=y
+CONFIG_MM_REGIONS=3
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_BACKTRACE=y
+CONFIG_SCHED_STACK_RECORD=32
+CONFIG_SCHED_WAITPID=y
+CONFIG_SPI=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
+CONFIG_STM32_EXTERNAL_RAM=y
+CONFIG_STM32_FMC=y
+CONFIG_STM32_JTAG_SW_ENABLE=y
+CONFIG_STM32_PWR=y
+CONFIG_STM32_USART1=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_USART1_SERIAL_CONSOLE=y
diff --git a/boards/xtensa/esp32s3/esp32s3-devkit/configs/stack/defconfig b/boards/xtensa/esp32s3/esp32s3-devkit/configs/stack/defconfig
new file mode 100644
index 0000000000..c668221b47
--- /dev/null
+++ b/boards/xtensa/esp32s3/esp32s3-devkit/configs/stack/defconfig
@@ -0,0 +1,51 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_ARCH_LEDS is not set
+# CONFIG_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+CONFIG_ARCH="xtensa"
+CONFIG_ARCH_BOARD="esp32s3-devkit"
+CONFIG_ARCH_BOARD_COMMON=y
+CONFIG_ARCH_BOARD_ESP32S3_DEVKIT=y
+CONFIG_ARCH_CHIP="esp32s3"
+CONFIG_ARCH_CHIP_ESP32S3=y
+CONFIG_ARCH_CHIP_ESP32S3WROOM1=y
+CONFIG_ARCH_INSTRUMENT_ALL=y
+CONFIG_ARCH_INTERRUPTSTACK=2048
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARCH_XTENSA=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_DEBUG_FULLOPT=y
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_ESP32S3_UART0=y
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=3072
+CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INTELHEX_BINARY=y
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_RAM_SIZE=114688
+CONFIG_RAM_START=0x20000000
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_BACKTRACE=y
+CONFIG_SCHED_STACK_RECORD=32
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSLOG_BUFFER=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_SYSTEM_NSH_STACKSIZE=4096
+CONFIG_UART0_SERIAL_CONSOLE=y