summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Saunier <tsaunier@gnome.org>2016-11-30 15:10:48 -0300
committerThibault Saunier <tsaunier@gnome.org>2016-12-12 15:06:20 -0300
commit33616d47becf743c038d10819e013bf0d0314804 (patch)
tree66c08dd2ed6359bf0834acf279a22925bfd5c30d
parent6b73bf38d1ee2869d94801d6cd601f83d05951de (diff)
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
-rw-r--r--docs/gst/gstreamer-sections.txt1
-rw-r--r--gst/gstinfo.c38
-rw-r--r--gst/gstinfo.h11
-rw-r--r--plugins/tracers/gstleaks.c4
4 files changed, 37 insertions, 17 deletions
diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt
index bccaac598..08534dd74 100644
--- a/docs/gst/gstreamer-sections.txt
+++ b/docs/gst/gstreamer-sections.txt
@@ -1328,6 +1328,7 @@ GST_STR_NULL
GST_DEBUG_PAD_NAME
GST_FUNCTION
GstLogFunction
+GstStackTraceFlags
gst_debug_log
gst_debug_log_valist
gst_debug_message_get
diff --git a/gst/gstinfo.c b/gst/gstinfo.c
index ba389d19b..6fcf3fa5f 100644
--- a/gst/gstinfo.c
+++ b/gst/gstinfo.c
@@ -2646,7 +2646,7 @@ append_debug_info (GString * trace, Dwfl * dwfl, const void *ip)
#endif /* HAVE_DW */
static gchar *
-generate_unwind_trace (void)
+generate_unwind_trace (GstStackTraceFlags flags)
{
unw_context_t uc;
unw_cursor_t cursor;
@@ -2654,14 +2654,14 @@ generate_unwind_trace (void)
GString *trace = g_string_new (NULL);
#ifdef HAVE_DW
- Dwfl *dwfl;
-
+ Dwfl *dwfl = NULL;
Dwfl_Callbacks callbacks = {
.find_elf = dwfl_linux_proc_find_elf,
.find_debuginfo = dwfl_standard_find_debuginfo,
};
- dwfl = dwfl_begin (&callbacks);
+ if ((flags & GST_STACK_TRACE_SHOW_FULL))
+ dwfl = dwfl_begin (&callbacks);
#endif /* HAVE_DW */
unw_getcontext (&uc);
@@ -2691,7 +2691,8 @@ generate_unwind_trace (void)
}
#ifdef HAVE_DW
- dwfl_end (dwfl);
+ if (dwfl)
+ dwfl_end (dwfl);
#endif
return g_string_free (trace, FALSE);
@@ -2725,26 +2726,35 @@ generate_backtrace_trace (void)
/**
* 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
* is returned.
+ *
+ * Since: 1.12
*/
gchar *
-gst_debug_get_stack_trace (void)
+gst_debug_get_stack_trace (GstStackTraceFlags flags)
{
gchar *trace = NULL;
+#ifdef HAVE_BACKTRACE
+ gboolean have_backtrace = TRUE;
+#else
+ gboolean have_backtrace = FALSE;
+#endif
#ifdef HAVE_UNWIND
- trace = generate_unwind_trace ();
- if (trace)
- return trace;
+ if ((flags & GST_STACK_TRACE_SHOW_FULL) || !have_backtrace)
+ trace = generate_unwind_trace (flags);
#endif /* HAVE_UNWIND */
-#ifdef HAVE_BACKTRACE
- trace = generate_backtrace_trace ();
-#endif /* HAVE_BACKTRACE */
+ if (trace)
+ return trace;
+ else if (have_backtrace)
+ return generate_backtrace_trace ();
- return trace;
+ return NULL;
}
/**
@@ -2756,7 +2766,7 @@ gst_debug_get_stack_trace (void)
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)
g_print ("%s\n", trace);
diff --git a/gst/gstinfo.h b/gst/gstinfo.h
index 8d6788586..c08b30561 100644
--- a/gst/gstinfo.h
+++ b/gst/gstinfo.h
@@ -176,6 +176,15 @@ typedef enum {
} 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:
* @GST_DEBUG_COLOR_MODE_OFF: Do not use colors in logs.
* @GST_DEBUG_COLOR_MODE_ON: Paint logs in a platform-specific way.
@@ -1570,7 +1579,7 @@ GST_TRACE (const char *format, ...)
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
diff --git a/plugins/tracers/gstleaks.c b/plugins/tracers/gstleaks.c
index e31031d96..abe7801f3 100644
--- a/plugins/tracers/gstleaks.c
+++ b/plugins/tracers/gstleaks.c
@@ -221,7 +221,7 @@ handle_object_created (GstLeaksTracer * self, gpointer object, GType type,
GST_OBJECT_LOCK (self);
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);
@@ -264,7 +264,7 @@ gst_leaks_tracer_init (GstLeaksTracer * self)
gchar *trace;
/* 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) {
self->log_stack_trace = TRUE;
g_free (trace);