[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