[Ltrace-devel] DWARF prototypes: handling symbol aliases

Thierry Fauck@linux.vnet.ibm.com thierry at linux.vnet.ibm.com
Fri May 16 14:21:44 UTC 2014


Dima,

I tested your case and I got the following result on my ppc64le box, so
I wonder if the problem you mention is not related to some
implementation - let me explain with my 2 cases on ppc64el and ppc64

ppc64 implemented a intermediate translation table ( OPD) when ppc64el
is not any more.

Don't know if that comfort your idea.
Let me know if you need other tests to confirm your point

Regards
Thierry

#----------------------------------------------------------------------------------------------------------------------------------------
On ppc64el
#---------------
ubuntu at fauck2:~/ltrace$ ./ltrace -x '*nanosl*' -e '' ../testdw
nanosleep at libc.so.6({ 0, 33 }, nil)              = 0
+++ exited (status 0) +++

ubuntu at fauck2:~/ltrace$ ./ltrace -l 'libc*' ../testdw
testdw->__libc_start_main([ "XDG_SESSION_ID=8", "TERM=xterm",
"SHELL=/bin/bash", "SSH_CLIENT=172.16.0.1 56603 22"... ] <unfinished ...>
testdw->nanosleep({ 0, 33 }, nil)                = 0
testdw->usleep(44)                               = <void>
+++ exited (status 0) +++


So I tested again on ppc64:
-------------------------------------
ltrace -x '*nanosleep at libc.*' -e '' ./testdw
nanosleep at libc.so.6({ 0, 33 }, nil)              = 0
nanosleep at libc.so.6({ 0, 44000 }, nil)           = 0
+++ exited (status 0) +++

$ ltrace -l 'libc*' ./testdw
testdw->__libc_start_main([ "XDG_SESSION_ID=14303",
"HOSTNAME=deb1.ltc.br.ibm.com", "TERM=xterm", "SHELL=/bin/bash"... ]
<unfinished ...>
testdw->nanosleep({ 0, 33 }, nil)                = 0
testdw->usleep(44)                               = <void>
+++ exited (status 0) +++





On 05/13/2014 12:25 AM, Dima Kogan wrote:
> As noted in the previous thread, there's an issue with parsing the
> prototypes from the DWARF data caused by multiple symbol names referring
> to the same address. A simple example is tracing this simple program
> with ltrace:
>
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <unistd.h>
>  #include <time.h>
>  int main(void)
>  {
>      nanosleep( &(struct timespec){.tv_sec=0,.tv_nsec=33}, NULL);
>      usleep(44);
>      return 0;
>  }
>
> I get this:
>
>  dima at shorty:~/projects/ltrace$ ./ltrace -x '*nanosleep at libc.so*' -e '' /tmp/tst
>
>  nanosleep at libc.so.6(0x7fffd8596b00, 0, 0x7fffd8596c08, 0)        = 0
>  nanosleep at libc.so.6(0x7fffd8596ae0, 0, 0, -1)                    = 0
>  +++ exited (status 0) +++
>
> Note that the nanosleep() calls do not have the correct prototypes. This
> is because we call nanosleep(), but the DWARF defines __nanosleep and
> __GI___nanosleep:
>
>
>  dima at shorty:~/projects/ltrace$ nm -D /tmp/tst | grep nanosleep
>
>                   U nanosleep
>
>
>  dima at shorty:~/projects/ltrace$ nm -D /lib/x86_64-linux-gnu/libc-2.18.so | grep nanosleep
>
>  00000000000f26f0 T __clock_nanosleep
>  00000000000b7070 W __nanosleep
>  00000000000f26f0 W clock_nanosleep
>  00000000000b7070 W nanosleep
>
>
>  dima at shorty:~/projects/ltrace$ readelf -w /usr/lib/debug/lib/x86_64-linux-gnu/libc-2.18.so | grep nanosleep
>
>      <20c7cf>   DW_AT_name        : (indirect string, offset: 0x13a95): __nanosleep
>      <20c7d5>   DW_AT_linkage_name: (indirect string, offset: 0x13a90): __GI___nanosleep
>      <280d67>   DW_AT_name        : (indirect string, offset: 0x13a95): __nanosleep
>      <280d6d>   DW_AT_linkage_name: (indirect string, offset: 0x13a90): __GI___nanosleep
>      <2dc871>   DW_AT_name        : (indirect string, offset: 0x1d940): __clock_nanosleep
>      <3b0b59>   DW_AT_name        : (indirect string, offset: 0x13a95): __nanosleep
>      <3b0b5f>   DW_AT_linkage_name: (indirect string, offset: 0x13a90): __GI___nanosleep
>
>
> We can resolve this discrepancy by noting that the nanosleep symbol in
> the libc symbol table has the same address and __nanosleep, and use
> __nanosleep's DWARF prototype. I implemented this, and the code is
> available in my tree:
>
>  https://github.com/dkogan/ltrace/tree/libsym_aliases
>
> The same ltrace run from before now looks like this:
>
>  dima at shorty:~/projects/ltrace$ ./ltrace -x '*nanosleep at libc.so*' -e '' /tmp/tst
>
>  nanosleep at libc.so.6({ 0, 33 }, nil)                              = 0
>  nanosleep at libc.so.6({ 0, 44000 }, nil)                           = 0
>
>
> So that's good. This doesn't solve the problem completely, however. If
> we invoke ltrace with -l, we still see the problematic behavior:
>
>
>  dima at shorty:~/projects/ltrace$ ./ltrace -l 'libc*' /tmp/tst
>
>  tst->__libc_start_main(0x40054d, 1, '/', 0x400590, 0x400600, 0x7f611a967d50, 0x7fffd468b8b8 <unfinished ...>
>  tst->nanosleep(0x7fffd468b7d0, 0, 0x7fffd468b8d8, 0)             = 0
>  tst->usleep(44)                                                  = 0
>  libc.so.6->__strcasecmp('\001', '\200')                          = 448018048
>  +++ exited (status 0) +++
>
>
> This happens (as I understand it) because the symbols are now read from
> /tmp/tst, not from libc.so. The /tmp/tst symbol table only has
> nanosleep, and not __nanosleep, so we don't see that those are
> equivalent.
>
> I'd like a bit of advice before I try to fix this. The current
> implementation looks for aliased symbols in the same bit of code that
> places the breakpoints. I'm thinking of moving this logic to the
> prototype-generating side, so all the known names of a symbol would have
> a reasonable prototype. This doesn't even need to depend on the DWARF.
> There could simply be a pass that looks for all aliased symbols where
> just one has a known prototype (from a config file or from DWARF), and
> assigns this prototype to the aliased symbols. Does that sound like a
> good approach?
>
> dima
>
> _______________________________________________
> Ltrace-devel mailing list
> Ltrace-devel at lists.alioth.debian.org
> http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/ltrace-devel
>


-- 
Thierry Fauck @ linux.vnet.ibm




More information about the Ltrace-devel mailing list