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 2022/02/26 06:32:50 UTC

[incubator-nuttx] branch master updated (b95022f -> 018d7d6)

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/incubator-nuttx.git.


    from b95022f  arm/armv7-a: Remove CONFIG_SMP guard from arm_scu.c
     new 39eaeef  mm/mm_heap: remove the unnecessary check for memory node size
     new c5ba926  procfs: add memdump interface to dump used/free memory info
     new 2dcc4a3  mm/dump: add pid and backtrace for every memory node
     new 7ae3c57  procfs: add heap info for every task
     new 168074f  mm/memdump: fix print backtrace abnormal
     new 018d7d6  mm/mm_malloc: dump all allocated memory info when malloc failed

The 6 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:
 arch/sim/src/sim/up_heap.c   |  12 ++++
 fs/procfs/Kconfig            |   4 ++
 fs/procfs/fs_procfs.c        |   4 ++
 fs/procfs/fs_procfsmeminfo.c | 131 ++++++++++++++++++++++++++++++----
 fs/procfs/fs_procfsproc.c    |  80 +++++++++++++++++++++
 include/malloc.h             |  12 ++++
 include/nuttx/mm/mm.h        |  12 ++++
 mm/kmm_heap/kmm_mallinfo.c   |  19 +++++
 mm/mm_heap/Make.defs         |   2 +-
 mm/mm_heap/mm.h              |  88 ++++++++++++++---------
 mm/mm_heap/mm_initialize.c   |  11 +--
 mm/mm_heap/mm_mallinfo.c     |  42 +++++++++++
 mm/mm_heap/mm_malloc.c       |   3 +
 mm/mm_heap/mm_memalign.c     |   1 +
 mm/mm_heap/mm_memdump.c      | 164 +++++++++++++++++++++++++++++++++++++++++++
 mm/mm_heap/mm_realloc.c      |   4 ++
 mm/umm_heap/umm_mallinfo.c   |  20 ++++++
 17 files changed, 552 insertions(+), 57 deletions(-)
 create mode 100644 mm/mm_heap/mm_memdump.c

[incubator-nuttx] 03/06: mm/dump: add pid and backtrace for every memory node

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/incubator-nuttx.git

commit 2dcc4a359d3fdc080be5c2742af6c496c1d13354
Author: Jiuzhu Dong <do...@xiaomi.com>
AuthorDate: Thu Jan 20 17:17:29 2022 +0800

    mm/dump: add pid and backtrace for every memory node
    
    usage:
    echo <pid/used/free> trace > /proc/memdump
    echo used > /proc/memdump //output all used memory info with backtrace
    echo free > /proc/memdump //output all free memory info
    echo 22 > /proc/memdump //output used memory info for task pid is 22 with backtrace
    
    Signed-off-by: Jiuzhu Dong <do...@xiaomi.com>
---
 fs/procfs/fs_procfsmeminfo.c | 12 +++++++-
 include/nuttx/mm/mm.h        |  5 +++-
 mm/mm_heap/mm.h              | 51 ++++++++++++++++++++++++++--------
 mm/mm_heap/mm_initialize.c   |  2 ++
 mm/mm_heap/mm_malloc.c       |  1 +
 mm/mm_heap/mm_memalign.c     |  1 +
 mm/mm_heap/mm_memdump.c      | 65 ++++++++++++++++++++++++++++++++++++--------
 mm/mm_heap/mm_realloc.c      |  4 +++
 8 files changed, 115 insertions(+), 26 deletions(-)

diff --git a/fs/procfs/fs_procfsmeminfo.c b/fs/procfs/fs_procfsmeminfo.c
index 13d86da..d15518f 100644
--- a/fs/procfs/fs_procfsmeminfo.c
+++ b/fs/procfs/fs_procfsmeminfo.c
@@ -415,15 +415,21 @@ static ssize_t memdump_read(FAR struct file *filep, FAR char *buffer,
   procfile = (FAR struct meminfo_file_s *)filep->f_priv;
   DEBUGASSERT(procfile);
 
+#ifdef CONFIG_DEBUG_MM
+  linesize  = procfs_snprintf(procfile->line, MEMINFO_LINELEN,
+                              "usage: <pid/used/free>\n"
+                              "pid: dump pid allocated node\n");
+#else
   linesize  = procfs_snprintf(procfile->line, MEMINFO_LINELEN,
                               "usage: <used/free>\n");
+#endif
 
   copysize  = procfs_memcpy(procfile->line, linesize, buffer, buflen,
                             &offset);
   totalsize = copysize;
   buffer   += copysize;
   buflen   -= copysize;
-  linesize  = procfs_snprintf(procfile->line, MEMINFO_LINELEN, "%s",
+  linesize  = procfs_snprintf(procfile->line, MEMINFO_LINELEN,
                               "used: dump all allocated node\n"
                               "free: dump all free node\n");
 
@@ -462,6 +468,10 @@ static ssize_t memdump_write(FAR struct file *filep, FAR const char *buffer,
       case 'f':
         pid = -2;
         break;
+#ifdef CONFIG_DEBUG_MM
+      default:
+        pid = atoi(buffer);
+#endif
     }
 
   for (entry = g_procfs_meminfo; entry != NULL; entry = entry->next)
diff --git a/include/nuttx/mm/mm.h b/include/nuttx/mm/mm.h
index 246a1b6..aad4e6f 100644
--- a/include/nuttx/mm/mm.h
+++ b/include/nuttx/mm/mm.h
@@ -296,7 +296,6 @@ void kmm_extend(FAR void *mem, size_t size, int region);
 
 struct mallinfo; /* Forward reference */
 int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info);
-void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid);
 
 /* Functions contained in kmm_mallinfo.c ************************************/
 
@@ -304,6 +303,10 @@ void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid);
 struct mallinfo kmm_mallinfo(void);
 #endif
 
+/* Functions contained in mm_memdump.c **************************************/
+
+void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid);
+
 #ifdef CONFIG_DEBUG_MM
 /* Functions contained in mm_checkcorruption.c ******************************/
 
diff --git a/mm/mm_heap/mm.h b/mm/mm_heap/mm.h
index 1d7219d..6f442db 100644
--- a/mm/mm_heap/mm.h
+++ b/mm/mm_heap/mm.h
@@ -30,10 +30,12 @@
 #include <nuttx/fs/procfs.h>
 
 #include <assert.h>
+#include <execinfo.h>
 #include <sys/types.h>
 #include <stdbool.h>
 #include <string.h>
 #include <semaphore.h>
