views:

118

answers:

7

Hi,

I wanna know if there is any way to know where the function currently in execution was called, this is, in what file and line. I'm using C language, and I'm looking for something similar to _FUNCTION_, _LINE_ or _FILE_ macros.

Best regards, Sérgio

+3  A: 

There's nothing in C itself that would give you this information. You could either trace the information yourself (upon entry/exit) or rely on platform specific APIs to walk the call stack and determine the calling function, but not much more.

Assaf Lavie
A: 

If you need to know it at runtime, I don't think it's possible.

If you need to know it at debugtime, you can place a breakpoint on the function you want, and then, using GDB (using bt command) or Vistual Studio's debugger, inspect the current STACK TRACE.

Pablo Santa Cruz
+2  A: 

__FILE__, __LINE__ etc are preprocessor macros which can easily be expanded to the correct value at compile time. A function may get called from many possible places, so that can't be done via the preprocessor. Finding out the caller's name would be very difficult; it involves walking the stack and matching addresses to symbols.

If you can live with a small hack, this might work (untested):

/* Add a called argument to your function */
void _myFunction(char *caller, int more_args)

/* And define a macro that adds it automagically */
#define myFunction(a) _myFunction(__FUNCTION__, a)
Matti Virkkunen
+9  A: 

Rename your function

void Function(param1)
{
}

to

void Function_debug(param1, char * file, char * func, unsigned long line)
{
}

Then #define a macro like this:

#define Function(param1) Function_debug(param1, __FILE__, __FUNCTION__, __LINE__)
bits
And btw, that means your client code will remain unchanged.
bits
Oh, really a beautiful and easy way to do it.Thank you very muchSérgio
Sérgio
If you really want to thank bits you should click the checkbox to the left of his answer to say its the one that solved your problem.
Willfulwizard
That's what I did, I only didn't click at the time because I need 10 min to accept the answer =)
Sérgio
A: 

This is actually a bit more complicated to do. Your best bet is to get a backtrace on a debugger, or find something similar to pstack for your platform. The manual way would involve traversing the call stack and using debug symbols to translate that to files and lines.

ninjalj
A: 

You can use logs .

#define BEGIN_FUNC(X,Y,Z) printf("Function %s Entered at line %d from file %s",X,Z,Y)
#define END_FUNC(X)  printf("Function %s Exited at line %d from file %s",X,Z,Y)

foo()
{
BEGIN_FUNC(__func__,__FILE__,__LINE__);

//Your code here


END_FUNC(__func___FILE__,__LINE__);

}

OR

Use bt in gdb. I call it backtrace.

Praveen S
+1  A: 

There isn't anything that is supported in all implementations that will do what you want. I have occasionally found myself in the same situation, where I needed to track callers for a few methods and did something like the following:

#ifdef TRACKBACK
int foo(int arg1, int arg2, const char * file, int line)
{
    SEND_TO_LOG("foo", file, line);
#else
int foo(int arg1, int arg2)
{
#endif
    ...
    ...

Of course, it makes for a bit of a headache at the calling end, so you'll want to do something like:

#ifdef TRACKBACK
    #define TRACKING, __FILE__, __LINE__
#else
    #define TRACKING
#endif

Then the call:

foo(arg1, arg2 TRACKING);  //note the lack of the comma

It does the trick when all else fails.