[PATCH V4] symlookup: improves symbol lookup when a file is specified.

Tedeschi, Walfred walfred.tedeschi@intel.com
Wed Oct 25 09:39:00 GMT 2017


> -----Original Message-----
> From: Pedro Alves [mailto:palves@redhat.com]
> Sent: Monday, October 23, 2017 12:07 PM
> To: Tedeschi, Walfred <walfred.tedeschi@intel.com>; Simon Marchi
> <simon.marchi@ericsson.com>; Simon Marchi <simon.marchi@polymtl.ca>
> Cc: gdb-patches@sourceware.org
> Subject: Re: [PATCH V4] symlookup: improves symbol lookup when a file is
> specified.
> 
> On 10/23/2017 10:03 AM, Tedeschi, Walfred wrote:
> 
> > Here we go:
> >
> > With mainline gdb we have the following scenario:
> >
> > Stopped at main line 32 in print-file-var-main(testcase)
> >
> > 	(gdb) print this_version_id
> > 	$1 = 104
> >
> > This was expected, we are looking at the symbol that the linker and main can
> see as specified in the global scope.
> >
> > 	(gdb) print &this_version_id
> > 	$2 = (int *) 0x7ffff7ddb028 <this_version_id>
> >
> > 	(gdb) info symbol 0x7ffff7ddb028
> > 	this_version_id in section .data of
> > /nfs/iul/disks/iul_team2/wtedesch/_gdb_/extern_gdb/bin/dlopen/gdb/test
> > suite/outputs/gdb.base/print-file-var/print-file-var-lib1.so
> >
> > Those two last evaluations prove that we are seem a symbol coming from the
> first library as expected and done by the linker.
> >
> > However interestingly if I specify the scope, I get:
> >
> > 	(gdb) print  &('print-file-var-lib2.c'::this_version_id)
> > 	$3 = (int *) 0x7ffff7ddb028  <this_version_id>
> >
> > 	(gdb) info symbol 0x7ffff7ddb028
> > 	this_version_id in section .data of
> > /nfs/iul/disks/iul_team2/wtedesch/_gdb_/extern_gdb/bin/dlopen/gdb/test
> > suite/outputs/gdb.base/print-file-var/print-file-var-lib1.so
> >
> > But I have specified the scope! I am asking specifically that I want the symbol
> defined in the second library not in the first.
> 
> In the running process, there is no such thing as two different addresses for
> 'this_version_id'.  The linker arranges for all references to refer to the same
> symbol.  This is symbol interposition at work.  Therefore, it does not make sense
> for print  &('print-file-var-lib2.c'::this_version_id)
> to print any other address because all the code in print-file-var-lib2.c _is_
> referencing the symbol in the first library.
> 
> Try this:
> 
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> From 9cbfd5d4985ab1bbc6a1d4e95fc965db00f807a8 Mon Sep 17 00:00:00 2001
> From: Pedro Alves <palves@redhat.com>
> Date: Mon, 23 Oct 2017 10:37:48 +0100
> Subject: [PATCH] print addresses
> 
> ---
>  gdb/testsuite/gdb.base/print-file-var-lib1.c | 4 ++++
> gdb/testsuite/gdb.base/print-file-var-lib2.c | 3 +++
> gdb/testsuite/gdb.base/print-file-var-main.c | 1 -
>  3 files changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/gdb/testsuite/gdb.base/print-file-var-lib1.c
> b/gdb/testsuite/gdb.base/print-file-var-lib1.c
> index 033f9e4..a284003 100644
> --- a/gdb/testsuite/gdb.base/print-file-var-lib1.c
> +++ b/gdb/testsuite/gdb.base/print-file-var-lib1.c
> @@ -14,10 +14,14 @@
>     You should have received a copy of the GNU General Public License
>     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> 
> +#include <stdio.h>
> +
>  int this_version_id = 104;
> 
>  int
>  get_version_1 (void)
>  {
> +  printf ("get_version_1: &this_version_id=%p, this_version_id=%d\n",
> + &this_version_id, this_version_id);
> +
>    return this_version_id;
>  }
> diff --git a/gdb/testsuite/gdb.base/print-file-var-lib2.c
> b/gdb/testsuite/gdb.base/print-file-var-lib2.c
> index d94a792..2cb210f 100644
> --- a/gdb/testsuite/gdb.base/print-file-var-lib2.c
> +++ b/gdb/testsuite/gdb.base/print-file-var-lib2.c
> @@ -14,10 +14,13 @@
>     You should have received a copy of the GNU General Public License
>     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> 
> +#include <stdio.h>
> +
>  int this_version_id = 203;
> 
>  int
>  get_version_2 (void)
>  {
> +  printf ("get_version_2: &this_version_id=%p, this_version_id=%d\n",
> + &this_version_id, this_version_id);
>    return this_version_id;
>  }
> diff --git a/gdb/testsuite/gdb.base/print-file-var-main.c
> b/gdb/testsuite/gdb.base/print-file-var-main.c
> index a19f6f7..3f4a5dc 100644
> --- a/gdb/testsuite/gdb.base/print-file-var-main.c
> +++ b/gdb/testsuite/gdb.base/print-file-var-main.c
> @@ -31,4 +31,3 @@ main (void)
> 
>    return 0; /* STOP */
>  }
> -
> --
> 2.5.5
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> and you'll see:
> 
>  $ ./testsuite/outputs/gdb.base/print-file-var/print-file-var-main
>  get_version_1: &this_version_id=0x7f2fcc3d2030, this_version_id=104
>  get_version_2: &this_version_id=0x7f2fcc3d2030, this_version_id=104
>                                  ^^^^^^^^^^^^^^                  ^^^
> 
> As you can see, the _same address_ is printed twice.  So it makes sense for GDB
> to do the same thing.
> 
> 
> And if you define the same symbol in the main program, you'll see the linker
> making sure that the version in the main program is used by both libraries.  I.e.,
> try this:
> 
> ~~~
> diff --git c/gdb/testsuite/gdb.base/print-file-var-main.c
> w/gdb/testsuite/gdb.base/print-file-var-main.c
> index 3f4a5dc..60f277a 100644
> --- c/gdb/testsuite/gdb.base/print-file-var-main.c
> +++ w/gdb/testsuite/gdb.base/print-file-var-main.c
> @@ -31,3 +31,5 @@ main (void)
> 
>    return 0; /* STOP */
>  }
> +
> +int this_version_id = 55;
> ~~~
> 
> and now you get:
> 
>  $ ./testsuite/outputs/gdb.base/print-file-var/print-file-var-main
>  get_version_1: &this_version_id=0x60103c, this_version_id=55
>  get_version_2: &this_version_id=0x60103c, this_version_id=55
>                                  ^^^^^^^^                  ^^
> 
> Again, that's symbol interposition for you.
> 
> 
> If you mark the "this_version_id" symbols in the libraries with hidden or
> protected visibility, like:
> 
> lib1:
>  __attribute__((visibility("hidden"))) int this_version_id = 104;
> lib2:
>  __attribute__((visibility("hidden"))) int this_version_id = 203;
> 
> then you'll see that that disables the interposition/overriding:
> 
>  $ ./testsuite/outputs/gdb.base/print-file-var/print-file-var-main
>  get_version_1: &this_version_id=0x7f343c96c030, this_version_id=104
>  get_version_2: &this_version_id=0x7f343c76a030, this_version_id=203
>                                  ^^^^^^^^^^^^^^                  ^^^
> 
> And in the dlopen case, you'll get the same / non-override result.
> 
> So to me, a proper fix for this whole shebang makes GDB follow the same rules
> the linker does (and ideally convert the variants above to testsuite tests).  How
> exactly to make that work, I'm not sure, off hand.  But we do already have some
> logic in place for something like this in
> 
>   solib.c:solib_global_lookup
>     -> ops->lookup_lib_global_symbol
>       -> solib-svr4.c:elf_lookup_lib_symbol.
> 
> Please investigate more into this.
> 
> >
> > If I use the patch provided than I get:
> >
> > 	(gdb) print  &('print-file-var-lib2.c'::this_version_id)
> > 	$4 = (int *) 0x7ffff7ddb028 <this_version_id>
> >
> > 	(gdb) info symbol 0x7ffff7ddb028
> > 	this_version_id in section .data of
> > /nfs/iul/disks/iul_team2/wtedesch/_gdb_/extern_gdb/bin/dlopen/gdb/test
> > suite/outputs/gdb.base/print-file-var/print-file-var-lib1.so
> >
> > _This was what I've expected. _
> 
> I disagree with your expectation.