+#include <unistd.h>
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -64,8 +66,8 @@
  * REVISIT: We could do better on machines with 16-bit addressing.
  */
 
-#  define MM_MIN_SHIFT   ( 4)  /* 16 bytes */
-#  define MM_MAX_SHIFT   (15)  /* 32 Kb */
+#  define MM_MIN_SHIFT_   ( 4)  /* 16 bytes */
+#  define MM_MAX_SHIFT    (15)  /* 32 Kb */
 
 #elif defined(CONFIG_HAVE_LONG_LONG)
 /* Four byte offsets; Pointers may be 4 or 8 bytes
@@ -73,19 +75,36 @@
  */
 
 #  if UINTPTR_MAX <= UINT32_MAX
-#    define MM_MIN_SHIFT ( 4)  /* 16 bytes */
+#    define MM_MIN_SHIFT_ ( 4)  /* 16 bytes */
 #  elif UINTPTR_MAX <= UINT64_MAX
-#    define MM_MIN_SHIFT ( 5)  /* 32 bytes */
+#    define MM_MIN_SHIFT_ ( 5)  /* 32 bytes */
 #  endif
-#  define MM_MAX_SHIFT   (22)  /*  4 Mb */
+#  define MM_MAX_SHIFT    (22)  /*  4 Mb */
 
 #else
 /* Four byte offsets; Pointers must be 4 bytes.
  * sizeof(struct mm_freenode_s) is 16 bytes.
  */
 
-#  define MM_MIN_SHIFT   ( 4)  /* 16 bytes */
-#  define MM_MAX_SHIFT   (22)  /*  4 Mb */
+#  define MM_MIN_SHIFT_   ( 4)  /* 16 bytes */
+#  define MM_MAX_SHIFT    (22)  /*  4 Mb */
+#endif
+
+#ifdef CONFIG_DEBUG_MM
+#  define MM_MIN_SHIFT       (MM_MIN_SHIFT_ + 2)
+#  define MM_BACKTRACE_DEPTH 8
+#  define MM_ADD_BACKTRACE(ptr) \
+     do \
+       { \
+         FAR struct mm_allocnode_s *tmp = (FAR struct mm_allocnode_s *)(ptr); \
+         tmp->pid = getpid(); \
+         memset(tmp->backtrace, 0, sizeof(tmp->backtrace)); \
+         backtrace(tmp->backtrace, MM_BACKTRACE_DEPTH); \
+       } \
+     while (0)
+#else
+#  define MM_ADD_BACKTRACE(ptr)
+#  define MM_MIN_SHIFT MM_MIN_SHIFT_
 #endif
 
 /* All other definitions derive from these two */
@@ -140,8 +159,12 @@ typedef uint32_t mmsize_t;
 
 struct mm_allocnode_s
 {
-  mmsize_t size;           /* Size of this chunk */
-  mmsize_t preceding;      /* Size of the preceding chunk */
+#ifdef CONFIG_DEBUG_MM
+  uint32_t pid;                            /* The pid for caller */
+  FAR void *backtrace[MM_BACKTRACE_DEPTH]; /* The backtrace buffer for caller */
+#endif
+  mmsize_t size;                           /* Size of this chunk */
+  mmsize_t preceding;                      /* Size of the preceding chunk */
 };
 
 static_assert(SIZEOF_MM_ALLOCNODE <= MM_MIN_CHUNK,
@@ -151,9 +174,13 @@ static_assert(SIZEOF_MM_ALLOCNODE <= MM_MIN_CHUNK,
 
 struct mm_freenode_s
 {
-  mmsize_t size;                   /* Size of this chunk */
-  mmsize_t preceding;              /* Size of the preceding chunk */
-  FAR struct mm_freenode_s *flink; /* Supports a doubly linked list */
+#ifdef CONFIG_DEBUG_MM
+  uint32_t pid;                            /* The pid for caller */
+  FAR void *backtrace[MM_BACKTRACE_DEPTH]; /* The backtrace buffer for caller */
+#endif
+  mmsize_t size;                           /* Size of this chunk */
+  mmsize_t preceding;                      /* Size of the preceding chunk */
+  FAR struct mm_freenode_s *flink;         /* Supports a doubly linked list */
   FAR struct mm_freenode_s *blink;
 };
 
diff --git a/mm/mm_heap/mm_initialize.c b/mm/mm_heap/mm_initialize.c
index bf84db4..5e8b52b 100644
--- a/mm/mm_heap/mm_initialize.c
+++ b/mm/mm_heap/mm_initialize.c
@@ -117,6 +117,7 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void *heapstart,
 
   heap->mm_heapstart[IDX]            = (FAR struct mm_allocnode_s *)
                                        heapbase;
+  MM_ADD_BACKTRACE(heap->mm_heapstart[IDX]);
   heap->mm_heapstart[IDX]->size      = SIZEOF_MM_ALLOCNODE;
   heap->mm_heapstart[IDX]->preceding = MM_ALLOC_BIT;
   node                               = (FAR struct mm_freenode_s *)
@@ -127,6 +128,7 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void *heapstart,
                                        (heapend - SIZEOF_MM_ALLOCNODE);
   heap->mm_heapend[IDX]->size        = SIZEOF_MM_ALLOCNODE;
   heap->mm_heapend[IDX]->preceding   = node->size | MM_ALLOC_BIT;
+  MM_ADD_BACKTRACE(heap->mm_heapend[IDX]);
 
 #undef IDX
 
diff --git a/mm/mm_heap/mm_malloc.c b/mm/mm_heap/mm_malloc.c
index a1262f5..9a94910 100644
--- a/mm/mm_heap/mm_malloc.c
+++ b/mm/mm_heap/mm_malloc.c
@@ -223,6 +223,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
       /* Handle the case of an exact size match */
 
       node->preceding |= MM_ALLOC_BIT;
+      MM_ADD_BACKTRACE(node);
       ret = (FAR void *)((FAR char *)node + SIZEOF_MM_ALLOCNODE);
     }
 
diff --git a/mm/mm_heap/mm_memalign.c b/mm/mm_heap/mm_memalign.c
index 1fcd387..0fa3968 100644
--- a/mm/mm_heap/mm_memalign.c
+++ b/mm/mm_heap/mm_memalign.c
@@ -178,6 +178,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
 
       newnode->size = (size_t)next - (size_t)newnode;
       newnode->preceding = precedingsize | MM_ALLOC_BIT;
+      MM_ADD_BACKTRACE(newnode);
 
       /* Reduce the size of the original chunk and mark it not allocated, */
 
diff --git a/mm/mm_heap/mm_memdump.c b/mm/mm_heap/mm_memdump.c
index b3b5a5a..4cea66d6 100644
--- a/mm/mm_heap/mm_memdump.c
+++ b/mm/mm_heap/mm_memdump.c
@@ -33,6 +33,20 @@
 
 #include "mm_heap/mm.h"
 
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if UINTPTR_MAX <= UINT32_MAX
+#  define MM_PTR_FMT_WIDTH 11
+#elif UINTPTR_MAX <= UINT64_MAX
+#  define MM_PTR_FMT_WIDTH 19
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
 struct memdump_info_s
 {
   pid_t pid;
@@ -51,13 +65,32 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
   if ((node->preceding & MM_ALLOC_BIT) != 0)
     {
       DEBUGASSERT(node->size >= SIZEOF_MM_ALLOCNODE);
+#ifndef CONFIG_DEBUG_MM
       if (info->pid == -1)
+#else
+      if (info->pid == -1 || node->pid == info->pid)
+#endif
         {
+#ifndef CONFIG_DEBUG_MM
+          syslog(LOG_INFO, "%12zu%*p\n",
+                 (size_t)node->size, MM_PTR_FMT_WIDTH,
+                 ((FAR char *)node + SIZEOF_MM_ALLOCNODE));
+#else
+          int i;
+          char buf[MM_BACKTRACE_DEPTH * MM_PTR_FMT_WIDTH + 1];
+
+          for (i = 0; i < MM_BACKTRACE_DEPTH && node->backtrace[i]; i++)
+            {
+              sprintf(buf + i * MM_PTR_FMT_WIDTH, " %*p",
+                      MM_PTR_FMT_WIDTH - 3, node->backtrace[i]);
+            }
+
+          syslog(LOG_INFO, "%6d%12zu%*p%s\n",
+                 (int)node->pid, (size_t)node->size, MM_PTR_FMT_WIDTH,
+                 ((FAR char *)node + SIZEOF_MM_ALLOCNODE), buf);
+#endif
           info->blks++;
           info->size += node->size;
-          syslog(LOG_INFO, "%12p%12" PRIu32 "\n",
-                 ((FAR char *)node + SIZEOF_MM_ALLOCNODE),
-                 node->size);
         }
     }
   else
@@ -73,13 +106,13 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
                   fnode->flink->size == 0 ||
                   fnode->flink->size >= fnode->size);
 
-      if (info->pid == -2)
+      if (info->pid <= -2)
         {
           info->blks++;
           info->size += node->size;
-          syslog(LOG_INFO, "%12p%12" PRIu32 "\n",
-                 ((FAR char *)node + SIZEOF_MM_ALLOCNODE),
-                 node->size);
+          syslog(LOG_INFO, "%12zu%*p\n",
+                 (size_t)node->size, MM_PTR_FMT_WIDTH,
+                 ((FAR char *)node + SIZEOF_MM_ALLOCNODE));
         }
     }
 }
