Bug 8588 - symbols present in multiple files are displayed wrongly
Summary: symbols present in multiple files are displayed wrongly
Status: REOPENED
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: 7.4
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 13800 15955 28428 (view as bug list)
Depends on:
Blocks:
 
Reported: 2003-12-12 15:08 UTC by Baurzhan Ismagulov
Modified: 2021-10-18 17:39 UTC (History)
9 users (show)

See Also:
Host: x86_64-linux-gnu
Target: x86_64-linux-gnu
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Baurzhan Ismagulov 2003-12-12 15:08:00 UTC
[Converted from Gnats 1483]

gdb finds the wrong copy of a symbol.

http://sources.redhat.com/ml/gdb/2003-12/msg00160.html

Release:
6.0

How-To-Repeat:
given the following program:

#include <unistd.h>

int main()
{
	printf("%p\n", &optind);
}


I do:

gcc -g a.c
./a.out
nm a.out |grep optind


I see, respectively:

0x80495ac
080495ac B optind@@GLIBC_2.0


After that I do:

gdb a.out
b main
r
p &optind


I see:

$1 = (int *) 0x4014814c,

whereas I expect it to be 080495ac.
Comment 1 Samuel Bronson 2013-01-28 03:26:29 UTC
Is it just me, or has this been fixed?  (I'm using "GNU gdb (GDB) 7.4.1-debian".)
Comment 2 Samuel Bronson 2013-01-29 23:56:07 UTC
I'm pretty sure it has...
Comment 3 John Hughes 2013-01-30 09:08:26 UTC
(In reply to comment #2)
> I'm pretty sure it has...

I'm pretty sure it hasn't.

john@celtic:~$ cat a.c
#include <unistd.h>

int main()
{
	printf("%p\n", &optind);
}
john@celtic:~$ gcc -g a.c
a.c: In function ‘main’:
a.c:5:2: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
john@celtic:~$ gdb a.out 
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/john/a.out...done.
(gdb) b main
Breakpoint 1 at 0x400550: file a.c, line 5.
(gdb) r
Starting program: /home/john/a.out 

Breakpoint 1, main () at a.c:5
5		printf("%p\n", &optind);
(gdb) p &optind
$1 = (int *) 0x7ffff7dd7130
(gdb) c
Continuing.
0x600930
[Inferior 1 (process 25283) exited with code 011]
(gdb) q
john@celtic:~$ nm a.out | grep optind
0000000000600930 B optind@@GLIBC_2.2.5
Comment 4 Samuel Bronson 2013-02-01 21:56:51 UTC
Strange. This is what I get:

naesten@hydrogen:~/hacking/bugs% cat a.c
#include <unistd.h>

int main()
{
        printf("%p\n", &optind);
}
naesten@hydrogen:~/hacking/bugs% gcc -g a.c
a.c: In function ‘main’:
a.c:5:2: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
naesten@hydrogen:~/hacking/bugs% gcc --version
gcc (Debian 4.7.2-5) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

naesten@hydrogen:~/hacking/bugs% ./a.out
0x8049740
naesten@hydrogen:~/hacking/bugs% nm a.out | grep optind
08049740 B optind
naesten@hydrogen:~/hacking/bugs% nm --dynamic a.out | grep optind
08049740 B optind
naesten@hydrogen:~/hacking/bugs% cat a.c
#include <unistd.h>

int main()
{
        printf("%p\n", &optind);
}
naesten@hydrogen:~/hacking/bugs% gcc --version
gcc (Debian 4.7.2-5) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

naesten@hydrogen:~/hacking/bugs% ./a.out
0x8049740
naesten@hydrogen:~/hacking/bugs% nm a.out |grep optind
08049740 B optind
naesten@hydrogen:~/hacking/bugs% gdb a.out
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/naesten/hacking/bugs/a.out...done.
(gdb) b main
Breakpoint 1 at 0x80484d5: file a.c, line 5.
(gdb) r
Starting program: /home/naesten/hacking/bugs/a.out

Breakpoint 1, main () at a.c:5
5               printf("%p\n", &optind);
(gdb) p &optind
$1 = (int *) 0x8049740
(gdb) info variables optind
All variables matching regular expression "optind":

File getopt.c:
int optind;
(gdb)


This leaves me wondering: Is this really architecture-dependent, or is it just due to chance (different addresses, hash collisions, etc.) that it works for me and not for you?

My questions for you are:

1. What version of libc6-dev do you have installed?

2. What do you get for "info variables optind"?
Comment 5 Samuel Bronson 2013-02-01 22:56:25 UTC
<http://bugs.debian.org/58322> reported the same problem in what Debian called gdb/4.18.19990928-1.
Comment 6 John Hughes 2013-02-02 11:27:47 UTC
On 02/01/2013 10:56 PM, naesten at gmail dot com wrote:
> This leaves me wondering: Is this really architecture-dependent, or is it just
> due to chance (different addresses, hash collisions, etc.) that it works for me
> and not for you?

I guess you're on x86?  My machines are amd64

>
> My questions for you are:
>
> 1. What version of libc6-dev do you have installed?

ii  gcc            4:4.7.2-1    amd64        GNU C compiler
ii  gdb            7.4.1-3      amd64        The GNU Debugger
ii  libc6-dev:amd6 2.13-38      amd64        Embedded GNU C Library: Developme

>
> 2. What do you get for "info variables optind"?
>
Not at all the same as you:

    (gdb) info variables optind
    All variables matching regular expression "optind":

    Non-debugging symbols:
    0x0000000000600930  optind@@GLIBC_2.2.5

Interesting - "non-debugging symbols"?   Maybe I should install libc6-dbg?

Well, with libc6-dbg I get different output from info variables:

    All variables matching regular expression "optind":

    File getopt.c:
    int optind;

    Non-debugging symbols:
    0x0000000000600930  optind@@GLIBC_2.2.5

But "p" still doesn't show the version I want:

    (gdb) p &optind
    $1 = (int *) 0x7ffff7dd7130
Comment 7 Tom Tromey 2013-02-04 17:43:00 UTC
See also PR 13800, which has some analysis.
Comment 8 Samuel Bronson 2013-02-04 20:15:32 UTC
Note this diagnosis by Daniel Jacobowitz and Andeas Schwab <http://www.sourceware.org/ml/gdb/2003-12/msg00163.html>:

Baurjan Ismagulov <ibr@ata.cs.hun.edu.tr> writes:

> Hello, Daniel!
>
> That was fast 8) , thanks much!
>
> On Wed, Dec 10, 2003 at 09:49:18AM -0500, Daniel Jacobowitz wrote:
>> The symbol exists in multiple shared objects...
>
> Do you mean weak symbols within libc, or multiple definitions in other
> libraries? ldd shows libc.so.6 and ld-linux.so.2, and nm -D shows that
> optind exists only in libc.

It also exists in the executable, due to a COPY relocation.

Andreas.
Comment 9 Samuel Bronson 2013-02-04 20:18:26 UTC
Note also these possible approaches by Ian Lance Taylor <http://www.sourceware.org/ml/gdb/2003-12/msg00165.html>:

Baurjan Ismagulov <ibr@ata.cs.hun.edu.tr> writes:

> On Wed, Dec 10, 2003 at 05:12:56PM +0100, Andreas Schwab wrote:
> > It also exists in the executable, due to a COPY relocation.
> 
> Thanks much, I see it now!
> 
> And how should gdb know which one to use?

gdb should always use the one in the executable.  That is the one the
code in the shared library will also be using, because that is the
address will be in the GOT.

In principle, while debugging shared library code, gdb could observe
that there is a GOT relocation for optind, and look at the GOT table
in memory to decide which address to use.

Alternatively, gdb could guess that if there is a global variable in
the executable, that any reference to that global variable in the
shared library will refer to the one in the executable.  This will
normally be true, but will fail in cases where the library is
controlling visibility in any of various different ways.

In practice I have no idea what gdb actually does.

Ian
Comment 10 Samuel Bronson 2013-02-04 20:18:47 UTC
*** Bug 13800 has been marked as a duplicate of this bug. ***
Comment 11 Tom Tromey 2013-09-16 15:40:25 UTC
*** Bug 15955 has been marked as a duplicate of this bug. ***
Comment 12 Tom Tromey 2019-06-13 16:29:43 UTC
I tried this and the bug 13800 test case today, and while I
do see copy relocations, gdb seems to do the right thing.
Comment 13 Tom Tromey 2019-06-13 16:30:55 UTC
Relevant: https://sourceware.org/ml/gdb-patches/2017-10/msg00710.html
Comment 14 Peter 2021-10-18 17:39:19 UTC
*** Bug 28428 has been marked as a duplicate of this bug. ***