views:

89

answers:

2

I have implemented tracing behavior using the -finstrument-functions option of gcc and this (simplified) code:

void __cyg_profile_func_enter(void *this_fn, void *call_site)
{
    Dl_info di;
    if(dladdr(this_fn, &di))
        printf("entered %s\n", (di.dli_sname?di_dli_sname:"<unknown>"));
}

This works great, except for one thing: macros are processed as well, but the function prints the information of the function which contains the macro.

So functions containing macros have their information printed multiple times (which is of course undesired).

Is there anything to detect that a macro is being processed? Or is is possible to turn off instrumenting macros at all?

PS Same problems occur with sizeof()

Edit: To clarify: I am looking for a solution to prevent macros messing with the instrumented functions (which they should not be doing). Not for methods to trace macros, functions and/or other things.

+1  A: 

Macros are expanded inline by the preprocessor, therefore there is no way to distinguish between a function called directly from the code and called from a macro.

The only possible way around this would be to have your macros set a global flag, which your tracing function will check. This is of course less than foolproof, since any calls done by a function called from a macro will also appear the same way.

Hasturkun
But why do I get calls to `__cyg_profile_func_enter` due to macros when they are expanded by the preprocessor?! They should be gone when the application is being compiled, but it looks like they are not gone and behaving as a function...
Veger
@Vegar: could you give an example of one such macro that behaves this way?
Hasturkun
`#define CLEAR_REQ(reqp) memset((reqp), 0, sizeof(struct raw1394_request))` for example.
Veger
+1  A: 

If you really want to dig into it you can see my response to breakdown c++ code size. C++ templates are really just more formal macros, so this may work for you.

It also may not, since LINE and FILE within a macro correspond to the caller.

edit from my comment on this:

$ gcc -E foo.c | gcc -x c-cpp-output -c -finstrument-functions - -o foo.o

preprocess piped into gcc expecting preprocessed input on standard input

nategoose
I am debugging/tracing a existing library which contains these macros and I am confused why they give hits at `__cyg_profile_func_enter`. And why are these hits the same as the function the macros are used in? And what do I need (gcc flag? some detection in the `__cyg_profile_func_enter` function) to prevent them (without modifying the library completely).
Veger
Try separating out the preprocessor and the compile stages of building. Preprocess the source files without the -finstrument-functions flag and then compile the preprocessed files with it. $ gcc -E foo.c | gcc -x c -c -finstrument-functions - -o foo.o
nategoose
I have been trying this, but I do not seem to get this working. The library is being build with libtool and I cannot get the libtool calls modified correctly to separately pre-process the files. But thanks for the idea!
Veger