[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.
Is it just me, or has this been fixed? (I'm using "GNU gdb (GDB) 7.4.1-debian".)
I'm pretty sure it has...
(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
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"?
<http://bugs.debian.org/58322> reported the same problem in what Debian called gdb/4.18.19990928-1.
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
See also PR 13800, which has some analysis.
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.
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
*** Bug 13800 has been marked as a duplicate of this bug. ***
*** Bug 15955 has been marked as a duplicate of this bug. ***
I tried this and the bug 13800 test case today, and while I do see copy relocations, gdb seems to do the right thing.
Relevant: https://sourceware.org/ml/gdb-patches/2017-10/msg00710.html
*** Bug 28428 has been marked as a duplicate of this bug. ***