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 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
Jiuzhu Dong 2022-03-17 14:02:37 +08:00 committed by Xiang Xiao
parent 42664f4505
commit 709207b8d3
7 changed files with 49 additions and 12 deletions

View File

@ -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':

View File

@ -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
};
/****************************************************************************

View File

@ -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

View File

@ -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

View File

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

View File

@ -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, */

View File

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