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

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

commit cb9014ba943b34563dcbe88fb7cf942d21b0c22a
Author: Marco Casaroli <[email protected]>
AuthorDate: Fri Oct 30 18:18:48 2026 +0100

    mm: Do not call scheduler functions in the user-space heap.
    
    In a protected or kernel build, the heap code is also built for user
    space, where the scheduler functions do not exist.  Some heap debug code
    calls them, so the user image does not link:
    
    - mm_memdump() calls nxsched_get_tcb() for a task dump.
    - MM_DUMP_LEAK() calls nxsched_get_tcb() when CONFIG_MM_BACKTRACE >= 0.
    - MM_ADD_BACKTRACE() and the TLSF memdump_backtrace() call
      nxsched_get_tcb() when CONFIG_MM_BACKTRACE > 0, to read the
      TCB_FLAG_HEAP_DUMP flag of the task.
    - mm_malloc() calls nxsched_foreach() on a failure with
      CONFIG_MM_DUMP_ON_FAILURE and CONFIG_MM_BACKTRACE >= 0.
    
    For example, mps2-an500:knsh fails with CONFIG_MM_BACKTRACE=0, with
    CONFIG_MM_DUMP_DETAILS_ON_FAILURE, or with the TLSF heap, where
    mm_memdump() is in the same object as mm_malloc().
    
    MM_DUMP_LEAK() now uses kill(pid, 0) in all builds, which does the same
    check as nxsched_get_tcb().  Remove TCB_FLAG_HEAP_DUMP and the
    "<pid> on" and "<pid> off" commands of /proc/memdump that set it: the
    backtrace of a heap now follows only the "on" and "off" commands of
    /proc/memdump, the same in all builds.  In user space, the task dump
    prints no task name and the failure dump prints only the leak line.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 arch/sim/src/sim/sim_ummheap.c |  5 +----
 fs/procfs/fs_procfsmeminfo.c   | 29 -----------------------------
 include/nuttx/mm/mm.h          |  3 ++-
 include/nuttx/sched.h          |  1 -
 mm/mm_heap/mm.h                |  4 +---
 mm/mm_heap/mm_malloc.c         |  2 ++
 mm/mm_heap/mm_memdump.c        |  2 ++
 mm/tlsf/mm_tlsf.c              | 10 +++-------
 8 files changed, 11 insertions(+), 45 deletions(-)