@@ -93,24 +126,32 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
  *
  * Description:
  *   mm_memdump returns a memory info about specified pid of task/thread.
- *
+ *   if pid equals -1, this function will dump all allocated node and output
+ *   backtrace for every allocated node for this heap, if pid equals -2, this
+ *   function will dump all free node for this heap, and if pid is greater
+ *   than or equal to 0, will dump pid allocated node and output backtrace.
  ****************************************************************************/
 
 void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid)
 {
   struct memdump_info_s info;
 
-  if (pid == -1)
+  if (pid >= -1)
     {
       syslog(LOG_INFO, "Dump all used memory node info:\n");
+#ifndef CONFIG_DEBUG_MM
+      syslog(LOG_INFO, "%12s%*s\n", "Size", MM_PTR_FMT_WIDTH, "Address");
+#else
+      syslog(LOG_INFO, "%6s%12s%*s %s\n", "PID", "Size", MM_PTR_FMT_WIDTH,
+             "Address", "Backtrace");
+#endif
     }
-  else if (pid == -2)
+  else
     {
       syslog(LOG_INFO, "Dump all free memory node info:\n");
+      syslog(LOG_INFO, "%12s%*s\n", "Size", MM_PTR_FMT_WIDTH, "Address");
     }
 
-  syslog(LOG_INFO, "%12s%12s\n", "Address", "Size");
-
   info.blks = 0;
   info.size = 0;
   info.pid  = pid;
diff --git a/mm/mm_heap/mm_realloc.c b/mm/mm_heap/mm_realloc.c
index 1842572..366cbfe 100644
--- a/mm/mm_heap/mm_realloc.c
+++ b/mm/mm_heap/mm_realloc.c
@@ -128,6 +128,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
                        oldsize - oldnode->size);
         }
 
+      MM_ADD_BACKTRACE(oldnode);
+
       /* Then return the original address */
 
       mm_givesemaphore(heap);
@@ -332,6 +334,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
             }
         }
 
+      MM_ADD_BACKTRACE((FAR char *)newmem - SIZEOF_MM_ALLOCNODE);
+
       mm_givesemaphore(heap);
 
       kasan_unpoison(newmem, mm_malloc_size(newmem));

[incubator-nuttx] 05/06: mm/memdump: fix print backtrace abnormal

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/incubator-nuttx.git

commit 168074fe2eddd1e6265c6378af980e165e3dc55d
Author: Jiuzhu Dong <do...@xiaomi.com>
AuthorDate: Wed Feb 9 15:27:22 2022 +0800

    mm/memdump: fix print backtrace abnormal
    
    Signed-off-by: Jiuzhu Dong <do...@xiaomi.com>
---
 mm/mm_heap/mm_memdump.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/mm/mm_heap/mm_memdump.c b/mm/mm_heap/mm_memdump.c
index 4cea66d6..cc99a8e 100644
--- a/mm/mm_heap/mm_memdump.c
+++ b/mm/mm_heap/mm_memdump.c
@@ -77,12 +77,14 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
                  ((FAR char *)node + SIZEOF_MM_ALLOCNODE));
 #else
           int i;
+          FAR const char *format = " %0*p";
           char buf[MM_BACKTRACE_DEPTH * MM_PTR_FMT_WIDTH + 1];
 
