[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