[Ltrace-devel] Getting prototypes from debug information

Dima Kogan lists at dima.secretsauce.net
Fri May 2 06:45:19 UTC 2014


Petr Machata <pmachata at redhat.com> writes:

>> Note that nanosleep didn't get its prototype parsed even though the
>> DWARF is available. It turns out that the exported symbol is indeed
>> called "nanosleep", but the DWARF definitions have a DW_AT_name of
>> "__nanosleep" and a DW_AT_linkage_name "__GI___nanosleep". The DWARF has
>> no mention at all of "nanosleep", which is the main issue. How can we
>> infer a connection between those two?
>
> I think what should work here is to look at DW_AT_low_pc of the
> DW_TAG_subprogram (dwarf_lowpc in libdw seems to be handling this) and
> cross-match it with ELF symbol tables, where each address will have a
> number of alias symbols.  I guess you could just walk through ltrace's
> own data structures, struct library and struct library_symbol, and look
> into ::enter_addr of the latter to figure out what symbol name ltrace
> assigned to this address.

Hmmm. I just looked into this a bit more, and there are more questions
than answers. First off, there are several "__nanosleep" dies in
libc6.so. Our code just uses the first one.

Compile-unit '../nptl/sysdeps/unix/sysv/linux/sleep.c' @ 0x20b13a
<1><20c7ce>: Abbrev Number: 72 (DW_TAG_subprogram)
   <20c7cf>   DW_AT_external    : 1	
   <20c7cf>   DW_AT_name        : (indirect string, offset: 0x13a95): __nanosleep	
   <20c7d3>   DW_AT_decl_file   : 32	
   <20c7d4>   DW_AT_decl_line   : 92	
   <20c7d5>   DW_AT_linkage_name: (indirect string, offset: 0x13a90): __GI___nanosleep	
   <20c7d9>   DW_AT_prototyped  : 1	
   <20c7d9>   DW_AT_type        : <0x20b1b2>	
   <20c7dd>   DW_AT_declaration : 1	
   <20c7dd>   DW_AT_sibling     : <0x20c7ec>	

Compile-unit '../sysdeps/unix/sysv/linux/usleep.c' @ 0x280c56
<1><280d66>: Abbrev Number: 12 (DW_TAG_subprogram)
   <280d67>   DW_AT_external    : 1	
   <280d67>   DW_AT_name        : (indirect string, offset: 0x13a95): __nanosleep	
   <280d6b>   DW_AT_decl_file   : 5	
   <280d6c>   DW_AT_decl_line   : 92	
   <280d6d>   DW_AT_linkage_name: (indirect string, offset: 0x13a90): __GI___nanosleep	
   <280d71>   DW_AT_prototyped  : 1	
   <280d71>   DW_AT_type        : <0x280ca2>	
   <280d75>   DW_AT_declaration : 1	
   <280d75>   DW_AT_sibling     : <0x280d84>	

Compile-unit 'svc.c' @ 0x3ae74c
<1><3b0b58>: Abbrev Number: 83 (DW_TAG_subprogram)
   <3b0b59>   DW_AT_external    : 1	
   <3b0b59>   DW_AT_name        : (indirect string, offset: 0x13a95): __nanosleep	
   <3b0b5d>   DW_AT_decl_file   : 33	
   <3b0b5e>   DW_AT_decl_line   : 92	
   <3b0b5f>   DW_AT_linkage_name: (indirect string, offset: 0x13a90): __GI___nanosleep	
   <3b0b63>   DW_AT_prototyped  : 1	
   <3b0b63>   DW_AT_type        : <0x3ae76e>	
   <3b0b67>   DW_AT_declaration : 1	
   <3b0b67>   DW_AT_sibling     : <0x3b0b76>	

Note that these all lack a DW_AT_low_pc. Yet this works in gdb as
"nanosleep". I have a theory. Look:

$ nm -D /lib/x86_64-linux-gnu/libc-2.18.so | grep -P ' _*(?:GI)?_*nanosleep'

 00000000000b7070 W __nanosleep
 00000000000b7070 W nanosleep

So both of these resolve to the same address, and gdb maybe matches them
up this way. We can too.

And another (related?) issue. I have tst.c:

 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h>
 int main(void)
 {
     __nanosleep( &(struct timespec){.tv_sec=0,.tv_nsec=1000}, NULL);
     return 0;
 }

I build it with 'gcc -std=gnu99 -o /tmp/tst{,.c}'

Here I used "__nanosleep" instead of "nanosleep", so ltrace should pick
it up.... But it doesn't:

$ ./ltrace -x '*sleep at libc.so*' /tmp/tst
 __libc_start_main(0x40051d, 1, 0x7fffe4516b68, 0x400560 <unfinished ...>
 __nanosleep(0x7fffe4516a70, 0, 0x7fffe4516b78, 0 <unfinished ...>
 nanosleep at libc.so.6(0x7fffe4516a70, 0, 0x7fffe4516b78, 0)              = 0
 <... __nanosleep resumed> )                                            = 0
 +++ exited (status 0) +++


If you have any thoughts about these, I'd love to hear about it.
Otherwise, I'll look again in a few days. Sorry about asking lots of
questions, I'm just hoping that somebody has already seen these issues
before.

dima



More information about the Ltrace-devel mailing list