+          buf[0] = '\0';
           for (i = 0; i < MM_BACKTRACE_DEPTH && node->backtrace[i]; i++)
             {
-              sprintf(buf + i * MM_PTR_FMT_WIDTH, " %*p",
-                      MM_PTR_FMT_WIDTH - 3, node->backtrace[i]);
+              sprintf(buf + i * MM_PTR_FMT_WIDTH, format,
+                      MM_PTR_FMT_WIDTH - 1, node->backtrace[i]);
             }
 
           syslog(LOG_INFO, "%6d%12zu%*p%s\n",

[incubator-nuttx] 02/06: procfs: add memdump interface to dump used/free memory info

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/incubator-nuttx.git

commit c5ba9261bcde94025e64f20eebe4f22592f84bc1
Author: Jiuzhu Dong <do...@xiaomi.com>
AuthorDate: Thu Jan 6 20:44:17 2022 +0800

    procfs: add memdump interface to dump used/free memory info
    
    usage:echo <used/free> > /proc/memdump
    echo used > /proc/memdump // output all used memory node info(address + size)
    echo free > /proc/memdump // output all free memory node info(address + size)
    
    Signed-off-by: Jiuzhu Dong <do...@xiaomi.com>
---
 arch/sim/src/sim/up_heap.c   |  12 +++++
 fs/procfs/Kconfig            |   4 ++
 fs/procfs/fs_procfs.c        |   4 ++
 fs/procfs/fs_procfsmeminfo.c | 121 +++++++++++++++++++++++++++++++++++++------
 include/nuttx/mm/mm.h        |   1 +
 mm/mm_heap/Make.defs         |   2 +-
 mm/mm_heap/mm_memdump.c      | 121 +++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 249 insertions(+), 16 deletions(-)

diff --git a/arch/sim/src/sim/up_heap.c b/arch/sim/src/sim/up_heap.c
index 196c6aa..d05c746 100644
--- a/arch/sim/src/sim/up_heap.c
+++ b/arch/sim/src/sim/up_heap.c
@@ -389,6 +389,18 @@ int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info)
   return 0;
 }
 
+/****************************************************************************
+ * Name: mm_memdump
+ *
+ * Description:
+ *   mm_memdump returns a memory info about specified pid of task/thread.
+ *
+ ****************************************************************************/
+
+void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid)
+{
+}
+
 #ifdef CONFIG_DEBUG_MM
 
 /****************************************************************************
diff --git a/fs/procfs/Kconfig b/fs/procfs/Kconfig
index 6d28080..f5c275f 100644
--- a/fs/procfs/Kconfig
+++ b/fs/procfs/Kconfig
@@ -96,6 +96,10 @@ config FS_PROCFS_EXCLUDE_MEMINFO
 	bool "Exclude meminfo"
 	default n
 
+config FS_PROCFS_EXCLUDE_MEMDUMP
+	bool "Exclude memdump"
+	default n
+
 config FS_PROCFS_INCLUDE_PROGMEM
 	bool "Include prog mem"
 	default n
diff --git a/fs/procfs/fs_procfs.c b/fs/procfs/fs_procfs.c
index 6d04af6..0c69f8a 100644
--- a/fs/procfs/fs_procfs.c
+++ b/fs/procfs/fs_procfs.c
@@ -66,6 +66,7 @@ extern const struct procfs_operations irq_operations;
 extern const struct procfs_operations cpuload_operations;
 extern const struct procfs_operations critmon_operations;
 extern const struct procfs_operations meminfo_operations;
+extern const struct procfs_operations memdump_operations;
 extern const struct procfs_operations iobinfo_operations;
 extern const struct procfs_operations module_operations;
 extern const struct procfs_operations uptime_operations;
@@ -115,6 +116,9 @@ static const struct procfs_entry_s g_procfs_entries[] =
 
 #ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMINFO
   { "meminfo",       &meminfo_operations,         PROCFS_FILE_TYPE   },
+#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMDUMP
+  { "memdump",       &memdump_operations,         PROCFS_FILE_TYPE   },
+#endif
 #endif
 
 #if defined(CONFIG_MM_IOB) && !defined(CONFIG_FS_PROCFS_EXCLUDE_IOBINFO)
diff --git a/fs/procfs/fs_procfsmeminfo.c b/fs/procfs/fs_procfsmeminfo.c
index 0156347..13d86da 100644
--- a/fs/procfs/fs_procfsmeminfo.c
+++ b/fs/procfs/fs_procfsmeminfo.c
@@ -94,6 +94,12 @@ static void    meminfo_progmem(FAR struct progmem_info_s *progmem);
 static int     meminfo_open(FAR struct file *filep, FAR const char *relpath,
                  int oflags, mode_t mode);
 static int     meminfo_close(FAR struct file *filep);
+#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMDUMP
+static ssize_t memdump_read(FAR struct file *filep, FAR char *buffer,
+                             size_t buflen);
+static ssize_t memdump_write(FAR struct file *filep, FAR const char *buffer,
+                             size_t buflen);
+#endif
 static ssize_t meminfo_read(FAR struct file *filep, FAR char *buffer,
                  size_t buflen);
 static int     meminfo_dup(FAR const struct file *oldp,
@@ -123,6 +129,22 @@ const struct procfs_operations meminfo_operations =
   meminfo_stat    /* stat */
 };
 
+#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMDUMP
+const struct procfs_operations memdump_operations =
+{
+  meminfo_open,   /* open */
+  meminfo_close,  /* close */
+  memdump_read,   /* read */
+  memdump_write,  /* write */
+  meminfo_dup,    /* dup */
+  NULL,           /* opendir */
+  NULL,           /* closedir */
+  NULL,           /* readdir */
+  NULL,           /* rewinddir */
+  meminfo_stat    /* stat */
+};
+#endif
+
 FAR struct procfs_meminfo_entry_s *g_procfs_meminfo = NULL;
 
 /****************************************************************************
@@ -206,22 +228,9 @@ static int meminfo_open(FAR struct file *filep, FAR const char *relpath,
 
   finfo("Open '%s'\n", relpath);
 
-  /* PROCFS is read-only.  Any attempt to open with any kind of write
-   * access is not permitted.
-   *
-   * REVISIT:  Write-able proc files could be quite useful.
-   */
-
-  if ((oflags & O_WRONLY) != 0 || (oflags & O_RDONLY) == 0)
-    {
-      ferr("ERROR: Only O_RDONLY supported\n");
-      return -EACCES;
-    }
-
   /* Allocate a container to hold the file attributes */
 
