diff options
author | Benoît Ganne <bganne@cisco.com> | 2024-10-08 16:43:12 +0200 |
---|---|---|
committer | Beno�t Ganne <bganne@cisco.com> | 2024-11-13 13:02:30 +0000 |
commit | 661fb34a90a131658abd726f4faebdc566230cd8 (patch) | |
tree | 3b681985edfde1734fb891c49101df77eba9de9f | |
parent | 34083c41b2aea74a82775ce4b74f5bfa8c434106 (diff) |
vlib: add clib_stack_frame_get_raw()
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 <bganne@cisco.com>
-rw-r--r-- | src/vppinfra/mem.h | 2 | ||||
-rw-r--r-- | src/vppinfra/mem_dlmalloc.c | 19 | ||||
-rw-r--r-- | src/vppinfra/stack.c | 25 | ||||
-rw-r--r-- | 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) \ |