Pedro and All,

I was considering all of that and sleeping a bit over it.
In summary I see the problem as:
1. For application that do not rely on dlopen GDB is doing the right job.
2. For dlopen applications there is improvement to be made.
3.  dlopen scenario is an exception in terms of usage.
4. User should have more control about the libraries that was dlopened.
5. Considering that from the system side there is no way to distinguish if the shared object was dlopened added with the linker.

Based on this scenario; I was considering in adding a flag in loaded object, so symbol lookup could profit
of the flag and provide right evaluations on both cases.

I do not know how implementation would look like.  By now this is only a proposal to solve the dlopen case.

Thanks and regards,
/Fred
> 
> Thanks,
> Pedro Alves
> 
> >
> > With that I _cannot_ say that GDB is doing right in the main line. Basically the
> test is weak!
> >
> > The issue is in the symtab.c ~2603:
> >      gdbarch_iterate_over_objfiles_in_search_order
> >  	(objfile != NULL ? get_objfile_arch (objfile) : target_gdbarch (),
> >  	 lookup_symbol_global_iterator_cb, &lookup_data, objfile);
> >
> > The lookup here is done in the order of the library load, what is right for global
> symbols, If and only if no scope is provided.
> > Again user will specify the scope if he has a doubt on how in earth his value is
> not what is seen in the execution!
> >
> >
> > I hope this sample run helps in elucidating the problem!
> >
> > Thanks and regards,
> > /Fred
Intel Deutschland GmbH
Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Christin Eisenschmid, Christian Lamprechter
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928



More information about the Gdb-patches mailing list