libc/execinfo: extract a common backtrace format function
Add a common method to format backtrace to buffer, so it can be used by both mm, fs and other possoble modules. Signed-off-by: fangpeina <fangpeina@xiaomi.com>
This commit is contained in:
parent
ed099f1cea
commit
242b50f921
|
@ -38,6 +38,7 @@
|
|||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#include <malloc.h>
|
||||
#include <execinfo.h>
|
||||
|
||||
#ifdef CONFIG_SCHED_CRITMONITOR
|
||||
# include <time.h>
|
||||
|
|
|
@ -27,15 +27,24 @@
|
|||
|
||||
#include <nuttx/sched.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define backtrace(buffer, size) sched_backtrace(_SCHED_GETTID(), \
|
||||
buffer, size, 0)
|
||||
#define dump_stack() sched_dumpstack(_SCHED_GETTID())
|
||||
/* 3: ' 0x' prefix */
|
||||
|
||||
#define BACKTRACE_PTR_FMT_WIDTH ((int)sizeof(uintptr_t) * 2 + 3)
|
||||
|
||||
/* Buffer size needed to hold formatted `depth` backtraces */
|
||||
|
||||
#define BACKTRACE_BUFFER_SIZE(d) (BACKTRACE_PTR_FMT_WIDTH * (d) + 1)
|
||||
|
||||
#define backtrace(b, s) sched_backtrace(_SCHED_GETTID(), b, s, 0)
|
||||
#define dump_stack() sched_dumpstack(_SCHED_GETTID())
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
|
@ -52,6 +61,8 @@ extern "C"
|
|||
|
||||
FAR char **backtrace_symbols(FAR void *const *buffer, int size);
|
||||
void backtrace_symbols_fd(FAR void *const *buffer, int size, int fd);
|
||||
int backtrace_format(FAR char *buffer, int size,
|
||||
FAR void *backtrace[], int depth);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -88,3 +88,39 @@ void backtrace_symbols_fd(FAR void *const *buffer, int size, int fd)
|
|||
dprintf(fd, "%pS\n", buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: backtrace_format
|
||||
*
|
||||
* Description:
|
||||
* Format a backtrace into a buffer for dumping.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int backtrace_format(FAR char *buffer, int size,
|
||||
FAR void *backtrace[], int depth)
|
||||
{
|
||||
FAR const char *format = "%0*p ";
|
||||
int len = 0;
|
||||
int i;
|
||||
|
||||
if (size < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer[0] = '\0';
|
||||
for (i = 0; i < depth && backtrace[i]; i++)
|
||||
{
|
||||
if (i * BACKTRACE_PTR_FMT_WIDTH >= size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len += snprintf(buffer + i * BACKTRACE_PTR_FMT_WIDTH,
|
||||
size - i * BACKTRACE_PTR_FMT_WIDTH,
|
||||
format, BACKTRACE_PTR_FMT_WIDTH - 1, backtrace[i]);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <execinfo.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
|
@ -33,12 +34,6 @@
|
|||
|
||||
#include "kasan/kasan.h"
|
||||
|
||||
#if UINTPTR_MAX <= UINT32_MAX
|
||||
# define MM_PTR_FMT_WIDTH 11
|
||||
#elif UINTPTR_MAX <= UINT64_MAX
|
||||
# define MM_PTR_FMT_WIDTH 19
|
||||
#endif
|
||||
|
||||
#undef ALIGN_UP
|
||||
#define ALIGN_UP(x, a) (((x) + ((a) - 1)) & (~((a) - 1)))
|
||||
|
||||
|
@ -484,13 +479,13 @@ void mempool_memdump(FAR struct mempool_s *pool,
|
|||
sq_for_every(&pool->queue, entry)
|
||||
{
|
||||
syslog(LOG_INFO, "%12zu%*p\n",
|
||||
blocksize, MM_PTR_FMT_WIDTH, (FAR char *)entry);
|
||||
blocksize, BACKTRACE_PTR_FMT_WIDTH, (FAR char *)entry);
|
||||
}
|
||||
|
||||
sq_for_every(&pool->iqueue, entry)
|
||||
{
|
||||
syslog(LOG_INFO, "%12zu%*p\n",
|
||||
blocksize, MM_PTR_FMT_WIDTH, (FAR char *)entry);
|
||||
blocksize, BACKTRACE_PTR_FMT_WIDTH, (FAR char *)entry);
|
||||
}
|
||||
}
|
||||
#if CONFIG_MM_BACKTRACE >= 0
|
||||
|
@ -506,23 +501,19 @@ void mempool_memdump(FAR struct mempool_s *pool,
|
|||
MM_DUMP_LEAK(dump->pid, buf->pid)) &&
|
||||
buf->seqno >= dump->seqmin && buf->seqno <= dump->seqmax)
|
||||
{
|
||||
char tmp[CONFIG_MM_BACKTRACE * MM_PTR_FMT_WIDTH + 1] = "";
|
||||
|
||||
# if CONFIG_MM_BACKTRACE > 0
|
||||
FAR const char *format = " %0*p";
|
||||
int i;
|
||||
char tmp[BACKTRACE_BUFFER_SIZE(CONFIG_MM_BACKTRACE)];
|
||||
|
||||
for (i = 0; i < CONFIG_MM_BACKTRACE && buf->backtrace[i]; i++)
|
||||
{
|
||||
snprintf(tmp + i * MM_PTR_FMT_WIDTH,
|
||||
sizeof(tmp) - i * MM_PTR_FMT_WIDTH,
|
||||
format, MM_PTR_FMT_WIDTH - 1, buf->backtrace[i]);
|
||||
}
|
||||
backtrace_format(tmp, sizeof(tmp), buf->backtrace,
|
||||
CONFIG_MM_BACKTRACE);
|
||||
# else
|
||||
char *tmp = "";
|
||||
# endif
|
||||
|
||||
syslog(LOG_INFO, "%6d%12zu%12lu%*p%s\n",
|
||||
syslog(LOG_INFO, "%6d%12zu%12lu%*p %s\n",
|
||||
buf->pid, blocksize, buf->seqno,
|
||||
MM_PTR_FMT_WIDTH, ((FAR char *)buf - blocksize), tmp);
|
||||
BACKTRACE_PTR_FMT_WIDTH, ((FAR char *)buf - blocksize),
|
||||
tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <execinfo.h>
|
||||
|
||||
#include <nuttx/mm/mm.h>
|
||||
|
||||
|
@ -36,12 +37,6 @@
|
|||
* 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
|
||||
****************************************************************************/
|
||||
|
@ -62,7 +57,7 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
|
|||
if (dump->pid == PID_MM_ALLOC)
|
||||
{
|
||||
syslog(LOG_INFO, "%12zu%*p\n",
|
||||
nodesize, MM_PTR_FMT_WIDTH,
|
||||
nodesize, BACKTRACE_PTR_FMT_WIDTH,
|
||||
((FAR char *)node + MM_SIZEOF_ALLOCNODE));
|
||||
}
|
||||
#elif CONFIG_MM_BACKTRACE == 0
|
||||
|
@ -73,7 +68,7 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
|
|||
{
|
||||
syslog(LOG_INFO, "%6d%12zu%12lu%*p\n",
|
||||
node->pid, nodesize, node->seqno,
|
||||
MM_PTR_FMT_WIDTH,
|
||||
BACKTRACE_PTR_FMT_WIDTH,
|
||||
((FAR char *)node + MM_SIZEOF_ALLOCNODE));
|
||||
}
|
||||
#else
|
||||
|
@ -82,21 +77,13 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
|
|||
MM_DUMP_LEAK(dump->pid, node->pid)) &&
|
||||
node->seqno >= dump->seqmin && node->seqno <= dump->seqmax)
|
||||
{
|
||||
char buf[CONFIG_MM_BACKTRACE * MM_PTR_FMT_WIDTH + 1] = "";
|
||||
char buf[BACKTRACE_BUFFER_SIZE(CONFIG_MM_BACKTRACE)];
|
||||
backtrace_format(buf, sizeof(buf), node->backtrace,
|
||||
CONFIG_MM_BACKTRACE);
|
||||
|
||||
FAR const char *format = " %0*p";
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_MM_BACKTRACE && node->backtrace[i]; i++)
|
||||
{
|
||||
snprintf(buf + i * MM_PTR_FMT_WIDTH,
|
||||
sizeof(buf) - i * MM_PTR_FMT_WIDTH,
|
||||
format, MM_PTR_FMT_WIDTH - 1, node->backtrace[i]);
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "%6d%12zu%12lu%*p%s\n",
|
||||
syslog(LOG_INFO, "%6d%12zu%12lu%*p %s\n",
|
||||
node->pid, nodesize, node->seqno,
|
||||
MM_PTR_FMT_WIDTH,
|
||||
BACKTRACE_PTR_FMT_WIDTH,
|
||||
((FAR char *)node + MM_SIZEOF_ALLOCNODE), buf);
|
||||
}
|
||||
#endif
|
||||
|
@ -115,7 +102,7 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
|
|||
MM_SIZEOF_NODE(fnode->flink) >= nodesize);
|
||||
|
||||
syslog(LOG_INFO, "%12zu%*p\n",
|
||||
nodesize, MM_PTR_FMT_WIDTH,
|
||||
nodesize, BACKTRACE_PTR_FMT_WIDTH,
|
||||
((FAR char *)node + MM_SIZEOF_ALLOCNODE));
|
||||
}
|
||||
}
|
||||
|
@ -144,16 +131,18 @@ void mm_memdump(FAR struct mm_heap_s *heap,
|
|||
{
|
||||
syslog(LOG_INFO, "Dump all used memory node info:\n");
|
||||
#if CONFIG_MM_BACKTRACE < 0
|
||||
syslog(LOG_INFO, "%12s%*s\n", "Size", MM_PTR_FMT_WIDTH, "Address");
|
||||
syslog(LOG_INFO, "%12s%*s\n", "Size", BACKTRACE_PTR_FMT_WIDTH,
|
||||
"Address");
|
||||
#else
|
||||
syslog(LOG_INFO, "%6s%12s%12s%*s %s\n", "PID", "Size", "Sequence",
|
||||
MM_PTR_FMT_WIDTH, "Address", "Backtrace");
|
||||
BACKTRACE_PTR_FMT_WIDTH, "Address", "Backtrace");
|
||||
#endif
|
||||
}
|
||||
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%*s\n", "Size", BACKTRACE_PTR_FMT_WIDTH,
|
||||
"Address");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MM_HEAP_MEMPOOL
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <execinfo.h>
|
||||
#include <sched.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -47,12 +48,6 @@
|
|||
* 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
|
||||
|
||||
#if CONFIG_MM_HEAP_MEMPOOL_THRESHOLD > 0
|
||||
# define MEMPOOL_NPOOLS (CONFIG_MM_HEAP_MEMPOOL_THRESHOLD / tlsf_align_size())
|
||||
#endif
|
||||
|
@ -444,7 +439,7 @@ static void memdump_handler(FAR void *ptr, size_t size, int used,
|
|||
#if CONFIG_MM_BACKTRACE < 0
|
||||
if (dump->pid == PID_MM_ALLOC)
|
||||
{
|
||||
syslog(LOG_INFO, "%12zu%*p\n", size, MM_PTR_FMT_WIDTH, ptr);
|
||||
syslog(LOG_INFO, "%12zu%*p\n", size, BACKTRACE_PTR_FMT_WIDTH, ptr);
|
||||
}
|
||||
#elif CONFIG_MM_BACKTRACE == 0
|
||||
FAR struct memdump_backtrace_s *buf =
|
||||
|
@ -456,7 +451,7 @@ static void memdump_handler(FAR void *ptr, size_t size, int used,
|
|||
buf->seqno >= dump->seqmin && buf->seqno <= dump->seqmax)
|
||||
{
|
||||
syslog(LOG_INFO, "%6d%12zu%12lu%*p\n",
|
||||
buf->pid, size, buf->seqno, MM_PTR_FMT_WIDTH, ptr);
|
||||
buf->pid, size, buf->seqno, BACKTRACE_PTR_FMT_WIDTH, ptr);
|
||||
}
|
||||
#else
|
||||
FAR struct memdump_backtrace_s *buf =
|
||||
|
@ -467,26 +462,19 @@ static void memdump_handler(FAR void *ptr, size_t size, int used,
|
|||
MM_DUMP_LEAK(dump->pid, buf->pid)) &&
|
||||
buf->seqno >= dump->seqmin && buf->seqno <= dump->seqmax)
|
||||
{
|
||||
char tmp[CONFIG_MM_BACKTRACE * MM_PTR_FMT_WIDTH + 1] = "";
|
||||
char tmp[BACKTRACE_BUFFER_SIZE(CONFIG_MM_BACKTRACE)];
|
||||
backtrace_format(tmp, sizeof(tmp), buf->backtrace,
|
||||
CONFIG_MM_BACKTRACE);
|
||||
|
||||
FAR const char *format = " %0*p";
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_MM_BACKTRACE && buf->backtrace[i]; i++)
|
||||
{
|
||||
snprintf(tmp + i * MM_PTR_FMT_WIDTH,
|
||||
sizeof(tmp) - i * MM_PTR_FMT_WIDTH,
|
||||
format, MM_PTR_FMT_WIDTH - 1, buf->backtrace[i]);
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "%6d%12zu%12lu%*p%s\n",
|
||||
buf->pid, size, buf->seqno, MM_PTR_FMT_WIDTH, ptr, tmp);
|
||||
syslog(LOG_INFO, "%6d%12zu%12lu%*p %s\n",
|
||||
buf->pid, size, buf->seqno, BACKTRACE_PTR_FMT_WIDTH,
|
||||
ptr, tmp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (dump->pid == PID_MM_FREE)
|
||||
{
|
||||
syslog(LOG_INFO, "%12zu%*p\n", size, MM_PTR_FMT_WIDTH, ptr);
|
||||
syslog(LOG_INFO, "%12zu%*p\n", size, BACKTRACE_PTR_FMT_WIDTH, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1074,16 +1062,18 @@ void mm_memdump(FAR struct mm_heap_s *heap,
|
|||
{
|
||||
syslog(LOG_INFO, "Dump all used memory node info:\n");
|
||||
#if CONFIG_MM_BACKTRACE < 0
|
||||
syslog(LOG_INFO, "%12s%*s\n", "Size", MM_PTR_FMT_WIDTH, "Address");
|
||||
syslog(LOG_INFO, "%12s%*s\n", "Size", BACKTRACE_PTR_FMT_WIDTH,
|
||||
"Address");
|
||||
#else
|
||||
syslog(LOG_INFO, "%6s%12s%12s%*s %s\n", "PID", "Size", "Sequence",
|
||||
MM_PTR_FMT_WIDTH, "Address", "Backtrace");
|
||||
BACKTRACE_PTR_FMT_WIDTH, "Address", "Backtrace");
|
||||
#endif
|
||||
}
|
||||
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%*s\n", "Size", BACKTRACE_PTR_FMT_WIDTH,
|
||||
"Address");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MM_HEAP_MEMPOOL
|
||||
|
|
Loading…
Reference in New Issue