Looks Good. Ethan
On Fri, May 13, 2011 at 13:07, Ben Pfaff <[email protected]> wrote: > The backtrace_capture() implementation only worked properly with GNU C on > systems that have a simple stack frame with a frame pointer. Notably, > the x86-64 ABI by default has no frame pointer, so this failed on x86-64. > > However, glibc has a function named backtrace() that does what we want. > This commit tests for this function and uses it when it is present, fixing > x86-64 backtraces. > --- > configure.ac | 1 + > lib/backtrace.c | 30 +++++++++++++++++++++++++----- > m4/openvswitch.m4 | 5 +++++ > 3 files changed, 31 insertions(+), 5 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 5b5f47e..fe91242 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -61,6 +61,7 @@ AC_CHECK_HEADERS([mntent.h sys/statvfs.h]) > > OVS_CHECK_PKIDIR > OVS_CHECK_RUNDIR > +OVS_CHECK_BACKTRACE > OVS_CHECK_MALLOC_HOOKS > OVS_CHECK_VALGRIND > OVS_CHECK_SOCKET_LIBS > diff --git a/lib/backtrace.c b/lib/backtrace.c > index 91549db..1c0dfd6 100644 > --- a/lib/backtrace.c > +++ b/lib/backtrace.c > @@ -1,5 +1,5 @@ > /* > - * Copyright (c) 2008, 2009, 2010 Nicira Networks. > + * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks. > * > * Licensed under the Apache License, Version 2.0 (the "License"); > * you may not use this file except in compliance with the License. > @@ -15,17 +15,34 @@ > */ > > #include <config.h> > + > #include "backtrace.h" > + > #include <errno.h> > #include <inttypes.h> > #include <stdbool.h> > #include <stdio.h> > + > #include "compiler.h" > #include "vlog.h" > > VLOG_DEFINE_THIS_MODULE(backtrace); > > -static uintptr_t OVS_UNUSED > +#ifdef HAVE_BACKTRACE > +#include <execinfo.h> > +void > +backtrace_capture(struct backtrace *b) > +{ > + void *frames[BACKTRACE_MAX_FRAMES]; > + int i; > + > + b->n_frames = backtrace(frames, BACKTRACE_MAX_FRAMES); > + for (i = 0; i < b->n_frames; i++) { > + b->frames[i] = (uintptr_t) frames[i]; > + } > +} > +#elif __GNUC__ > +static uintptr_t > get_max_stack(void) > { > static const char file_name[] = "/proc/self/maps"; > @@ -83,7 +100,6 @@ in_stack(void *p) > void > backtrace_capture(struct backtrace *backtrace) > { > -#ifdef __GNUC__ > void **frame; > size_t n; > > @@ -96,7 +112,11 @@ backtrace_capture(struct backtrace *backtrace) > backtrace->frames[n++] = (uintptr_t) frame[1]; > } > backtrace->n_frames = n; > -#else > +} > +#else /* !HAVE_BACKTRACE && !__GNUC__ */ > +void > +backtrace_capture(struct backtrace *backtrace) > +{ > backtrace->n_frames = 0; > -#endif > } > +#endif > diff --git a/m4/openvswitch.m4 b/m4/openvswitch.m4 > index e6d03a6..73db4bb 100644 > --- a/m4/openvswitch.m4 > +++ b/m4/openvswitch.m4 > @@ -152,6 +152,11 @@ AC_DEFUN([OVS_CHECK_LOGDIR], > [LOGDIR='${localstatedir}/log/${PACKAGE}']) > AC_SUBST([LOGDIR])]) > > +dnl Defines HAVE_BACKTRACE if backtrace() is declared in <execinfo.h> > +dnl and exists in libc. > +AC_DEFUN([OVS_CHECK_BACKTRACE], > + [AC_CHECK_HEADER([execinfo.h], [AC_CHECK_FUNCS([backtrace])])]) > + > dnl Checks for __malloc_hook, etc., supported by glibc. > AC_DEFUN([OVS_CHECK_MALLOC_HOOKS], > [AC_CACHE_CHECK( > -- > 1.7.4.4 > > _______________________________________________ > dev mailing list > [email protected] > http://openvswitch.org/mailman/listinfo/dev > _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