-  procfile = (FAR struct meminfo_file_s *)
-    kmm_zalloc(sizeof(struct meminfo_file_s));
+  procfile = kmm_zalloc(sizeof(struct meminfo_file_s));
   if (!procfile)
     {
       ferr("ERROR: Failed to allocate file attributes\n");
@@ -230,7 +239,7 @@ static int meminfo_open(FAR struct file *filep, FAR const char *relpath,
 
   /* Save the attributes as the open-specific state in filep->f_priv */
 
-  filep->f_priv = (FAR void *)procfile;
+  filep->f_priv = procfile;
   return OK;
 }
 
@@ -383,6 +392,88 @@ static ssize_t meminfo_read(FAR struct file *filep, FAR char *buffer,
 }
 
 /****************************************************************************
+ * Name: memdump_read
+ ****************************************************************************/
+
+#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMDUMP
+static ssize_t memdump_read(FAR struct file *filep, FAR char *buffer,
+                            size_t buflen)
+{
+  FAR struct meminfo_file_s *procfile;
+  size_t linesize;
+  size_t copysize;
+  size_t totalsize;
+  off_t offset;
+
+  finfo("buffer=%p buflen=%d\n", buffer, (int)buflen);
+
+  DEBUGASSERT(filep != NULL && buffer != NULL && buflen > 0);
+  offset = filep->f_pos;
+
+  /* Recover our private data from the struct file instance */
+
+  procfile = (FAR struct meminfo_file_s *)filep->f_priv;
+  DEBUGASSERT(procfile);
+
+  linesize  = procfs_snprintf(procfile->line, MEMINFO_LINELEN,
+                              "usage: <used/free>\n");
+
+  copysize  = procfs_memcpy(procfile->line, linesize, buffer, buflen,
+                            &offset);
+  totalsize = copysize;
+  buffer   += copysize;
+  buflen   -= copysize;
+  linesize  = procfs_snprintf(procfile->line, MEMINFO_LINELEN, "%s",
+                              "used: dump all allocated node\n"
+                              "free: dump all free node\n");
+
+  totalsize += procfs_memcpy(procfile->line, linesize, buffer, buflen,
+                             &offset);
+  filep->f_pos += totalsize;
+  return totalsize;
+}
+#endif
+
+/****************************************************************************
+ * Name: memdump_write
+ ****************************************************************************/
+
+#ifndef CONFIG_FS_PROCFS_EXCLUDE_MEMDUMP
+static ssize_t memdump_write(FAR struct file *filep, FAR const char *buffer,
+                             size_t buflen)
+{
+  FAR const struct procfs_meminfo_entry_s *entry;
+  FAR struct meminfo_file_s *procfile;
+  pid_t pid = -1;
+
+  DEBUGASSERT(filep != NULL && buffer != NULL && buflen > 0);
+
+  /* Recover our private data from the struct file instance */
+
+  procfile = filep->f_priv;
+  DEBUGASSERT(procfile);
+
+  switch (buffer[0])
+    {
+      case 'u':
+        pid = -1;
+        break;
+
+      case 'f':
+        pid = -2;
+        break;
+    }
+
+  for (entry = g_procfs_meminfo; entry != NULL; entry = entry->next)
+    {
+      mm_memdump(entry->user_data, pid);
+    }
+
+  return buflen;
+}
+#endif
+
+/****************************************************************************
  * Name: meminfo_dup
  *
  * Description:
diff --git a/include/nuttx/mm/mm.h b/include/nuttx/mm/mm.h
index fa9e3a1..246a1b6 100644
--- a/include/nuttx/mm/mm.h
+++ b/include/nuttx/mm/mm.h
@@ -296,6 +296,7 @@ void kmm_extend(FAR void *mem, size_t size, int region);
 
 struct mallinfo; /* Forward reference */
 int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info);
+void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid);
 
 /* Functions contained in kmm_mallinfo.c ************************************/
 
diff --git a/mm/mm_heap/Make.defs b/mm/mm_heap/Make.defs
index c9c0c1c..fdeb15d 100644
--- a/mm/mm_heap/Make.defs
+++ b/mm/mm_heap/Make.defs
@@ -25,7 +25,7 @@ ifeq ($(CONFIG_MM_DEFAULT_MANAGER),y)
 CSRCS += mm_initialize.c mm_sem.c mm_addfreechunk.c mm_size2ndx.c
 CSRCS += mm_malloc_size.c mm_shrinkchunk.c mm_brkaddr.c mm_calloc.c
 CSRCS += mm_extend.c mm_free.c mm_mallinfo.c mm_malloc.c mm_foreach.c
-CSRCS += mm_memalign.c mm_realloc.c mm_zalloc.c mm_heapmember.c
+CSRCS += mm_memalign.c mm_realloc.c mm_zalloc.c mm_heapmember.c mm_memdump.c
 
 ifeq ($(CONFIG_DEBUG_MM),y)
 CSRCS += mm_checkcorruption.c
diff --git a/mm/mm_heap/mm_memdump.c b/mm/mm_heap/mm_memdump.c
new file mode 100644
index 0000000..b3b5a5a
--- /dev/null
+++ b/mm/mm_heap/mm_memdump.c
@@ -0,0 +1,121 @@
+/****************************************************************************
+ * mm/mm_heap/mm_memdump.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/config.h>
+
+#include <stdio.h>
+#include <malloc.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/mm/mm.h>
+
+#include "mm_heap/mm.h"
+
+struct memdump_info_s
+{
+  pid_t pid;
+  int   blks;
+  int   size;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
+{
+  FAR struct memdump_info_s *info = arg;
+
+  if ((node->preceding & MM_ALLOC_BIT) != 0)
+    {
+      DEBUGASSERT(node->size >= SIZEOF_MM_ALLOCNODE);
+      if (info->pid == -1)
+        {
+          info->blks++;
+          info->size += node->size;
+          syslog(LOG_INFO, "%12p%12" PRIu32 "\n",
+                 ((FAR char *)node + SIZEOF_MM_ALLOCNODE),
+                 node->size);
+        }
+    }
+  else
+    {
+      FAR struct mm_freenode_s *fnode = (FAR void *)node;
+
+      DEBUGASSERT(node->size >= SIZEOF_MM_FREENODE);
+      DEBUGASSERT(fnode->blink->flink == fnode);
+      DEBUGASSERT(fnode->blink->size <= fnode->size);
+      DEBUGASSERT(fnode->flink == NULL ||
+                  fnode->flink->blink == fnode);
+      DEBUGASSERT(fnode->flink == NULL ||
+                  fnode->flink->size == 0 ||
+                  fnode->flink->size >= fnode->size);
+
+      if (info->pid == -2)
+        {
+          info->blks++;
+          info->size += node->size;
+          syslog(LOG_INFO, "%12p%12" PRIu32 "\n",
+                 ((FAR char *)node + SIZEOF_MM_ALLOCNODE),
+                 node->size);
+        }
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mm_memdump
+ *
+ * Description:
+ *   mm_memdump returns a memory info about specified pid of task/thread.
+ *
+ ****************************************************************************/
+
+void mm_memdump(FAR struct mm_heap_s *heap, pid_t pid)
+{
+  struct memdump_info_s info;
+
+  if (pid == -1)
+    {
+      syslog(LOG_INFO, "Dump all used memory node info:\n");
+    }
+  else if (pid == -2)
+    {
+      syslog(LOG_INFO, "Dump all free memory node info:\n");
+    }
+
+  syslog(LOG_INFO, "%12s%12s\n", "Address", "Size");
+
+  info.blks = 0;
+  info.size = 0;
+  info.pid  = pid;
+  mm_foreach(heap, memdump_handler, &info);
+
+  syslog(LOG_INFO, "%12s%12s\n", "Total Blks", "Total Size");
+  syslog(LOG_INFO, "%12d%12d\n", info.blks, info.size);
+}

