[PATCH 4/5] Support backtracing through elfutils (#70746)

Peter Hutterer peter.hutterer at who-t.net
Wed Oct 30 04:35:31 CET 2013


On Tue, Oct 29, 2013 at 10:13:28PM -0400, Jasper St. Pierre wrote:
> 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?

we're getting rid of libunwind, which was merged after 1.14 and isn't
available on e.g. RHEL and apparently not required either. as for
libbacktrace - haven't dealt with it yet, so I can't comment much on it.

schedule - asap, before the 1.15 release would be nice so we don't introduce
a dependency that we don't need.

Cheers,
   Peter

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


More information about the xorg-devel mailing list