tags:

views:

41

answers:

3

Hi,

I would like to trace calls to some 3rd party library which are made from another 3rd party library.

Example: I want to trace calls to library A. My application statically links library B, which in turn is statically linked to library A. So basically what I have is libAB.a

In case of dynamic linking I could write library A2 with wrappers for functions which I want to trace of library A and use LD_PRELOAD=A2.so. Then, my wrappers will be called instead, and I will see the trace. In my case I cannot use dynamic linking.

Is it possible to achieve the same using static linking?

In ideal case I would like to link my application with libAB.a and trace library libA2.a and get the trace.

Thanks,
Robusta

A: 

Depending on how much performance matters you could do it with gdb... (Set a breakpoint on all the functions you care about and log the stack traces... but that involves learning how to script gdb)

There's also things like Oprofile http://oprofile.sourceforge.net/, LTTng http://lttng.org/, and perf (comes with recent kernels in the kernel source it's under tools/perf/ you need to compile it, on Ubuntu I think it's in the linux-tools package)

I can't tell you how to achieve what you want with any of those tools but oprofile and LTTng have lots of documentation and an active user community.

Spudd86
A: 

Well, it seems like a dead lock :)

But I think you may solve it using macros. Although this solution might not be clean and may not work for all situations.

You can try this:

void functionFromLibA();
#define functionFromLibA() trace(); functionFromLibA()
int main()
{
    functionFromLibA();
}

This will be expanded to:

void myfunc();
int main()
{
trace(); functionFromLibA();
}

EDIT: But note that for this solution, all declarations of functions prototypes should be done before defining the macros. Else you will have the prototypes expanded in preprocessing as well.

Yousf
+1  A: 

Okay, I found it :)

man ld

       --wrap symbol
       Use a wrapper function for symbol.  Any undefined reference to symbol will be resolved to "__wrap_symbol".  Any undefined ref‐
       erence to "__real_symbol" will be resolved to symbol.

       This  can  be  used to provide a wrapper for a system function.  The wrapper function should be called "__wrap_symbol".  If it
       wishes to call the system function, it should call "__real_symbol".

       Here is a trivial example:

               void *
               __wrap_malloc (size_t c)
               {
                 printf ("malloc called with %zu\n", c);
                 return __real_malloc (c);
               }

       If you link other code with this file using --wrap malloc, then all calls to "malloc" will call the  function  "__wrap_malloc"
       instead.  The call to "__real_malloc" in "__wrap_malloc" will call the real "malloc" function.