[incubator-nuttx] 04/06: procfs: add heap info for every task

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/incubator-nuttx.git

commit 7ae3c572dc8475e9ef2d6b05e2dc62c99f5203ca
Author: Jiuzhu Dong <do...@xiaomi.com>
AuthorDate: Sat Jan 22 20:21:51 2022 +0800

    procfs: add heap info for every task
    
    cat /proc/2/heap
    AllocSize:  512
    AllocBlks:  10
    
    Signed-off-by: Jiuzhu Dong <do...@xiaomi.com>
---
 fs/procfs/fs_procfsproc.c  | 80 ++++++++++++++++++++++++++++++++++++++++++++++
 include/malloc.h           | 12 +++++++
 include/nuttx/mm/mm.h      |  8 +++++
 mm/kmm_heap/kmm_mallinfo.c | 19 +++++++++++
 mm/mm_heap/mm_mallinfo.c   | 42 ++++++++++++++++++++++++
 mm/umm_heap/umm_mallinfo.c | 20 ++++++++++++
 6 files changed, 181 insertions(+)

diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c
index 60ca146..fbf622f 100644
--- a/fs/procfs/fs_procfsproc.c
+++ b/fs/procfs/fs_procfsproc.c
@@ -37,6 +37,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <debug.h>
+#include <malloc.h>
 
 #ifdef CONFIG_SCHED_CRITMONITOR
 #  include <time.h>
@@ -50,6 +51,7 @@
 #include <nuttx/fs/fs.h>
 #include <nuttx/fs/procfs.h>
 #include <nuttx/fs/dirent.h>
+#include <nuttx/mm/mm.h>
 
 #if defined(CONFIG_SCHED_CPULOAD) || defined(CONFIG_SCHED_CRITMONITOR)
 #  include <nuttx/clock.h>
@@ -87,6 +89,9 @@ enum proc_node_e
 #ifdef CONFIG_SCHED_CRITMONITOR
   PROC_CRITMON,                       /* Critical section monitor */
 #endif
+#ifdef CONFIG_DEBUG_MM
+  PROC_HEAP,                          /* Task heap info */
+#endif
   PROC_STACK,                         /* Task stack info */
   PROC_GROUP,                         /* Group directory */
   PROC_GROUP_STATUS,                  /* Task group status */
@@ -172,6 +177,11 @@ static ssize_t proc_critmon(FAR struct proc_file_s *procfile,
                  FAR struct tcb_s *tcb, FAR char *buffer, size_t buflen,
                  off_t offset);
 #endif
+#ifdef CONFIG_DEBUG_MM
+static ssize_t proc_heap(FAR struct proc_file_s *procfile,
+                         FAR struct tcb_s *tcb, FAR char *buffer,
+                         size_t buflen, off_t offset);
+#endif
 static ssize_t proc_stack(FAR struct proc_file_s *procfile,
                  FAR struct tcb_s *tcb, FAR char *buffer, size_t buflen,
                  off_t offset);
@@ -268,6 +278,13 @@ static const struct proc_node_s g_critmon =
 };
 #endif
 
+#ifdef CONFIG_DEBUG_MM
+static const struct proc_node_s g_heap =
+{
+  "heap",         "heap",   (uint8_t)PROC_HEAP,          DTYPE_FILE        /* Task heap info */
+};
+#endif
+
 static const struct proc_node_s g_stack =
 {
   "stack",        "stack",   (uint8_t)PROC_STACK,        DTYPE_FILE        /* Task stack info */
@@ -308,6 +325,9 @@ static FAR const struct proc_node_s * const g_nodeinfo[] =
 #ifdef CONFIG_SCHED_CRITMONITOR
   &g_critmon,      /* Critical section Monitor */
 #endif
+#ifdef CONFIG_DEBUG_MM
+  &g_heap,         /* Task heap info */
+#endif
   &g_stack,        /* Task stack info */
   &g_group,        /* Group directory */
   &g_groupstatus,  /* Task group status */
@@ -331,6 +351,9 @@ static const struct proc_node_s * const g_level0info[] =
 #ifdef CONFIG_SCHED_CRITMONITOR
   &g_critmon,      /* Critical section monitor */
 #endif
+#ifdef CONFIG_DEBUG_MM
+  &g_heap,         /* Task heap info */
+#endif
   &g_stack,        /* Task stack info */
   &g_group,        /* Group directory */
 };
