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 709207b8d3b9e019c841b163fe893d8e1c77348a
Author: Jiuzhu Dong <dongjiuz...@xiaomi.com>
AuthorDate: Thu Mar 17 14:02:37 2022 +0800

    mm/memdump: dynamic turn on backtrace in heap when enable DEBUG_MM
    
    default turn off.
    turn on: echo on > /proc/memdump
    turn off: echo off > proc/memdump
    
    Signed-off-by: Jiuzhu Dong <dongjiuz...@xiaomi.com>
---
 fs/procfs/fs_procfsmeminfo.c | 26 ++++++++++++++++++++++++--
 include/nuttx/fs/procfs.h    |  8 ++++++++
 mm/mm_heap/mm.h              | 15 +++++++++++----
 mm/mm_heap/mm_initialize.c   |  4 ++--
 mm/mm_heap/mm_malloc.c       |  2 +-
 mm/mm_heap/mm_memalign.c     |  2 +-
 mm/mm_heap/mm_realloc.c      |  4 ++--
 7 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/fs/procfs/fs_procfsmeminfo.c b/fs/procfs/fs_procfsmeminfo.c
index 29f3ff3..50b3ac4 100644
--- a/fs/procfs/fs_procfsmeminfo.c
+++ b/fs/procfs/fs_procfsmeminfo.c
@@ -417,7 +417,8 @@ static ssize_t memdump_read(FAR struct file *filep, FAR 
char *buffer,
 
 #ifdef CONFIG_DEBUG_MM
   linesize  = procfs_snprintf(procfile->line, MEMINFO_LINELEN,
-                              "usage: <pid/used/free>\n"
+                              "usage: <pid/used/free/on/off>\n"
+                              "on/off backtrace\n"
                               "pid: dump pid allocated node\n");
 #else
   linesize  = procfs_snprintf(procfile->line, MEMINFO_LINELEN,
@@ -448,7 +449,7 @@ static ssize_t memdump_read(FAR struct file *filep, FAR 
char *buffer,
 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 procfs_meminfo_entry_s *entry;
   FAR struct meminfo_file_s *procfile;
   pid_t pid = INVALID_PROCESS_ID;
 
@@ -459,6 +460,27 @@ static ssize_t memdump_write(FAR struct file *filep, FAR 
const char *buffer,
   procfile = filep->f_priv;
   DEBUGASSERT(procfile);
 
+#ifdef CONFIG_DEBUG_MM
+  if (strcmp(buffer, "on") == 0)
+    {
+      for (entry = g_procfs_meminfo; entry != NULL; entry = entry->next)
+        {
+          entry->backtrace = true;
+        }
+
+      return buflen;
+    }
+  else if (strcmp(buffer, "off") == 0)
+    {
+      for (entry = g_procfs_meminfo; entry != NULL; entry = entry->next)
+        {
+          entry->backtrace = false;
+        }
+
+      return buflen;
+    }
+#endif
+
   switch (buffer[0])
     {
       case 'u':
diff --git a/include/nuttx/fs/procfs.h b/include/nuttx/fs/procfs.h
index b68a2b7..97bd245 100644
--- a/include/nuttx/fs/procfs.h
+++ b/include/nuttx/fs/procfs.h
@@ -133,6 +133,14 @@ struct procfs_meminfo_entry_s
   FAR const char *name;
   FAR struct mm_heap_s *heap;
   struct procfs_meminfo_entry_s *next;
+#if defined(CONFIG_DEBUG_MM)
+
+  /* This is dynamic control flag whether to turn on backtrace in the heap,
+   * you can set it by /proc/memdump.
+   */
+
+  bool backtrace;
+#endif
 };
 
 /****************************************************************************
diff --git a/mm/mm_heap/mm.h b/mm/mm_heap/mm.h
index c4c6a9d..af89268 100644
--- a/mm/mm_heap/mm.h
+++ b/mm/mm_heap/mm.h
@@ -93,17 +93,24 @@
 #ifdef CONFIG_DEBUG_MM
 #  define MM_MIN_SHIFT       (MM_MIN_SHIFT_ + 2)
 #  define MM_BACKTRACE_DEPTH 8
-#  define MM_ADD_BACKTRACE(ptr) \
+#  define MM_ADD_BACKTRACE(heap, 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); \
+         if ((heap)->mm_procfs.backtrace) \
+           { \
+             memset(tmp->backtrace, 0, sizeof(tmp->backtrace)); \
+             backtrace(tmp->backtrace, MM_BACKTRACE_DEPTH); \
+           } \
+         else \
+           { \
+             tmp->backtrace[0] = 0; \
+           } \
        } \
      while (0)
 #else
-#  define MM_ADD_BACKTRACE(ptr)
+#  define MM_ADD_BACKTRACE(heap, ptr)
 #  define MM_MIN_SHIFT MM_MIN_SHIFT_
 #endif
 
diff --git a/mm/mm_heap/mm_initialize.c b/mm/mm_heap/mm_initialize.c
index d13c45c..096ebff 100644
--- a/mm/mm_heap/mm_initialize.c
+++ b/mm/mm_heap/mm_initialize.c
@@ -117,7 +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]);
+  MM_ADD_BACKTRACE(heap, 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 *)
@@ -128,7 +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]);
+  MM_ADD_BACKTRACE(heap, heap->mm_heapend[IDX]);
 
 #undef IDX
 
diff --git a/mm/mm_heap/mm_malloc.c b/mm/mm_heap/mm_malloc.c
index d392c2a..51c789d 100644
--- a/mm/mm_heap/mm_malloc.c
+++ b/mm/mm_heap/mm_malloc.c
@@ -223,7 +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);
+      MM_ADD_BACKTRACE(heap, 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 0fa3968..d3681dd 100644
--- a/mm/mm_heap/mm_memalign.c
+++ b/mm/mm_heap/mm_memalign.c
@@ -178,7 +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);
+      MM_ADD_BACKTRACE(heap, newnode);
 
       /* Reduce the size of the original chunk and mark it not allocated, */
 
diff --git a/mm/mm_heap/mm_realloc.c b/mm/mm_heap/mm_realloc.c
index 366cbfe..7b9abe8 100644
--- a/mm/mm_heap/mm_realloc.c
+++ b/mm/mm_heap/mm_realloc.c
@@ -128,7 +128,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void 
*oldmem,
                        oldsize - oldnode->size);
         }
 
-      MM_ADD_BACKTRACE(oldnode);
+      MM_ADD_BACKTRACE(heap, oldnode);
 
       /* Then return the original address */
 
@@ -334,7 +334,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void 
*oldmem,
             }
         }
 
-      MM_ADD_BACKTRACE((FAR char *)newmem - SIZEOF_MM_ALLOCNODE);
+      MM_ADD_BACKTRACE(heap, (FAR char *)newmem - SIZEOF_MM_ALLOCNODE);
 
       mm_givesemaphore(heap);
 

Reply via email to