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>
This commit is contained in:

committed by
Beno�t Ganne

parent
34083c41b2
commit
661fb34a90
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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) \
|
||||
|
Reference in New Issue
Block a user