如何用C语言覆盖函数(系统调用)?

时间:2012-08-03 14:06:52

标签: c

在许多脚本语言中,我们有一个这样的编程方法:

首先,有一个名为func的函数:

void func()
{
}

其次,我想在客户端调用此函数时记录一些信息,但我不想这样做 修改功能,所以我可以这样做:

void (*pfunc)(void) = func;
void func()
{
    log("Someone call fund");
    pfunc();
}

之后,任何拨打电话的人都会调用我的“覆盖”功能。这在许多脚本语言中都可以。我可以用C语言做同样的事情吗?以及如何编码?

我想使用这个方法在一些3party库中做一些工作,所以我必须做一些影响链接过程的事情,而不仅仅是编译过程。

3 个答案:

答案 0 :(得分:7)

在简单的情况下,您可以用宏编码

#define func()                \
do {                          \
    log("Someone called func"); \
    func();                   \
} while(0)

在宏的扩展中,宏不会递归扩展。

对于更复杂的情况,您实现了一个函数和一个宏。在" .h"你要放的文件:

void func_annotated(void);
#ifdef DEBUG
# define func() func_annotated()
// or if the function takes parameters
// # define func(...) func_annotated(__VA_ARGS__)
#endif

在" .c"提交你的文件

void func_annotated(void)
{
    log("Someone called func");
    (func)();
}

此处额外() arround func可确保始终使用真实函数。

答案 1 :(得分:1)

也许您正在寻找library interposer。您可以在文件中定义自己的函数,并使用该函数而不是系统调用来调用要记录调用的程序。

例如,插入由ls生成的一些系统调用:

$ LD_PRELOAD=/your/own/functions/file.so ls -l

它更适合于无法更​​改程序代码(可能因​​为它不可用)而调用要记录的函数的情况。

答案 2 :(得分:0)

在这种情况下,您不需要使用函数指针。你可以让函数func获取你想要记录的任何参数。与覆盖相同的是,它不需要是函数指针(除非您打算稍后更改覆盖函数的内容)。此外,在这种情况下,它将创建一个无限循环,因为函数指针指向func函数。此外,我甚至不确定在声明函数之前是否允许使用func作为函数指针。

我会尝试这样的事情,这会记录一个整数,但你可以用它来记录你想要的任何东西。

void func(int value)
{
    printf("%d\n", value);
    anotherFunc(value);
}

其中anotherFunc()完全是一个不同的功能。就像我之前说的那样,如果你想改变anotherFunc()调用的函数,那么使用函数指针是有意义的,否则就不需要了。