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)
