[Ltrace-devel] [PATCH 0/1] Attempt to fix libdl tracing when attaching to PIDs

Petr Machata pmachata at redhat.com
Wed Mar 20 01:25:44 UTC 2013


Joe Damato <ice799 at gmail.com> writes:

> There is something odd happening that I need to investigate a bit
> more. I've noticed when trying to use ltrace to trace symbols loaded
> with dlsym, only -x seems to actually work. I think this is because of
> where and how plt_filter and static_filter are examined in the
> codebase. I tried to re-arrange them and some surrounding code, but I
> ended up breaking existing tests for -e.

This may be obvious, but note that -e really only matches PLT entries,
so you wouldn't see any actual calls from libm (unless they were really
done via PLT slots, like for malloc and free).

> I wrote a test program that dlopen's libm, and then uses dlsym to find
> "acos" and calls the function after a short sleep so I can attach
> ltrace.

[...]

> joe at ubuntu:~/code/ltrace$ /tmp/test/usr/local/bin/ltrace -e* -p 2821
> libm.so.6->(0x7fff07366f90, 0x7fff07366f90, 0, -1)                                                      = 0x7f0384fe06a0
> libdl.so.2->__cxa_finalize(0x7f038582f078, 0, 0xffffffff, 0x7f038582ed50)                               = 0x7f0385627350
> libm.so.6->(0x7f038526c0c0, 0, 0, 3)                                                                    = 0x7f0385627350
> +++ exited (status 0) +++

Suspicious.  This doesn't show up at my machine.  Valgrind is clean as
well.  we used to have a hack in ltrace that produced "anonymous" calls
like this, but that's been gone since before 0.7.

They shouldn't be the acos calls.  dlsym doesn't return a PLT slot
address, it returns the actual symbol, so the calls end up being direct.
I'm seeing the following:

$ ./a.out & ~/proj/ltrace/master/64/ltrace -p $(jobs -p) -e*
[1] 15103
my pid: 15103
libdl.so.2->__cxa_finalize(0x7fb12de47d78, 0, 0xffffffff, 0x7fb12de47d48)                        = 0x7fb12dc3f9d0
libm.so.6->__cxa_finalize(0x7fb12d8a9de0, 0, 0, 3)                                               = 0x7fb12dc3f9d0
+++ exited (status 0) +++

You have two calls from libm, I only have one.  The latter might me "my"
__cxa_finalize, but no clue what the former could be, or why the symbols
are not initialized.  When I trace with -x*@libm*, I get:

acos at libm.so.6(0x7fff59585930, 0x7fff59585930, 0, -1 <unfinished ...>
__ieee754_acos at libm.so.6(0x7fff59585930, 0x7fff59585930, 0, -1)                                  = 0x7f3017209500
isnan at libm.so.6(1059, 1066, 0x3fe00000, 1067)                                                    = 0
<... acos resumed> )                                                                             = 0

Is perhaps your libm somehow calling one of these via a PLT slot?  In my
libm, both calls are direct:

00000000000242d0 <acos>:
[...]
   242dd:       e8 0e 3b fe ff          callq  7df0 <__ieee754_acos>
[...]
   24301:       e8 2a 42 00 00          callq  28530 <__GI___isnan>

Or, isn't your acos an IFUNC symbol?  readelf would tell you.  I'm not
at all sure about the interaction between IFUNC and dlsym, but IFUNC
symbols as such are not supported by ltrace at all.

You might also want to look into symbol name initialization,
i.e. ltrace-elf.c.  Maybe they are mis-loaded to begin with.  That's
where the filters are applied as well: clearly that part of the code
thinks that those symbols are worth tracing, and adds them to symbol
table, otherwise ltrace wouldn't even trace them.  But either it fails
to initialize the names, or they get lost somewhere later.

Thanks,
PM



More information about the Ltrace-devel mailing list