Get a pointer to the current function in C (gcc)?

2019-01-18 04:52发布

is there a magic variable in gcc holding a pointer to the current function ?

I would like to have a kind of table containing for each function pointer a set of information.

I know there's a __func__ variable containing the name of the current function as a string but not as a function pointer.

This is not to call the function then but just to be used as an index.

EDIT Basically what i would like to do is being able to run nested functions just before the execution of the current function (and also capturing the return to perform some things.) Basically, this is like __cyg_profile_func_enter and __cyg_profile_func_exit (the instrumentation functions)... But the problem is that these instrumentation functions are global and not function-dedicated.

EDIT In the linux kernel, you can use unsigned long kallsyms_lookup_name(const char *name) from include/linux/kallsyms.h ... Note that the CONFIG_KALLSYMS option must be activated.

12条回答
仙女界的扛把子
2楼-- · 2019-01-18 05:21

You can capture this information with setjmp(). Since it saves enough information to return to your current function, it must include that information in the provided jmp_buf.

This structure is highly nonportable, but you mention GCC explicitly so that's probably not a blocking issue. See this GCC/x86 example to get an idea how it roughly works.

查看更多
小情绪 Triste *
3楼-- · 2019-01-18 05:24

static const char * const cookie = __FUNCTION__;

__FUNCTION__ will be stored at the text segment at your binary and a pointer will always be unique and valid.

查看更多
闹够了就滚
4楼-- · 2019-01-18 05:28

If you went for C++ the following information might help you:

Objects are typed, functors are functions wrapped as objects, RTTI allows the identification of type at runtime.

Functors carry a runtime overhead with them, and if this is a problem for you I would suggest hard-coding the knowledge using code-generation or leveraging a OO-heirarchy of functors.

查看更多
淡お忘
5楼-- · 2019-01-18 05:32
void f() {
   void (*fpointer)() = &f;
}
查看更多
放我归山
6楼-- · 2019-01-18 05:34

If you want to do this in a 'generic' way, then you should use the facilities you already mention (__cyg_profile_func*) since that is what they are designed for. Anything else will have to be as ad hoc as your profile.

Honestly, doing things the generic way (with a filter) is probably less error prone than any new method that you will insert on-the-fly.

查看更多
地球回转人心会变
7楼-- · 2019-01-18 05:35

I think you could build your table using strings (the function names) as keys, then look up by comparing with the __func__ builtin variable.

To enforce having a valid function name, you could use a macro that gets the function pointer, does some dummy operation with it (e.g. assigning it to a compatible function type temporary variable) to check that it's indeed a valid function identifier, and then stringifies (with #) the function name before being used as a key.

UPDATE:

What I mean is something like:

typedef struct {
  char[MAX_FUNC_NAME_LENGTH] func_name;
  //rest of the info here
} func_info;

func_info table[N_FUNCS];

#define CHECK_AND_GET_FUNC_NAME(f) ({void (*tmp)(int); tmp = f; #f})

void fill_it()
{
  int i = -1;
  strcpy(table[++i].func_name, CHECK_AND_GET_FUNC_NAME(foo));
  strcpy(table[++i].func_name, CHECK_AND_GET_FUNC_NAME(bar));
  //fill the rest
}

void lookup(char *name) {
  int i = -1;
  while(strcmp(name, table[++i]));
  //now i points to your entry, do whatever you need
}

void foo(int arg) {
  lookup(__func__);
  //do something
}

void bar(int arg) {
  lookup(__func__);
  //do something
}

(the code might need some fixes, I haven't tried to compile it, it's just to illustrate the idea)

查看更多
登录 后发表回答