diff --git a/arch/sim/src/sim/sim_ummheap.c b/arch/sim/src/sim/sim_ummheap.c
index 3bcfd19c07a..c3a1b52253c 100644
--- a/arch/sim/src/sim/sim_ummheap.c
+++ b/arch/sim/src/sim/sim_ummheap.c
@@ -61,11 +61,9 @@
 #  define MM_ADD_BACKTRACE(heap, ptr) \
      do { \
          FAR struct mm_allocnode_s *tmp = (FAR struct mm_allocnode_s *)(ptr); \
-         FAR struct tcb_s *tcb; \
          pid_t tid = _SCHED_GETTID(); \
          tmp->pid = tid; \
-         tcb = nxsched_get_tcb(tid); \
-         if ((heap)->procfs.backtrace || (tcb && tcb->flags & 
TCB_FLAG_HEAP_DUMP)) { \
+         if ((heap)->procfs.backtrace) { \
              int n = sched_backtrace(tid, tmp->backtrace, CONFIG_MM_BACKTRACE, 
\
                                      CONFIG_MM_BACKTRACE_SKIP); \
              if (n < CONFIG_MM_BACKTRACE) { \
@@ -74,7 +72,6 @@
          } else { \
              tmp->backtrace[0] = NULL; \
          } \
-         if (tcb) nxsched_put_tcb(tcb); \
          MM_INCSEQNO(tmp); \
      } while (0)
 
diff --git a/fs/procfs/fs_procfsmeminfo.c b/fs/procfs/fs_procfsmeminfo.c
index 92945c5da72..616a3efa86a 100644
--- a/fs/procfs/fs_procfsmeminfo.c
+++ b/fs/procfs/fs_procfsmeminfo.c
@@ -499,9 +499,6 @@ static ssize_t memdump_write(FAR struct file *filep, FAR 
const char *buffer,
 #if CONFIG_MM_BACKTRACE >= 0
   FAR char *p;
 #endif
-#if CONFIG_MM_BACKTRACE > 0
-  FAR struct tcb_s *tcb;
-#endif
 
   DEBUGASSERT(buffer != NULL && buflen > 0);
 
@@ -529,32 +526,6 @@ static ssize_t memdump_write(FAR struct file *filep, FAR 
const char *buffer,
 
       return buflen;
     }
-  else if ((p = strstr(buffer, "on")) != NULL)
-    {
-      *p = '\0';
-      dump.pid = atoi(buffer);
-      tcb = nxsched_get_tcb(dump.pid);
-      if (tcb == NULL)
-        {
-          return -EINVAL;
-        }
-
-      tcb->flags |= TCB_FLAG_HEAP_DUMP;
-      return buflen;
-    }
-  else if ((p = strstr(buffer, "off")) != NULL)
-    {
-      *p = '\0';
-      dump.pid = atoi(buffer);
-      tcb = nxsched_get_tcb(dump.pid);
-      if (tcb == NULL)
-        {
-          return -EINVAL;
-        }
-
-      tcb->flags &= ~TCB_FLAG_HEAP_DUMP;
-      return buflen;
-    }
 #endif
 
   switch (buffer[0])
diff --git a/include/nuttx/mm/mm.h b/include/nuttx/mm/mm.h
index ca0857c3cb0..15371798ffe 100644
--- a/include/nuttx/mm/mm.h
+++ b/include/nuttx/mm/mm.h
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <stdbool.h>
 #include <malloc.h>
+#include <signal.h>
 #include <string.h>
 
 /****************************************************************************
@@ -170,7 +171,7 @@
     ((node) != NULL && (dump)->pid == (node)->pid)
 #  define MM_DUMP_LEAK(dump, node) \
     ((node) != NULL && (dump)->pid == PID_MM_LEAK && (node)->pid >= 0 && \
-     nxsched_get_tcb((node)->pid) == NULL)
+     kill((node)->pid, 0) != 0)
 #else
 #  define MM_DUMP_ALLOC(dump,node)  ((dump)->pid == PID_MM_ALLOC)
 #  define MM_DUMP_SEQNO(dump,node)  (true)
diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h
index 2a2f5adbc85..aa6a2914676 100644
--- a/include/nuttx/sched.h
+++ b/include/nuttx/sched.h
@@ -106,7 +106,6 @@
 #define TCB_FLAG_EXIT_PROCESSING   (1 << 8)                      /* Bit 8: 
Exiting */
 #define TCB_FLAG_FREE_STACK        (1 << 9)                      /* Bit 9: 
Free stack after exit */
 #define TCB_FLAG_HEAP_CHECK        (1 << 10)                     /* Bit 10: 
Heap check */
-#define TCB_FLAG_HEAP_DUMP         (1 << 11)                     /* Bit 11: 
Heap dump */
 #define TCB_FLAG_DETACHED          (1 << 12)                     /* Bit 12: 
Pthread detached */
 #define TCB_FLAG_FORCED_CANCEL     (1 << 13)                     /* Bit 13: 
Pthread cancel is forced */
 #define TCB_FLAG_JOIN_COMPLETED    (1 << 14)                     /* Bit 14: 
Pthread join completed */
diff --git a/mm/mm_heap/mm.h b/mm/mm_heap/mm.h
index b34c2055231..1753da304b4 100644
--- a/mm/mm_heap/mm.h
+++ b/mm/mm_heap/mm.h
@@ -86,10 +86,8 @@
      do \
        { \
          FAR struct mm_allocnode_s *tmp = (FAR struct mm_allocnode_s *)(ptr); \
-         FAR struct tcb_s *tcb; \
          tmp->pid = _SCHED_GETTID(); \
-         tcb = nxsched_get_tcb(tmp->pid); \
-         if ((heap)->mm_procfs.backtrace || (tcb && tcb->flags & 
TCB_FLAG_HEAP_DUMP)) \
+         if ((heap)->mm_procfs.backtrace) \
            { \
              int n = sched_backtrace(tmp->pid, tmp->backtrace, 
CONFIG_MM_BACKTRACE, \
                                      CONFIG_MM_BACKTRACE_SKIP); \
diff --git a/mm/mm_heap/mm_malloc.c b/mm/mm_heap/mm_malloc.c
index 025714163e0..6e5cab9d2e5 100644
--- a/mm/mm_heap/mm_malloc.c
+++ b/mm/mm_heap/mm_malloc.c
@@ -375,7 +375,9 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
             minfo.arena, minfo.uordblks, minfo.fordblks,
             minfo.mxordblk, minfo.aordblks, minfo.ordblks);
 #  if CONFIG_MM_BACKTRACE >= 0
+#    if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
       nxsched_foreach(mm_dump_handler, heap);
+#    endif
       mm_dump_handler(NULL, heap);
 #  endif
 #  ifdef CONFIG_MM_HEAP_MEMPOOL
diff --git a/mm/mm_heap/mm_memdump.c b/mm/mm_heap/mm_memdump.c
index e49380d7e61..45b349bca00 100644
--- a/mm/mm_heap/mm_memdump.c
+++ b/mm/mm_heap/mm_memdump.c
@@ -271,7 +271,9 @@ void mm_memdump(FAR struct mm_heap_s *heap,
       else
         {
           name = "Unknown";
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
           tcb  = nxsched_get_tcb(pid);
+#endif
         }
 
       if (tcb == NULL)
diff --git a/mm/tlsf/mm_tlsf.c b/mm/tlsf/mm_tlsf.c
index 00ba5cd3443..cd82f180a97 100644
--- a/mm/tlsf/mm_tlsf.c
+++ b/mm/tlsf/mm_tlsf.c
@@ -320,16 +320,10 @@ static void memdump_dump_biggestnodes(FAR struct 
mm_memdump_priv_s *priv)
 static void memdump_backtrace(FAR struct mm_heap_s *heap,
                               FAR struct memdump_backtrace_s *buf)
 {
-#  if CONFIG_MM_BACKTRACE > 0
-  FAR struct tcb_s *tcb;
-#  endif
-
   buf->pid = _SCHED_GETTID();
   MM_INCSEQNO(buf);
 #  if CONFIG_MM_BACKTRACE > 0
-  tcb = nxsched_get_tcb(buf->pid);
-  if (heap->mm_procfs.backtrace ||
-      (tcb && tcb->flags & TCB_FLAG_HEAP_DUMP))
+  if (heap->mm_procfs.backtrace)
     {
       int ret = sched_backtrace(buf->pid, buf->backtrace,
                                 CONFIG_MM_BACKTRACE,
@@ -1285,7 +1279,9 @@ void mm_memdump(FAR struct mm_heap_s *heap,
       else
         {
           name = "Unknown";
+#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
           tcb  = nxsched_get_tcb(pid);
+#endif
         }
 
       if (tcb == NULL)

Reply via email to