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);