From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32739 invoked by alias); 17 Jun 2011 16:11:07 -0000 Received: (qmail 32727 invoked by uid 22791); 17 Jun 2011 16:11:04 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,TW_EG,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 17 Jun 2011 16:10:45 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 839F72BB504; Fri, 17 Jun 2011 12:10:44 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id GocOGAOTr+H1; Fri, 17 Jun 2011 12:10:44 -0400 (EDT) Received: from kwai.gnat.com (kwai.gnat.com [205.232.38.4]) by rock.gnat.com (Postfix) with ESMTP id 7094C2BB4DB; Fri, 17 Jun 2011 12:10:44 -0400 (EDT) Received: by kwai.gnat.com (Postfix, from userid 4233) id 6C3CA946F6; Fri, 17 Jun 2011 12:10:44 -0400 (EDT) From: Joel Brobecker To: gdb-patches@sourceware.org Cc: Joel Brobecker Subject: [RFC/ia64] link against libunwind rather than using dlopen Date: Fri, 17 Jun 2011 16:11:00 -0000 Message-Id: <1308327042-6327-1-git-send-email-brobecker@adacore.com> Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-06/txt/msg00234.txt.bz2 Hello, This is something that I mentioned back in Aug 2005, and which came back to bite me a little. Basically, on ia64 hosts, we dlopen libunwind rather that link GDB against it. This has two consequences: - I cannot link libunwind statically, which is very important in my case; - But also, I was trying to figure out why Steve Elcey, at HP, was having trouble when he's using GDB on ia64-hpux. I thought I had reproduced the problem, and it took 30min of debugging to realize that the libunwind had not been initialized, due to a problem during the dlopen. The real problem is that this failure was completely silent, so there was no way to know without debugging that this had happened. This patch is a first step towards treating libunwind the same way we treat the other libraries such as expat, iconv, etc. What it does is change the configury perform a link check against libunwind. The --with-libunwind option is also extended to allow a path to be given, when libunwind is installed at a non-standard location. There are a few adjustements that are needed after that, mostly: - Some macros no longer exists, but we can use HAVE_LIBUNWIND for that purpose; - We set the various function pointers directly, rather than doing a dlsym. This is not the whole series yet, as I want to make sure that we're still OK with this approach before I waste more time on this. Next on the list is to delete the libunwind_load phase, and use the unw_* symbols directly (so all the function unw_*_p pointers will disappear). gdb/ChangeLog: * configure.ac: Allow the argument of the --with-libunwind option to be the prefix where libunwind is installed. Perform a link check against libunwind, rather than a couple of header file checks. * configure, config.in: Regenerate. * ia64-tdep.c: Replace uses of HAVE_LIBUNWIND_IA64_H by HAVE_LIBUNWIND. * libunwind-frame.h: Replace HAVE_LIBUNWIND_H by HAVE_LIBUNWIND. * libunwind-frame.c: Remove dlfcn.h include. (libunwind_load): Reimplement without using dlopen. What do you guys think? Thanks, -- Joel --- gdb/config.in | 6 --- gdb/configure | 107 ++++++++++++++++++++++++++++++++++--------------- gdb/configure.ac | 49 +++++++++++++++++----- gdb/ia64-tdep.c | 10 ++-- gdb/libunwind-frame.c | 59 +++++---------------------- gdb/libunwind-frame.h | 4 +- 6 files changed, 128 insertions(+), 107 deletions(-) diff --git a/gdb/configure.ac b/gdb/configure.ac index 8c12a44..d2e3792 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -304,20 +304,45 @@ esac # Libunwind support. AC_ARG_WITH(libunwind, -AS_HELP_STRING([--with-libunwind], [use libunwind frame unwinding support]), -[case "${withval}" in - yes) enable_libunwind=yes ;; - no) enable_libunwind=no ;; - *) AC_MSG_ERROR(bad value ${withval} for GDB with-libunwind option) ;; -esac],[ - AC_CHECK_HEADERS(libunwind.h libunwind-ia64.h) - if test x"$ac_cv_header_libunwind_h" = xyes -a x"$ac_cv_header_libunwind_ia64_h" = xyes; then - enable_libunwind=yes; - fi + AS_HELP_STRING([--with-libunwind@<:@=LIBUNWIND@:>@], + [use libunwind frame unwinding support (auto/yes/no/libunwind-path)]), + [], [with_libunwind=auto]) + +AC_DEFUN([AC_CHECK_LIBUNWIND], +[ + save_LIBS=$LIBS + LIBS="$LIBS -lunwind-ia64 -lunwind" + case "$host_os" in + hpux*) # On this platform, libunwind depends on libuca... + LIBS="$LIBS -luca" + ;; + esac + AC_LINK_IFELSE(AC_LANG_PROGRAM([#include "libunwind.h"], + [unw_init_local (0, 0);]), + [enable_libunwind=yes], + [enable_libunwind=no + LIBS=$save_LIBS]) ]) - + +if test "$with_libunwind" = "no"; then + AC_MSG_WARN([libunwind support disabled; some features may be unavailable.]) + enable_libunwind=no +else + case "$with_libunwind" in + auto|yes) AC_CHECK_LIBUNWIND() + ;; + *) # The argument is the prefix where libunwind has been installed. + CPPFLAGS="$CPPFLAGS -I${with_libunwind}/include" + LIBS="$LIBS -L${with_libunwind}/lib" + AC_CHECK_LIBUNWIND() + ;; + esac + if test "$with_libunwind" != "auto" -a "$enable_libunwind" != "yes"; then + AC_MSG_ERROR(libunwind library is missing.) + fi +fi + if test x"$enable_libunwind" = xyes; then - AC_CHECK_HEADERS(libunwind.h libunwind-ia64.h) AC_DEFINE(HAVE_LIBUNWIND, 1, [Define if libunwind library is being used.]) CONFIG_OBS="$CONFIG_OBS libunwind-frame.o" CONFIG_DEPS="$CONFIG_DEPS libunwind-frame.o" diff --git a/gdb/config.in b/gdb/config.in index c1d7c68..7f8d41c 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -236,12 +236,6 @@ /* Define if libunwind library is being used. */ #undef HAVE_LIBUNWIND -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBUNWIND_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBUNWIND_IA64_H - /* Define to 1 if you have the `w' library (-lw). */ #undef HAVE_LIBW diff --git a/gdb/configure b/gdb/configure [snip'ed] diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c index 68e5021..0090e38 100644 --- a/gdb/ia64-tdep.c +++ b/gdb/ia64-tdep.c @@ -41,7 +41,7 @@ #include "ia64-tdep.h" #include "cp-abi.h" -#ifdef HAVE_LIBUNWIND_IA64_H +#ifdef HAVE_LIBUNWIND #include "elf/ia64.h" /* for PT_IA_64_UNWIND value */ #include "libunwind-frame.h" #include "libunwind-ia64.h" @@ -942,7 +942,7 @@ ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, if (regnum >= V32_REGNUM && regnum <= V127_REGNUM) { -#ifdef HAVE_LIBUNWIND_IA64_H +#ifdef HAVE_LIBUNWIND /* First try and use the libunwind special reg accessor, otherwise fallback to standard logic. */ if (!libunwind_is_initialized () @@ -2392,7 +2392,7 @@ static const struct frame_base ia64_frame_base = ia64_frame_base_address }; -#ifdef HAVE_LIBUNWIND_IA64_H +#ifdef HAVE_LIBUNWIND struct ia64_unwind_table_entry { @@ -3189,7 +3189,7 @@ static struct libunwind_descr ia64_libunwind_descr = &ia64_unw_rse_accessors, }; -#endif /* HAVE_LIBUNWIND_IA64_H */ +#endif /* HAVE_LIBUNWIND */ static int ia64_use_struct_convention (struct type *type) @@ -4031,7 +4031,7 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_dummy_id (gdbarch, ia64_dummy_id); set_gdbarch_unwind_pc (gdbarch, ia64_unwind_pc); -#ifdef HAVE_LIBUNWIND_IA64_H +#ifdef HAVE_LIBUNWIND frame_unwind_append_unwinder (gdbarch, &ia64_libunwind_sigtramp_frame_unwind); frame_unwind_append_unwinder (gdbarch, &ia64_libunwind_frame_unwind); diff --git a/gdb/libunwind-frame.c b/gdb/libunwind-frame.c index 677d4c5..eacd4ff 100644 --- a/gdb/libunwind-frame.c +++ b/gdb/libunwind-frame.c @@ -32,8 +32,6 @@ #include "objfiles.h" #include "regcache.h" -#include - #include "gdb_assert.h" #include "gdb_string.h" @@ -505,54 +503,17 @@ libunwind_get_reg_special (struct gdbarch *gdbarch, struct regcache *regcache, static int libunwind_load (void) { - void *handle; - - handle = dlopen (LIBUNWIND_SO, RTLD_NOW); - if (handle == NULL) - return 0; - - /* Initialize pointers to the dynamic library functions we will use. */ - - unw_get_reg_p = dlsym (handle, get_reg_name); - if (unw_get_reg_p == NULL) - return 0; - - unw_get_fpreg_p = dlsym (handle, get_fpreg_name); - if (unw_get_fpreg_p == NULL) - return 0; - - unw_get_saveloc_p = dlsym (handle, get_saveloc_name); - if (unw_get_saveloc_p == NULL) - return 0; - - unw_is_signal_frame_p = dlsym (handle, is_signal_frame_name); - if (unw_is_signal_frame_p == NULL) - return 0; + unw_get_reg_p = UNW_OBJ(get_reg); + unw_get_fpreg_p = UNW_OBJ(get_fpreg); + unw_get_saveloc_p = UNW_OBJ(get_save_loc); + unw_is_signal_frame_p = UNW_OBJ(is_signal_frame); + unw_step_p = UNW_OBJ(step); + unw_init_remote_p = UNW_OBJ(init_remote); + unw_create_addr_space_p = UNW_OBJ(create_addr_space); + unw_destroy_addr_space_p = UNW_OBJ (destroy_addr_space); + unw_search_unwind_table_p = UNW_OBJ(search_unwind_table); + unw_find_dyn_list_p = UNW_OBJ(find_dyn_list); - unw_step_p = dlsym (handle, step_name); - if (unw_step_p == NULL) - return 0; - - unw_init_remote_p = dlsym (handle, init_remote_name); - if (unw_init_remote_p == NULL) - return 0; - - unw_create_addr_space_p = dlsym (handle, create_addr_space_name); - if (unw_create_addr_space_p == NULL) - return 0; - - unw_destroy_addr_space_p = dlsym (handle, destroy_addr_space_name); - if (unw_destroy_addr_space_p == NULL) - return 0; - - unw_search_unwind_table_p = dlsym (handle, search_unwind_table_name); - if (unw_search_unwind_table_p == NULL) - return 0; - - unw_find_dyn_list_p = dlsym (handle, find_dyn_list_name); - if (unw_find_dyn_list_p == NULL) - return 0; - return 1; } diff --git a/gdb/libunwind-frame.h b/gdb/libunwind-frame.h index 9b88f71..b4c3a4c 100644 --- a/gdb/libunwind-frame.h +++ b/gdb/libunwind-frame.h @@ -20,7 +20,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifdef HAVE_LIBUNWIND_H +#ifdef HAVE_LIBUNWIND struct frame_info; struct frame_id; @@ -74,4 +74,4 @@ int libunwind_get_reg_special (struct gdbarch *gdbarch, #endif /* libunwind-frame.h */ -#endif /* HAVE_LIBUNWIND_H */ +#endif /* HAVE_LIBUNWIND */ -- 1.7.0.4