<div dir="ltr">I'm not a fan at all. This API is really bad compared to what's provided by libbacktrace, which is super simple. This also seem to require callbacks that have "Linux" in the name. Why are we trying to get rid of libbacktrace, and what's the schedule for this?<br>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Oct 29, 2013 at 7:25 PM, Peter Hutterer <span dir="ltr"><<a href="mailto:peter.hutterer@who-t.net" target="_blank">peter.hutterer@who-t.net</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From Jan Kratochvil:<br>
There is a longterm plan to obsolete libunwind from Fedora by new elfutils<br>
unwinder.  But xorg-x11-server does not even need any external (non-glibc)<br>
unwinder.<br>
<br>
According to e21e183059df5975e7086850d1931edb2c1bbd06 you do only<br>
self-backtrace (called local unwinding by libunwind).  glibc backtrace() can<br>
do the same.  According to the sample backtrace in the patch above the<br>
backtrace addresses there are the same in before/after cases, libunwind only<br>
adds resolving of address -> symbol name there, IIUC.<br>
<br>
address -> symbol name resolving can be done with RH-supported elfutils<br>
package.<br>
<br>
X.Org Bug 70746 <<a href="http://bugs.freedesktop.org/show_bug.cgi?id=70746" target="_blank">http://bugs.freedesktop.org/show_bug.cgi?id=70746</a>><br>
<br>
Cc: Marcin Slusarz <<a href="mailto:marcin.slusarz@gmail.com">marcin.slusarz@gmail.com</a>><br>
Cc: Jan Kratochvil <<a href="mailto:jan.kratochvil@redhat.com">jan.kratochvil@redhat.com</a>><br>
Signed-off-by: Peter Hutterer <<a href="mailto:peter.hutterer@who-t.net">peter.hutterer@who-t.net</a>><br>
---<br>
This may need some extra linux checks...<br>
<br>
 <a href="http://configure.ac" target="_blank">configure.ac</a>            | 10 ++++--<br>
 include/<a href="http://dix-config.h.in" target="_blank">dix-config.h.in</a> |  3 ++<br>
 os/backtrace.c          | 91 +++++++++++++++++++++++++++++++++++++++++++++++--<br>
 3 files changed, 99 insertions(+), 5 deletions(-)<br>
<br>
diff --git a/<a href="http://configure.ac" target="_blank">configure.ac</a> b/<a href="http://configure.ac" target="_blank">configure.ac</a><br>
index d36aefc..0e589f8 100644<br>
--- a/<a href="http://configure.ac" target="_blank">configure.ac</a><br>
+++ b/<a href="http://configure.ac" target="_blank">configure.ac</a><br>
@@ -308,6 +308,12 @@ AC_CHECK_HEADER([execinfo.h],[<br>
     ])]<br>
 )<br>
<br>
+dnl elfutils for backtrace symbol lookup<br>
+AC_CHECK_HEADER([elfutils/libdwfl.h],<br>
+                [AC_DEFINE(HAVE_ELFUTILS, 1, [Has elfutils])<br>
+                 ELFUTILS_LIBS="-ldw"])<br>
+AC_SUBST(ELFUTILS_LIBS)<br>
+<br>
 dnl ---------------------------------------------------------------------------<br>
 dnl Bus options and CPU capabilities.  Replaces logic in<br>
 dnl hw/xfree86/os-support/bus/Makefile.am, among others.<br>
@@ -1339,10 +1345,10 @@ AC_DEFINE(BIGREQS, 1, [Support BigRequests extension])<br>
<br>
 if test "x$SPECIAL_DTRACE_OBJECTS" = "xyes" ; then<br>
   DIX_LIB='$(top_builddir)/dix/dix.O'<br>
-  OS_LIB='$(top_builddir)/os/os.O $(SHA1_LIBS) $(DLOPEN_LIBS)'<br>
+  OS_LIB='$(top_builddir)/os/os.O $(SHA1_LIBS) $(DLOPEN_LIBS) $(ELFUTILS_LIBS)'<br>
 else<br>
   DIX_LIB='$(top_builddir)/dix/<a href="http://libdix.la" target="_blank">libdix.la</a>'<br>
-  OS_LIB='$(top_builddir)/os/<a href="http://libos.la" target="_blank">libos.la</a>'<br>
+  OS_LIB='$(top_builddir)/os/<a href="http://libos.la" target="_blank">libos.la</a> $(ELFUTILS_LIBS)'<br>
 fi<br>
 AC_SUBST([DIX_LIB])<br>
 AC_SUBST([OS_LIB])<br>
diff --git a/include/<a href="http://dix-config.h.in" target="_blank">dix-config.h.in</a> b/include/<a href="http://dix-config.h.in" target="_blank">dix-config.h.in</a><br>
index e1cb9eb..c7c0a8a 100644<br>
--- a/include/<a href="http://dix-config.h.in" target="_blank">dix-config.h.in</a><br>
+++ b/include/<a href="http://dix-config.h.in" target="_blank">dix-config.h.in</a><br>
@@ -60,6 +60,9 @@<br>
 /* Has backtrace support */<br>
 #undef HAVE_BACKTRACE<br>
