mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-13 02:45:35 +00:00
info: Add a 'flags' parametter to gst_debug_get_stack_trace
This is an API break but that API has not been released yet. We are passing a flag rather than a simple boolean as we can imagine to implement more features in the future for example to retrieve a stack trace for all the threads, etc.. Retrieving source file and line numbers is pretty expensive while getting a stack trace, this new argument allows the user to decide to retrieve a backtrace without those infos instead which is much faster. For example running $ GST_LEAKS_TRACER_STACK_TRACE=1 GST_DEBUG=GST_TRACER:7 \ GST_TRACERS=leaks time gst-launch-1.0 videotestsrc num-buffers=1 ! fakesink: * With simple stack traces: 0.04s user 0.02s system 99% cpu 0.060 total * With full stack traces: 0.66s user 0.23s system 96% cpu 0.926 total https://bugzilla.gnome.org/show_bug.cgi?id=775423
This commit is contained in:
parent
6b73bf38d1
commit
33616d47be
4 changed files with 37 additions and 17 deletions
|
@ -1328,6 +1328,7 @@ GST_STR_NULL
|
||||||
GST_DEBUG_PAD_NAME
|
GST_DEBUG_PAD_NAME
|
||||||
GST_FUNCTION
|
GST_FUNCTION
|
||||||
GstLogFunction
|
GstLogFunction
|
||||||
|
GstStackTraceFlags
|
||||||
gst_debug_log
|
gst_debug_log
|
||||||
gst_debug_log_valist
|
gst_debug_log_valist
|
||||||
gst_debug_message_get
|
gst_debug_message_get
|
||||||
|
|
|
@ -2646,7 +2646,7 @@ append_debug_info (GString * trace, Dwfl * dwfl, const void *ip)
|
||||||
#endif /* HAVE_DW */
|
#endif /* HAVE_DW */
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
generate_unwind_trace (void)
|
generate_unwind_trace (GstStackTraceFlags flags)
|
||||||
{
|
{
|
||||||
unw_context_t uc;
|
unw_context_t uc;
|
||||||
unw_cursor_t cursor;
|
unw_cursor_t cursor;
|
||||||
|
@ -2654,14 +2654,14 @@ generate_unwind_trace (void)
|
||||||
GString *trace = g_string_new (NULL);
|
GString *trace = g_string_new (NULL);
|
||||||
|
|
||||||
#ifdef HAVE_DW
|
#ifdef HAVE_DW
|
||||||
Dwfl *dwfl;
|
Dwfl *dwfl = NULL;
|
||||||
|
|
||||||
Dwfl_Callbacks callbacks = {
|
Dwfl_Callbacks callbacks = {
|
||||||
.find_elf = dwfl_linux_proc_find_elf,
|
.find_elf = dwfl_linux_proc_find_elf,
|
||||||
.find_debuginfo = dwfl_standard_find_debuginfo,
|
.find_debuginfo = dwfl_standard_find_debuginfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
dwfl = dwfl_begin (&callbacks);
|
if ((flags & GST_STACK_TRACE_SHOW_FULL))
|
||||||
|
dwfl = dwfl_begin (&callbacks);
|
||||||
#endif /* HAVE_DW */
|
#endif /* HAVE_DW */
|
||||||
|
|
||||||
unw_getcontext (&uc);
|
unw_getcontext (&uc);
|
||||||
|
@ -2691,7 +2691,8 @@ generate_unwind_trace (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DW
|
#ifdef HAVE_DW
|
||||||
dwfl_end (dwfl);
|
if (dwfl)
|
||||||
|
dwfl_end (dwfl);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return g_string_free (trace, FALSE);
|
return g_string_free (trace, FALSE);
|
||||||
|
@ -2725,26 +2726,35 @@ generate_backtrace_trace (void)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_debug_get_stack_trace:
|
* gst_debug_get_stack_trace:
|
||||||
|
* @flags: A set of #GstStackTraceFlags to determine how the stack
|
||||||
|
* trace should look like. Pass 0 to retrieve a minimal backtrace.
|
||||||
*
|
*
|
||||||
* If libunwind or glibc backtrace are present, a stack trace
|
* If libunwind or glibc backtrace are present, a stack trace
|
||||||
* is returned.
|
* is returned.
|
||||||
|
*
|
||||||
|
* Since: 1.12
|
||||||
*/
|
*/
|
||||||
gchar *
|
gchar *
|
||||||
gst_debug_get_stack_trace (void)
|
gst_debug_get_stack_trace (GstStackTraceFlags flags)
|
||||||
{
|
{
|
||||||
gchar *trace = NULL;
|
gchar *trace = NULL;
|
||||||
|
#ifdef HAVE_BACKTRACE
|
||||||
|
gboolean have_backtrace = TRUE;
|
||||||
|
#else
|
||||||
|
gboolean have_backtrace = FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_UNWIND
|
#ifdef HAVE_UNWIND
|
||||||
trace = generate_unwind_trace ();
|
if ((flags & GST_STACK_TRACE_SHOW_FULL) || !have_backtrace)
|
||||||
if (trace)
|
trace = generate_unwind_trace (flags);
|
||||||
return trace;
|
|
||||||
#endif /* HAVE_UNWIND */
|
#endif /* HAVE_UNWIND */
|
||||||
|
|
||||||
#ifdef HAVE_BACKTRACE
|
if (trace)
|
||||||
trace = generate_backtrace_trace ();
|
return trace;
|
||||||
#endif /* HAVE_BACKTRACE */
|
else if (have_backtrace)
|
||||||
|
return generate_backtrace_trace ();
|
||||||
|
|
||||||
return trace;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2756,7 +2766,7 @@ gst_debug_get_stack_trace (void)
|
||||||
void
|
void
|
||||||
gst_debug_print_stack_trace (void)
|
gst_debug_print_stack_trace (void)
|
||||||
{
|
{
|
||||||
gchar *trace = gst_debug_get_stack_trace ();
|
gchar *trace = gst_debug_get_stack_trace (GST_STACK_TRACE_SHOW_FULL);
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
g_print ("%s\n", trace);
|
g_print ("%s\n", trace);
|
||||||
|
|
|
@ -175,6 +175,15 @@ typedef enum {
|
||||||
GST_DEBUG_UNDERLINE = 0x0200
|
GST_DEBUG_UNDERLINE = 0x0200
|
||||||
} GstDebugColorFlags;
|
} GstDebugColorFlags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstStackTraceFlags:
|
||||||
|
* @GST_STACK_TRACE_SHOW_FULL: Try to retrieve as much information as
|
||||||
|
* possible when getting the stack trace
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
GST_STACK_TRACE_SHOW_FULL = 1 << 0
|
||||||
|
} GstStackTraceFlags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstDebugColorMode:
|
* GstDebugColorMode:
|
||||||
* @GST_DEBUG_COLOR_MODE_OFF: Do not use colors in logs.
|
* @GST_DEBUG_COLOR_MODE_OFF: Do not use colors in logs.
|
||||||
|
@ -1570,7 +1579,7 @@ GST_TRACE (const char *format, ...)
|
||||||
|
|
||||||
|
|
||||||
void gst_debug_print_stack_trace (void);
|
void gst_debug_print_stack_trace (void);
|
||||||
gchar * gst_debug_get_stack_trace (void);
|
gchar * gst_debug_get_stack_trace (GstStackTraceFlags flags);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -221,7 +221,7 @@ handle_object_created (GstLeaksTracer * self, gpointer object, GType type,
|
||||||
|
|
||||||
GST_OBJECT_LOCK (self);
|
GST_OBJECT_LOCK (self);
|
||||||
if (self->log_stack_trace) {
|
if (self->log_stack_trace) {
|
||||||
trace = gst_debug_get_stack_trace ();
|
trace = gst_debug_get_stack_trace (GST_STACK_TRACE_SHOW_FULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_insert (self->objects, object, trace);
|
g_hash_table_insert (self->objects, object, trace);
|
||||||
|
@ -264,7 +264,7 @@ gst_leaks_tracer_init (GstLeaksTracer * self)
|
||||||
gchar *trace;
|
gchar *trace;
|
||||||
|
|
||||||
/* Test if we can retrieve backtrace */
|
/* Test if we can retrieve backtrace */
|
||||||
trace = gst_debug_get_stack_trace ();
|
trace = gst_debug_get_stack_trace (GST_STACK_TRACE_SHOW_FULL);
|
||||||
if (trace) {
|
if (trace) {
|
||||||
self->log_stack_trace = TRUE;
|
self->log_stack_trace = TRUE;
|
||||||
g_free (trace);
|
g_free (trace);
|
||||||
|
|
Loading…
Reference in a new issue