aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenoît Ganne <bganne@cisco.com>2024-10-08 16:43:12 +0200
committerBeno�t Ganne <bganne@cisco.com>2024-11-13 13:02:30 +0000
commit661fb34a90a131658abd726f4faebdc566230cd8 (patch)
tree3b681985edfde1734fb891c49101df77eba9de9f
parent34083c41b2aea74a82775ce4b74f5bfa8c434106 (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.h2
-rw-r--r--src/vppinfra/mem_dlmalloc.c19
-rw-r--r--src/vppinfra/stack.c25
-rw-r--r--src/vppinfra/stack.h1
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) \