@@ -877,6 +900,58 @@ static ssize_t proc_critmon(FAR struct proc_file_s *procfile,
 #endif
 
 /****************************************************************************
+ * Name: proc_heap
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_MM
+static ssize_t proc_heap(FAR struct proc_file_s *procfile,
+                         FAR struct tcb_s *tcb, FAR char *buffer,
+                         size_t buflen, off_t offset)
+{
+  size_t remaining = buflen;
+  size_t linesize;
+  size_t copysize;
+  size_t totalsize = 0;
+  struct mallinfo_task info;
+
+#ifdef CONFIG_MM_KERNEL_HEAP
+  if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL)
+    {
+      info = kmm_mallinfo_task(tcb->pid);
+    }
+  else
+#endif
+    {
+      info = mallinfo_task(tcb->pid);
+    }
+
+  /* Show the heap alloc size */
+
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                               "%-12s%d\n", "AllocSize:", info.uordblks);
+  copysize   = procfs_memcpy(procfile->line, linesize, buffer, remaining,
+                             &offset);
+
+  totalsize += copysize;
+  buffer    += copysize;
+  remaining -= copysize;
+
+  if (totalsize >= buflen)
+    {
+      return totalsize;
+    }
+
+  /* Show the heap alloc block */
+
+  linesize   = procfs_snprintf(procfile->line, STATUS_LINELEN,
+                               "%-12s%d\n", "AllocBlks:", info.aordblks);
+  totalsize += procfs_memcpy(procfile->line, linesize, buffer, remaining,
+                             &offset);
+  return totalsize;
+}
+#endif
+
+/****************************************************************************
  * Name: proc_stack
  ****************************************************************************/
 
@@ -1484,6 +1559,11 @@ static ssize_t proc_read(FAR struct file *filep, FAR char *buffer,
       ret = proc_critmon(procfile, tcb, buffer, buflen, filep->f_pos);
       break;
 #endif
+#ifdef CONFIG_DEBUG_MM
+    case PROC_HEAP: /* Task heap info */
+      ret = proc_heap(procfile, tcb, buffer, buflen, filep->f_pos);
+      break;
+#endif
     case PROC_STACK: /* Task stack info */
       ret = proc_stack(procfile, tcb, buffer, buflen, filep->f_pos);
       break;
diff --git a/include/malloc.h b/include/malloc.h
index 0854174..50345c3 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -52,6 +52,15 @@ struct mallinfo
                  * by free (not in use) chunks. */
 };
 
+#ifdef CONFIG_DEBUG_MM
+struct mallinfo_task
+{
+  pid_t pid;    /* The pid of task */
+  int aordblks; /* This is the number of allocated (in use) chunks for task */
+  int uordblks; /* This is the total size of memory occupied for task */
+};
+#endif
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
@@ -63,6 +72,9 @@ extern "C"
 
 struct mallinfo mallinfo(void);
 size_t malloc_size(FAR void *ptr);
+#ifdef CONFIG_DEBUG_MM
+struct mallinfo_task mallinfo_task(pid_t pid);
+#endif
 
 #if defined(__cplusplus)
 }
diff --git a/include/nuttx/mm/mm.h b/include/nuttx/mm/mm.h
index aad4e6f..6f78a6a 100644
--- a/include/nuttx/mm/mm.h
+++ b/include/nuttx/mm/mm.h
@@ -296,11 +296,19 @@ void kmm_extend(FAR void *mem, size_t size, int region);
 
 struct mallinfo; /* Forward reference */
 int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info);
+#ifdef CONFIG_DEBUG_MM
+struct mallinfo_task; /* Forward reference */
+int mm_mallinfo_task(FAR struct mm_heap_s *heap,
+                     FAR struct mallinfo_task *info);
+#endif
 
 /* Functions contained in kmm_mallinfo.c ************************************/
 
 #ifdef CONFIG_MM_KERNEL_HEAP
 struct mallinfo kmm_mallinfo(void);
+#  ifdef CONFIG_DEBUG_MM
+struct mallinfo_task kmm_mallinfo_task(pid_t pid);
+#  endif
 #endif
 
 /* Functions contained in mm_memdump.c **************************************/
diff --git a/mm/kmm_heap/kmm_mallinfo.c b/mm/kmm_heap/kmm_mallinfo.c
index 1172ed4..33dd664 100644
--- a/mm/kmm_heap/kmm_mallinfo.c
+++ b/mm/kmm_heap/kmm_mallinfo.c
@@ -50,4 +50,23 @@ struct mallinfo kmm_mallinfo(void)
   return info;
 }
 
+/****************************************************************************
+ * Name: kmm_mallinfo_task
+ *
+ * Description:
+ *   kmm_mallinfo_task returns a copy of updated current heap information of
+ *   task with specified pid for the user heap.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_MM
+struct mallinfo_task kmm_mallinfo_task(pid_t pid)
+{
+  struct mallinfo_task info;
+
+  info.pid = pid;
+  mm_mallinfo_task(g_kmmheap, &info);
+  return info;
+}
+#endif
 #endif /* CONFIG_MM_KERNEL_HEAP */
diff --git a/mm/mm_heap/mm_mallinfo.c b/mm/mm_heap/mm_mallinfo.c
index e3fb94a..7ecdc03 100644
--- a/mm/mm_heap/mm_mallinfo.c
+++ b/mm/mm_heap/mm_mallinfo.c
@@ -75,6 +75,26 @@ static void mallinfo_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
     }
 }
 
+#ifdef CONFIG_DEBUG_MM
+static void mallinfo_task_handler(FAR struct mm_allocnode_s *node,
+                                  FAR void *arg)
+{
+  FAR struct mallinfo_task *info = arg;
+
+  /* Check if the node corresponds to an allocated memory chunk */
+
+  if ((node->preceding & MM_ALLOC_BIT) != 0)
+    {
+      DEBUGASSERT(node->size >= SIZEOF_MM_ALLOCNODE);
+      if (node->pid == info->pid)
+        {
+          info->aordblks++;
+          info->uordblks += node->size;
+        }
+    }
+}
+#endif
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -107,3 +127,25 @@ int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info)
 
   return OK;
 }
