From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19499 invoked by alias); 30 Nov 2004 21:37:11 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 19443 invoked from network); 30 Nov 2004 21:37:02 -0000 Received: from unknown (HELO nevyn.them.org) (66.93.172.17) by sourceware.org with SMTP; 30 Nov 2004 21:37:02 -0000 Received: from drow by nevyn.them.org with local (Exim 4.34 #1 (Debian)) id 1CZFg9-00077M-QO; Tue, 30 Nov 2004 16:36:57 -0500 Date: Tue, 30 Nov 2004 21:37:00 -0000 From: Daniel Jacobowitz To: Elena Zannoni Cc: gdb-patches@sources.redhat.com Subject: Re: [RFA/symtab] Handle weak functions as global Message-ID: <20041130213657.GA13028@nevyn.them.org> Mail-Followup-To: Elena Zannoni , gdb-patches@sources.redhat.com References: <20041101173014.GA20449@nevyn.them.org> <16810.33952.467392.147939@localhost.redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <16810.33952.467392.147939@localhost.redhat.com> User-Agent: Mutt/1.5.5.1+cvs20040105i X-SW-Source: 2004-11/txt/msg00538.txt.bz2 On Sun, Nov 28, 2004 at 09:08:32PM -0500, Elena Zannoni wrote: > Interesting. This is just gdb not following in the symbol searches any > of the ELF scoping rules. Can you add a small testcase? I'll have to limit it to GCC - the patch only affects weak symbols. Here's a test case; one unexpected failure without the patch, none with. Two known failures (see below). > If you compile the files with bar() as shared libraries, what version > of bar does gdb pick from main? The right one, with or without the patch - if you link the library contaning file1 first on the command line, it breaks in file1.c, otherwise it breaks in file2.c. I think you could get GDB to give the wrong answer with more complicated tests - for instance using dlopen. Like you said, GDB doesn't know anything about ELF scoping (and I don't think it could know everything about it, either - does the link map expose enough information about search order?). The only way I could get the test to work was by using a weak symbol and building the shared libraries without debug information. This patch only changes the minsym type; with debug information, lookup_minimal_symbol is never called. The original problem came up because "open" is an assembly stub in GDB. This exposed a related problem, which I've filed as gdb/1824. If one has debug and the other doesn't, lookup_symbol will succeed, and we'll always breakpoint the full symbol. Global minimal symbols could be handled before static full symbols, one object at a time. Or, as I suggest in the bug report, we could just breakpoint both copies. I suspect that's more robust and more useful. Testcase look OK? I finally added some shared library utility code to gdb.exp. -- Daniel Jacobowitz 2004-11-30 Daniel Jacobowitz * gdb.base/solib-weak.c, gdb.base/solib-weak.exp, gdb.base/weaklib1.c, gdb.base/weaklib2.c: New files. * lib/gdb.exp (gdb_compile): Handle shlib=. (gdb_compile_shlib): New function. Index: testsuite/gdb.base/solib-weak.c =================================================================== RCS file: testsuite/gdb.base/solib-weak.c diff -N testsuite/gdb.base/solib-weak.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/solib-weak.c 30 Nov 2004 21:22:27 -0000 @@ -0,0 +1,25 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +int +main() +{ + foo (); + return 0; +} Index: testsuite/gdb.base/solib-weak.exp =================================================================== RCS file: testsuite/gdb.base/solib-weak.exp diff -N testsuite/gdb.base/solib-weak.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/solib-weak.exp 30 Nov 2004 21:28:35 -0000 @@ -0,0 +1,109 @@ +# Copyright 2004 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Test setting breakpoints on shared library functions provided by more +# than one shared library, when one of the implementations is a "weak" +# symbol. GDB should set a breakpoint at the first copy it finds. + +# Don't try to run shared library test cases on a remote target for now. +if ![isnative] then { + return 0 +} + +# This test uses GCC-specific syntax. +if [get_compiler_info ${objdir}/${subdir}/solib-weak] { + return -1 +} + +if {$gcc_compiled == 0} { + return 0 +} + +proc do_test { lib1opts lib2opts lib1first } { + global objdir srcdir subdir + + set testopts "" + if {$lib1opts == ""} { + append testopts "lib1 nodebug, " + } else { + append testopts "lib1 debug, " + } + if {$lib2opts == ""} { + append testopts "lib2 nodebug, " + } else { + append testopts "lib2 debug, " + } + if {$lib1first} { + append testopts "lib1 first" + } else { + append testopts "lib2 first" + } + + set testfile "solib-weak" + set srcfile ${testfile}.c + set binfile ${objdir}/${subdir}/${testfile} + + set libfile1 "weaklib1" + set libfile2 "weaklib2" + set lib1src ${srcdir}/${subdir}/${libfile1}.c + set lib2src ${srcdir}/${subdir}/${libfile2}.c + set lib1 ${objdir}/${subdir}/${libfile1}.sl + set lib2 ${objdir}/${subdir}/${libfile2}.sl + + if $lib1first { + set exec_opts [list debug shlib=${lib1} shlib=${lib2}] + set expected_file ${libfile1} + } else { + set exec_opts [list debug shlib=${lib2} shlib=${lib1}] + set expected_file ${libfile2} + } + + if { [gdb_compile_shlib ${lib1src} ${lib1} ${lib1opts}] != "" + || [gdb_compile_shlib ${lib2src} ${lib2} ${lib2opts}] != "" + || [gdb_compile "${srcdir}/${subdir}/${srcfile}" ${binfile} executable $exec_opts] != ""} { + return -1 + } + + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + + runto_main + + gdb_breakpoint "bar" + + # If the library which will be used is compiled without debugging + # information, GDB will pick the wrong copy of "bar", i.e. the one + # with debugging information. + + if {(${lib1opts} == "" && ${lib2opts} != "" && ${lib1first} == 1) + || (${lib1opts} != "" && ${lib2opts} == "" && ${lib1first} == 0)} { + setup_kfail *-*-* gdb/1824 + } + + gdb_test "continue" "Breakpoint .* bar .*${expected_file}\\..*" \ + "run to breakpoint - $testopts" +} + +foreach lib1opts {{} {debug}} { + foreach lib2opts {{} {debug}} { + foreach lib1first {1 0} { + do_test $lib1opts $lib2opts $lib1first + } + } +} Index: testsuite/gdb.base/weaklib1.c =================================================================== RCS file: testsuite/gdb.base/weaklib1.c diff -N testsuite/gdb.base/weaklib1.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/weaklib1.c 30 Nov 2004 21:22:26 -0000 @@ -0,0 +1,24 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +void __attribute__((weak)) +bar (void) +{ + puts ("bar in u1"); +} Index: testsuite/gdb.base/weaklib2.c =================================================================== RCS file: testsuite/gdb.base/weaklib2.c diff -N testsuite/gdb.base/weaklib2.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ testsuite/gdb.base/weaklib2.c 30 Nov 2004 21:22:26 -0000 @@ -0,0 +1,31 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2004 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +void bar (void); +void +foo (void) +{ + bar (); +} + +void +bar (void) +{ + puts ("bar in u2"); +} Index: testsuite/lib/gdb.exp =================================================================== RCS file: /big/fsf/rsync/src-cvs/src/gdb/testsuite/lib/gdb.exp,v retrieving revision 1.58 diff -u -p -r1.58 gdb.exp --- testsuite/lib/gdb.exp 10 Sep 2004 01:04:59 -0000 1.58 +++ testsuite/lib/gdb.exp 30 Nov 2004 21:24:17 -0000 @@ -1324,6 +1324,30 @@ proc gdb_compile {source dest type optio global gdb_wrapper_flags; global gdb_wrapper_initialized; + # Add platform-specific options if a shared library was specified using + # "shlib=librarypath" in OPTIONS. + set new_options "" + set shlib_found 0 + foreach opt $options { + if [regexp {^shlib=(.*)} $opt dummy_var shlib_name] { + lappend source $shlib_name + if {$shlib_found == 0} { + set shlib_found 1 + global gcc_compiled + if { ($gcc_compiled + && ([istarget "powerpc*-*-aix*"] + || [istarget "rs6000*-*-aix*"] )) } { + lappend options "additional_flags=-L${objdir}/${subdir}" + } elseif { [istarget "mips-sgi-irix*"] } { + lappend options "additional_flags=-rpath ${objdir}/${subdir}" + } + } + } else { + lappend new_options $opt + } + } + set options $new_options + if [target_info exists gdb_stub] { set options2 { "additional_flags=-Dusestubs" } lappend options "libs=[target_info gdb_stub]"; @@ -1434,6 +1458,50 @@ proc gdb_compile_objc {source dest type } } +# Build a shared library from SOURCES. You must use get_compiler_info +# first. + +proc gdb_compile_shlib {sources dest options} { + global gcc_compiled + + set obj_options $options + if {$gcc_compiled == 0} { + if [istarget "hppa*-hp-hpux*"] then { + lappend obj_options "additional_flags=+z" + } elseif { [istarget "mips-sgi-irix*"] } { + # Disable SGI compiler's implicit -Dsgi + lappend obj_options "additional_flags=-Usgi" + } else { + # don't know what the compiler is... + } + } else { + if { !([istarget "powerpc*-*-aix*"] + || [istarget "rs6000*-*-aix*"]) } { + lappend obj_options "additional_flags=-fpic" + } + } + + set outdir [file dirname $dest] + set objects "" + foreach source $sources { + set sourcebase [file tail $source] + if {[gdb_compile $source "${outdir}/${sourcebase}.o" object $obj_options] != ""} { + return -1 + } + lappend objects ${outdir}/${sourcebase}.o + } + + if [istarget "hppa*-*-hpux*"] { + remote_exec build "ld -b ${objects} -o ${dest}" + } else { + set link_options options + lappend link_options "additional_flags=-shared" + if {[gdb_compile "${objects}" "${dest}" executable $link_options] != ""} { + return -1 + } + } +} + proc send_gdb { string } { global suppress_flag; if { $suppress_flag } {