#ifdef HAVE_DW
#include <elfutils/libdwfl.h>
+static Dwfl *_global_dwfl = NULL;
+static GMutex _dwfl_mutex;
+
+#define GST_DWFL_LOCK() g_mutex_lock(&_dwfl_mutex);
+#define GST_DWFL_UNLOCK() g_mutex_unlock(&_dwfl_mutex);
+
+static Dwfl *
+get_global_dwfl (void)
+{
+ if (g_once_init_enter (&_global_dwfl)) {
+ static Dwfl_Callbacks callbacks = {
+ .find_elf = dwfl_linux_proc_find_elf,
+ .find_debuginfo = dwfl_standard_find_debuginfo,
+ };
+ Dwfl *_dwfl = dwfl_begin (&callbacks);
+ g_mutex_init (&_dwfl_mutex);
+ g_once_init_leave (&_global_dwfl, _dwfl);
+ }
+
+ return _global_dwfl;
+}
+
#endif /* HAVE_DW */
#endif /* HAVE_UNWIND */
Dwfl_Module *module;
const gchar *function_name;
- if (dwfl_linux_proc_report (dwfl, getpid ()) != 0)
- return FALSE;
-
- if (dwfl_report_end (dwfl, NULL, NULL))
- return FALSE;
-
addr = (uintptr_t) ip;
module = dwfl_addrmodule (dwfl, addr);
function_name = dwfl_module_addrname (module, addr);
#ifdef HAVE_DW
Dwfl *dwfl = NULL;
- Dwfl_Callbacks callbacks = {
- .find_elf = dwfl_linux_proc_find_elf,
- .find_debuginfo = dwfl_standard_find_debuginfo,
- };
- if ((flags & GST_STACK_TRACE_SHOW_FULL))
- dwfl = dwfl_begin (&callbacks);
+ if ((flags & GST_STACK_TRACE_SHOW_FULL)) {
+ dwfl = get_global_dwfl ();
+ if (G_UNLIKELY (dwfl == NULL)) {
+ GST_WARNING ("Failed to initialize dwlf");
+ goto done;
+ }
+ GST_DWFL_LOCK ();
+ }
#endif /* HAVE_DW */
unret = unw_getcontext (&uc);
goto done;
}
+#ifdef HAVE_DW
+ /* Due to plugins being loaded, mapping of process might have changed,
+ * so always scan it. */
+ if (dwfl_linux_proc_report (dwfl, getpid ()) != 0)
+ goto done;
+#endif
while (unw_step (&cursor) > 0) {
#ifdef HAVE_DW
done:
#ifdef HAVE_DW
if (dwfl)
- dwfl_end (dwfl);
+ GST_DWFL_UNLOCK ();
#endif
return g_string_free (trace, FALSE);