+
+/****************************************************************************
+ * Name: mm_mallinfo_task
+ *
+ * Description:
+ *   mallinfo returns a copy of updated current heap information for task
+ *   with pid.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_MM
+int mm_mallinfo_task(FAR struct mm_heap_s *heap,
+                     FAR struct mallinfo_task *info)
+{
+  DEBUGASSERT(info);
+
+  info->uordblks = 0;
+  info->aordblks = 0;
+  mm_foreach(heap, mallinfo_task_handler, info);
+  return OK;
+}
+#endif
diff --git a/mm/umm_heap/umm_mallinfo.c b/mm/umm_heap/umm_mallinfo.c
index 2176095..e59cfa8 100644
--- a/mm/umm_heap/umm_mallinfo.c
+++ b/mm/umm_heap/umm_mallinfo.c
@@ -49,3 +49,23 @@ struct mallinfo mallinfo(void)
   mm_mallinfo(USR_HEAP, &info);
   return info;
 }
+
+/****************************************************************************
+ * Name: mallinfo_task
+ *
+ * Description:
+ *   mallinfo_task returns a copy of updated current heap information of
+ *   task with specified pid for the user heap.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_MM
+struct mallinfo_task mallinfo_task(pid_t pid)
+{
+  struct mallinfo_task info;
+
+  info.pid = pid;
+  mm_mallinfo_task(USR_HEAP, &info);
+  return info;
+}
+#endif

[incubator-nuttx] 01/06: mm/mm_heap: remove the unnecessary check for memory node size

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/incubator-nuttx.git

commit 39eaeefb78f36724adbdc47400d6f60372b68344
Author: Jiuzhu Dong <do...@xiaomi.com>
AuthorDate: Thu Jan 27 12:17:20 2022 +0800

    mm/mm_heap: remove the unnecessary check for memory node size
    
    Signed-off-by: Jiuzhu Dong <do...@xiaomi.com>
---
 mm/mm_heap/mm.h            | 37 +++++++++++++++++--------------------
 mm/mm_heap/mm_initialize.c |  9 ---------
 2 files changed, 17 insertions(+), 29 deletions(-)

diff --git a/mm/mm_heap/mm.h b/mm/mm_heap/mm.h
index 4726acb..1d7219d 100644
--- a/mm/mm_heap/mm.h
+++ b/mm/mm_heap/mm.h
@@ -29,6 +29,7 @@
 
 #include <nuttx/fs/procfs.h>
 
+#include <assert.h>
 #include <sys/types.h>
 #include <stdbool.h>
 #include <string.h>
@@ -103,12 +104,23 @@
 
 #ifdef CONFIG_MM_SMALL
 # define MM_ALLOC_BIT    0x8000
+# define MMSIZE_MAX      UINT16_MAX
 #else
 # define MM_ALLOC_BIT    0x80000000
+# define MMSIZE_MAX      UINT32_MAX
 #endif
+
 #define MM_IS_ALLOCATED(n) \
   ((int)((FAR struct mm_allocnode_s *)(n)->preceding) < 0)
 
+/* What is the size of the allocnode? */
+
+#define SIZEOF_MM_ALLOCNODE sizeof(struct mm_allocnode_s)
+
+/* What is the size of the freenode? */
+
+#define SIZEOF_MM_FREENODE sizeof(struct mm_freenode_s)
+
 /****************************************************************************
  * Public Types
  ****************************************************************************/
@@ -117,10 +129,8 @@
 
 #ifdef CONFIG_MM_SMALL
 typedef uint16_t mmsize_t;
-#  define MMSIZE_MAX UINT16_MAX
 #else
 typedef uint32_t mmsize_t;
-#  define MMSIZE_MAX UINT32_MAX
 #endif
 
 /* This describes an allocated chunk.  An allocated chunk is
@@ -134,16 +144,8 @@ struct mm_allocnode_s
   mmsize_t preceding;      /* Size of the preceding chunk */
 };
 
-/* What is the size of the allocnode? */
-
-#ifdef CONFIG_MM_SMALL
-# define SIZEOF_MM_ALLOCNODE   (4)
-#else
-# define SIZEOF_MM_ALLOCNODE   (8)
-#endif
-
-#define CHECK_ALLOCNODE_SIZE \
-  DEBUGASSERT(sizeof(struct mm_allocnode_s) == SIZEOF_MM_ALLOCNODE)
+static_assert(SIZEOF_MM_ALLOCNODE <= MM_MIN_CHUNK,
+              "Error size for struct mm_allocnode_s\n");
 
 /* This describes a free chunk */
 
@@ -155,19 +157,14 @@ struct mm_freenode_s
   FAR struct mm_freenode_s *blink;
 };
 
+static_assert(SIZEOF_MM_FREENODE <= MM_MIN_CHUNK,
+              "Error size for struct mm_freenode_s\n");
+
 struct mm_delaynode_s
 {
   FAR struct mm_delaynode_s *flink;
 };
 
-/* What is the size of the freenode? */
-
-#define MM_PTR_SIZE sizeof(FAR struct mm_freenode_s *)
-#define SIZEOF_MM_FREENODE (SIZEOF_MM_ALLOCNODE + 2*MM_PTR_SIZE)
-
-#define CHECK_FREENODE_SIZE \
-  DEBUGASSERT(sizeof(struct mm_freenode_s) == SIZEOF_MM_FREENODE)
-
 /* This describes one heap (possibly with multiple regions) */
 
 struct mm_heap_s
diff --git a/mm/mm_heap/mm_initialize.c b/mm/mm_heap/mm_initialize.c
index 4e2a21b..bf84db4 100644
--- a/mm/mm_heap/mm_initialize.c
+++ b/mm/mm_heap/mm_initialize.c
@@ -182,15 +182,6 @@ FAR struct mm_heap_s *mm_initialize(FAR const char *name,
   heapsize -= sizeof(struct mm_heap_s);
   heapstart = (FAR char *)heap_adj + sizeof(struct mm_heap_s);
 
-  /* The following two lines have cause problems for some older ZiLog
-   * compilers in the past (but not the more recent).  Life is easier if we
-   * just the suppress them altogther for those tools.
-   */
-
-#ifndef __ZILOG__
-  CHECK_ALLOCNODE_SIZE;
-  CHECK_FREENODE_SIZE;
-#endif
   DEBUGASSERT(MM_MIN_CHUNK >= SIZEOF_MM_FREENODE);
   DEBUGASSERT(MM_MIN_CHUNK >= SIZEOF_MM_ALLOCNODE);
 

[incubator-nuttx] 06/06: mm/mm_malloc: dump all allocated memory info when malloc failed

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/incubator-nuttx.git

commit 018d7d605c4a1bb4b419a4421020394c3ddb82a2
Author: Jiuzhu Dong <do...@xiaomi.com>
AuthorDate: Fri Jan 28 14:11:47 2022 +0800

    mm/mm_malloc: dump all allocated memory info when malloc failed
    
    Signed-off-by: Jiuzhu Dong <do...@xiaomi.com>
---
 mm/mm_heap/mm_malloc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/mm_heap/mm_malloc.c b/mm/mm_heap/mm_malloc.c
index 9a94910..d392c2a 100644
--- a/mm/mm_heap/mm_malloc.c
+++ b/mm/mm_heap/mm_malloc.c
@@ -244,6 +244,8 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
   else
     {
       mwarn("WARNING: Allocation failed, size %zu\n", alignsize);
+      mm_memdump(heap, -1);
+      DEBUGASSERT(false);
     }
 #endif