<br>
+/* Has elfutils */<br>
+#undef HAVE_ELFUTILS<br>
+<br>
 /* Define to 1 if you have the <byteswap.h> header file. */<br>
 #undef HAVE_BYTESWAP_H<br>
<br>
diff --git a/os/backtrace.c b/os/backtrace.c<br>
index c807bd2..acf110a 100644<br>
--- a/os/backtrace.c<br>
+++ b/os/backtrace.c<br>
@@ -37,6 +37,89 @@<br>
 #include <dlfcn.h><br>
 #include <execinfo.h><br>
<br>
+#ifdef HAVE_ELFUTILS<br>
+#include <unistd.h><br>
+#include <elfutils/libdwfl.h><br>
+<br>
+static Dwfl*<br>
+dwfl_get(void)<br>
+{<br>
+    static char *debuginfo_path;<br>
+    static Dwfl *dwfl;<br>
+<br>
+    static const Dwfl_Callbacks proc_callbacks = {<br>
+        .find_debuginfo = dwfl_standard_find_debuginfo,<br>
+        .debuginfo_path = &debuginfo_path,<br>
+        .find_elf = dwfl_linux_proc_find_elf,<br>
+   };<br>
+<br>
+    if (dwfl)<br>
+        return dwfl;<br>
+<br>
+    dwfl = dwfl_begin(&proc_callbacks);<br>
+    if (!dwfl)<br>
+        return NULL;<br>
+<br>
+    errno = 0;<br>
+    if (dwfl_linux_proc_report(dwfl, getpid ()) != 0 ||<br>
+        dwfl_report_end(dwfl, NULL, NULL) != 0)<br>
+    {<br>
+        ErrorFSigSafe("dwfl reporting: %s\n", sterror(errno));<br>
+        dwfl_end(dwfl);<br>
+        dwfl = NULL;<br>
+        abort();<br>
+    }<br>
+<br>
+    return dwfl;<br>
+}<br>
+<br>
+struct getmodules_callback_arg {<br>
+    void *addr;<br>
+    const char *name;<br>
+};<br>
+<br>
+static int<br>
+getmodules_callback(Dwfl_Module *module,<br>
+                    void **userdata,<br>
+                    const char *module_name,<br>
+                    Dwarf_Addr module_low_addr, void *arg)<br>
+{<br>
+    struct getmodules_callback_arg *cbarg = arg;<br>
+    cbarg->name = dwfl_module_addrname(module, (GElf_Addr)cbarg->addr);<br>
+    return cbarg->name ? DWARF_CB_ABORT : DWARF_CB_OK;<br>
+}<br>
+<br>
+static const char*<br>
+addr_lookup(void *addr)<br>
+{<br>
+    Dwfl *dwfl = dwfl_get();<br>
+    struct getmodules_callback_arg arg;<br>
+<br>
+    <a href="http://arg.name" target="_blank">arg.name</a> = NULL;<br>
+    arg.addr = addr;<br>
+    dwfl_getmodules(dwfl, getmodules_callback, &arg, 0);<br>
+    return <a href="http://arg.name" target="_blank">arg.name</a>;<br>
+}<br>
+#endif<br>
+<br>
+static const char*<br>
+symbol_name(void *addr, void *fbase)<br>
+{<br>
+    const char *name = NULL;<br>
+<br>
+#ifdef HAVE_ELFUTILS<br>
+    name = addr_lookup(addr);<br>
+#endif<br>
+<br>
+    if (!name) {<br>
+        static char buf[20];<br>
+        sprintf(buf, "%p", fbase);<br>
+        name = buf;<br>
+    }<br>
+<br>
+    return name;<br>
+}<br>
+<br>
 void<br>
 xorg_backtrace(void)<br>
 {<br>
@@ -66,15 +149,17 @@ xorg_backtrace(void)<br>
                 (unsigned int)((char *) array[i] -<br>
                                (char *) info.dli_saddr),<br>
                 array[i]);<br>
-        else<br>
+        else {<br>
+            const char *name = symbol_name(array[i], info.dli_fbase);<br>
             ErrorFSigSafe(<br>
-                "%u: %s (%p+0x%x) [%p]\n",<br>
+                "%u: %s (%s+0x%x) [%p]\n",<br>
                 i,<br>
                 mod,<br>
-                info.dli_fbase,<br>
+                name,<br>
                 (unsigned int)((char *) array[i] -<br>
                                (char *) info.dli_fbase),<br>
                 array[i]);<br>
+        }<br>
     }<br>
     ErrorFSigSafe("\n");<br>
 }<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.3.1<br>
<br>
_______________________________________________<br>
<a href="mailto:xorg-devel@lists.x.org">xorg-devel@lists.x.org</a>: X.Org development<br>
Archives: <a href="http://lists.x.org/archives/xorg-devel" target="_blank">http://lists.x.org/archives/xorg-devel</a><br>
Info: <a href="http://lists.x.org/mailman/listinfo/xorg-devel" target="_blank">http://lists.x.org/mailman/listinfo/xorg-devel</a><br>
</font></span></blockquote></div><br><br clear="all"><br>-- <br>  Jasper<br>
</div>