From 661fb34a90a131658abd726f4faebdc566230cd8 Mon Sep 17 00:00:00 2001 From: Benoît Ganne Date: Tue, 8 Oct 2024 16:43:12 +0200 Subject: vlib: add clib_stack_frame_get_raw() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit clib_stack_frame_get() is getting the backtrace for all threads and does symbol resolution which is too slow for certain features (eg. memory traces). clib_stack_frame_get_raw() only gets the local backtrace and defer symbol resolution only when displaying results. Type: improvement Change-Id: Ia374d86e9175b6648a39ed5aaa676ceb7235e877 Signed-off-by: Benoît Ganne --- src/vppinfra/mem.h | 2 +- src/vppinfra/mem_dlmalloc.c | 19 +++++-------------- src/vppinfra/stack.c | 25 ++++++++++++++++++++++++- src/vppinfra/stack.h | 1 + 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/vppinfra/mem.h b/src/vppinfra/mem.h index ab9c5da30ec..6211bb51f0a 100644 --- a/src/vppinfra/mem.h +++ b/src/vppinfra/mem.h @@ -302,7 +302,7 @@ void clib_mem_exit (void); typedef struct { /* Address of callers: outer first, inner last. */ - uword callers[12]; + void *callers[12]; /* Count of allocations with this traceback. */ u32 n_allocations; diff --git a/src/vppinfra/mem_dlmalloc.c b/src/vppinfra/mem_dlmalloc.c index d5ff21e58c0..7944240390b 100644 --- a/src/vppinfra/mem_dlmalloc.c +++ b/src/vppinfra/mem_dlmalloc.c @@ -53,7 +53,7 @@ mheap_get_trace_internal (const clib_mem_heap_t *heap, uword offset, mheap_trace_t *t; uword i, trace_index, *p; mheap_trace_t trace = {}; - int index; + int n_callers; if (heap != tm->current_traced_mheap || mheap_trace_thread_disable) return; @@ -67,19 +67,10 @@ mheap_get_trace_internal (const clib_mem_heap_t *heap, uword offset, /* Turn off tracing for this thread to avoid embarrassment... */ mheap_trace_thread_disable = 1; - index = -2; /* skip first 2 stack frames */ - foreach_clib_stack_frame (sf) - { - if (index >= 0) - { - if (index == ARRAY_LEN (trace.callers)) - break; - trace.callers[index] = sf->ip; - } - index++; - } - - if (index < 1) + /* Skip our frame and mspace_get_aligned's frame */ + n_callers = + clib_stack_frame_get_raw (trace.callers, ARRAY_LEN (trace.callers), 2); + if (n_callers == 0) goto out; if (!tm->trace_by_callers) diff --git a/src/vppinfra/stack.c b/src/vppinfra/stack.c index 190e880c228..12b24e3189f 100644 --- a/src/vppinfra/stack.c +++ b/src/vppinfra/stack.c @@ -17,7 +17,30 @@ static __thread unw_cursor_t cursor; static __thread unw_context_t context; -#endif +#endif /* HAVE_LIBUNWIND */ + +__clib_export int +clib_stack_frame_get_raw (void **sf, int n, int skip) +{ +#if HAVE_LIBUNWIND == 1 + void *sf__[20]; + int n__; + + /* Also skip current frame. */ + skip++; + n__ = unw_backtrace (sf__, clib_min (ARRAY_LEN (sf__), n + skip)); + + if (n__ <= skip) + return 0; + else if (n__ - skip < n) + n = n__ - skip; + + clib_memcpy_fast (&sf[0], &sf__[skip], n * sizeof (sf[0])); + return n; +#else /* HAVE_LIBUNWIND */ + return 0; +#endif /* HAVE_LIBUNWIND */ +} __clib_export clib_stack_frame_t * clib_stack_frame_get (clib_stack_frame_t *sf) diff --git a/src/vppinfra/stack.h b/src/vppinfra/stack.h index 98a621d4176..5b833a3811e 100644 --- a/src/vppinfra/stack.h +++ b/src/vppinfra/stack.h @@ -17,6 +17,7 @@ typedef struct u8 is_signal_frame; } clib_stack_frame_t; +int clib_stack_frame_get_raw (void **sf, int n, int skip); clib_stack_frame_t *clib_stack_frame_get (clib_stack_frame_t *); #define foreach_clib_stack_frame(sf) \ -- cgit 1.2.3-korg