Description of problem: The fedora 12 x86_64 gdb experience: # gdb ./fact GNU gdb (GDB) Fedora (7.0-3.fc12) ...yadda, yadda, yadda... (gdb) b main Breakpoint 1 at 0x400593: file fact.c, line 19. (gdb) r 7 Starting program: fact 7 Breakpoint 1, main (argc=2, argv=0x7fffffffe708) at fact.c:19 19 for (i = 1; i < argc; ++i) { (gdb) p strlen("xyzzy") $1 = -509088576 (gdb) I'm pretty sure the string "xyzzy" is not -509,088,576 bytes long :-). The fedora 11 x86_64 gdb experience: zooty> gdb ./fact GNU gdb (GDB) Fedora (6.8.50.20090302-39.fc11) ...yadda, yadda, yadda... (gdb) b main Breakpoint 1 at 0x400593: file fact.c, line 19. (gdb) r 7 Starting program: fact 7 Breakpoint 1, main (argc=2, argv=0x7fffffffe2b8) at fact.c:19 19 for (i = 1; i < argc; ++i) { (gdb) p strlen("xyzzy") $1 = 5 (gdb) I was right! It is actually 5 bytes long. P.S. The program "fact" is unimportant, any old hello world sort of app dynamically linked with libc will do. Version-Release number of selected component (if applicable): gdb-7.0-3.fc12.x86_64 glibc-2.11-2.x86_64 How reproducible: Oh, it is gonna happen every time, for strlen and several other similar functions (strcpy, etc). Steps to Reproduce: 1.see above 2. 3. Actual results: ridiculous nonsense Expected results: actual length of string Additional info: I know exactly what is happening here, but why should I spare the gdb maintainers the thrill of the discovery of the true horror the latest glibc "improvements" have foisted on long suffering debugger maintainers? :-).
This might be cross-pollination of a cause involving conditional breakpoints involving an inferior function call smashing the breakpoint struct. I've been looking a little at this today, and the value returned from inferior function call is bogus. https://bugzilla.redhat.com/show_bug.cgi?id=538626 If you have a theory the the cause, please by all means expound on it! It's all good ;)
Nope, this has nothing to do with conditional breakpoints. If you do an 'nm' on libc.so, you will see the functions that gdb cannot call have an 'i' printed in front of the symbol. If you disassemble the code at &strlen, you find no code that could possibly take an argument and return a string length. If you follow these clues around for several hours of google searching, you will find the STT_GNU_IFUNC symbol type and the assembler directive .type @gnu_indirect_function in various patches applied to the glibc code. In those patches, you will also find that glibc now has 47,621 different versions of strlen, each optimized for a different architecture variation, because, after all, it is vital to provide a 1 nanosecond speed improvement in routines that typical programs spend 0.001% of their time in at the cost of complicating the maintenance of glibc and debuggers by a factor of at least 100. Anyway, it seems like the dynamic linker checks for these indirect function entries when it is looking up symbols to resolve .plt entries, and when it finds one, rather than stashing the symbol value as the address of the function, it *calls* the funtion, which returns a pointer to the best version of of the 47,621 alternate strlens to use on the current architecture. So the symbol named "strlen" is indeed a function, but it is a function of no arguments which returns a pointer to another function (the one you really want). God help us all when the security boys get wind of this dynamic linker feature - then they can randomly pick different implementations of all the glibc functions at runtime :-).
Created attachment 373246 [details] ifunc implementation #1.
gdb-7.0-7.fc12 has been submitted as an update for Fedora 12. http://admin.fedoraproject.org/updates/gdb-7.0-7.fc12
gdb-7.0-7.fc12 has been pushed to the Fedora 12 stable repository. If problems still persist, please make note of it in this bug report.
gdb-7.0.1-28.fc12 has been submitted as an update for Fedora 12. http://admin.fedoraproject.org/updates/gdb-7.0.1-28.fc12
gdb-7.0.1-49.fc12 has been submitted as an update for Fedora 12. http://admin.fedoraproject.org/updates/gdb-7.0.1-49.fc12