diff --git a/fs/procfs/fs_procfsproc.c b/fs/procfs/fs_procfsproc.c index 0a7811f578..4284d40008 100644 --- a/fs/procfs/fs_procfsproc.c +++ b/fs/procfs/fs_procfsproc.c @@ -38,6 +38,7 @@ #include #include #include +#include #ifdef CONFIG_SCHED_CRITMONITOR # include diff --git a/include/execinfo.h b/include/execinfo.h index acee5f273a..1092843970 100644 --- a/include/execinfo.h +++ b/include/execinfo.h @@ -27,15 +27,24 @@ #include +#include +#include #include /**************************************************************************** * 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) diff --git a/libs/libc/misc/lib_execinfo.c b/libs/libc/misc/lib_execinfo.c index 422ffad75e..90fb3969d8 100644 --- a/libs/libc/misc/lib_execinfo.c +++ b/libs/libc/misc/lib_execinfo.c @@ -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; +} diff --git a/mm/mempool/mempool.c b/mm/mempool/mempool.c index 46f278e373..aeb501f898 100644 --- a/mm/mempool/mempool.c +++ b/mm/mempool/mempool.c @@ -23,6 +23,7 @@ ****************************************************************************/ #include +#include #include #include #include @@ -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); } } } diff --git a/mm/mm_heap/mm_memdump.c b/mm/mm_heap/mm_memdump.c index 98a083bd68..6c5ff9753d 100644 --- a/mm/mm_heap/mm_memdump.c +++ b/mm/mm_heap/mm_memdump.c @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -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 diff --git a/mm/tlsf/mm_tlsf.c b/mm/tlsf/mm_tlsf.c index 444f9ad839..8e8d74dee9 100644 --- a/mm/tlsf/mm_tlsf.c +++ b/mm/tlsf/mm_tlsf.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -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