From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 308 invoked by alias); 24 Dec 2007 17:49:23 -0000 Received: (qmail 32766 invoked by uid 22791); 24 Dec 2007 17:49:22 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 24 Dec 2007 17:49:11 +0000 Received: (qmail 21392 invoked from network); 24 Dec 2007 17:49:08 -0000 Received: from unknown (HELO 172.16.unknown.plus.ru) (vladimir@127.0.0.2) by mail.codesourcery.com with ESMTPA; 24 Dec 2007 17:49:08 -0000 From: Vladimir Prus Date: Wed, 26 Dec 2007 06:00:00 -0000 Subject: [RFA] Handle solaris dynamic linker name change. To: gdb-patches@sources.redhat.com X-TUID: fc88a045fab311af X-Length: 3217 X-UID: 123 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200712242048.33983.vladimir@codesourcery.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: 2007-12/txt/msg00411.txt.bz2 As reported by Joel in http://www.cygwin.com/ml/gdb/2007-03/msg00160.html, on Solaris, the name of dynamic linker as seen by GDB changes midway. As result, GDB concludes that dynamic linker was unloaded. Now, after my breakpoint changes this actually has the effect of breaking pending breakpoints -- because when GDB decides that dynamic linker is unloaded, it disables the bp_shlib_event breakpoint, and it's never enabled back. In past gdb version, when infrun.c handles BPSTAT_WHAT_CHECK_SHLIBS it does: solib_add which calls update_solib_list re_enable_breakpoints_in_shlibs The re_enable_breakpoint_in_shlibs looks at all breakpoints, and enables back those which are in mapped shared libs. In current gdb, the re_enable_breakpoints_in_shlibs code is just not present. And breakpoint_re_set_one explicitly does nothing about bpstat_shlib_event. The solutions are: 1. Stop gdb from thinking dynamic linker was unloaded 2. Revive re_enable_breakpoints_in_shlibs 3. Make breakpoint_re_set one try to re-enable bp_shlib_event I think (1) is best, since it will make (2) or (3) unnecessary. The attached patch does (1) by just special casing the names of libraries. A better approach would be to also make sure address ranges of libraries are the same, but it would require rearranging the code a bit -- quite a bit. OK? - Volodya Ignore change in name of dynamic linker during execution. This also unbreaks pending breakpoints. * solist.h (struct target_so_ops): New field same. * solib-svr4.c (svr4_same): New. (_initialize_svr4_solib): Register svr4_same. * solib.c (update_solib_list): Use ops->same, if available. --- gdb/solib-svr4.c | 21 +++++++++++++++++++++ gdb/solib.c | 12 ++++++++++-- gdb/solist.h | 4 ++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 1d2737a..d227d32 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -1569,6 +1569,26 @@ elf_lookup_lib_symbol (const struct objfile *objfile, (objfile, name, linkage_name, domain, symtab); } +static int +svr4_same (struct so_list *gdb, struct so_list *inferior) +{ + if (! strcmp (gdb->so_original_name, inferior->so_original_name)) + return 1; + + /* On Solaris, when starting inferior we think that + dynamic linker is /usr/lib/ld.so.1, but later on, + the table of loaded shared libraries contains + /lib/ld.so.1. + Sometimes one file is a link to another, but sometimes + they have identical content, but are not linked to each + other. */ + if (strcmp (gdb->so_original_name, "/usr/lib/ld.so.1") == 0 + && strcmp (inferior->so_original_name, "/lib/ld.so.1") == 0) + return 1; + + return 0; +} + extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */ void @@ -1585,4 +1605,5 @@ _initialize_svr4_solib (void) svr4_so_ops.open_symbol_file_object = open_symbol_file_object; svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code; svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol; + svr4_so_ops.same = svr4_same; } diff --git a/gdb/solib.c b/gdb/solib.c index 0ec0a51..d52852a 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -537,8 +537,16 @@ update_solib_list (int from_tty, struct target_ops *target) the inferior's current list. */ while (i) { - if (! strcmp (gdb->so_original_name, i->so_original_name)) - break; + if (ops->same) + { + if (ops->same (gdb, i)) + break; + } + else + { + if (! strcmp (gdb->so_original_name, i->so_original_name)) + break; + } i_link = &i->next; i = *i_link; diff --git a/gdb/solist.h b/gdb/solist.h index 279f1ad..18c547a 100644 --- a/gdb/solist.h +++ b/gdb/solist.h @@ -115,6 +115,10 @@ struct target_so_ops const domain_enum domain, struct symtab **symtab); + /* Given two so_list, first from GDB thread list and another + present in the list returned by current_sos, return 1 if + they are equal -- referring to the same library. */ + int (*same) (struct so_list *gdb, struct so_list *inferior); }; /* Free the memory associated with a (so_list *). */ -- 1.5.3.5