如何在Linux上重新实现(或包装)系统调用函数?

假设我想完全接pipeopen()系统调用,也许包装实际的系统调用并执行一些日志logging。 一种方法是使用LD_PRELOAD来加载一个(用户自制的)共享对象库,它接pipeopen()入口点。

用户自制的open()例程然后通过dlsym()获取指向glibc函数open()的指针并调用它。

上面提出的解决scheme是一个dynamic解决scheme,但是。 假设我想静态链接自己的open()包装器。 我该怎么做? 我猜这个机制是一样的,但我也猜测在用户定义的open()和libc open()之间会有符号冲突。

请分享其他技术来实现相同的目标。

Solutions Collecting From Web of "如何在Linux上重新实现(或包装)系统调用函数?"

你可以使用ld提供的wrap功能。 从man ld

--wrap symbol使用--wrap symbol的包装函数。 任何未定义的symbol引用将被解析为__wrap_symbol

__real_symbol任何未定义的引用将被解析为symbol

所以当你想调用真正的函数的时候,你只需要使用前缀__wrap_来包装函数和__real_ 。 一个简单的例子是:

malloc_wrapper.c

 #include <stdio.h> void *__real_malloc (size_t); /* This function wraps the real malloc */ void * __wrap_malloc (size_t size) { void *lptr = __real_malloc(size); printf("Malloc: %lu bytes @%p\n", size, lptr); return lptr; } 

测试应用程序testapp.c

 #include <stdio.h> #include <stdlib.h> int main() { free(malloc(1024)); // malloc will resolve to __wrap_malloc return 0; } 

然后编译应用程序:

 gcc -c malloc_wrapper.c gcc -c testapp.c gcc -Wl,-wrap,malloc testapp.o malloc_wrapper.o -o testapp 

结果应用程序的输出将是:

 $ ./testapp Malloc: 1024 bytes @0x20d8010 

链接器按照您在命令行上列出的顺序来解析符号,因此如果您在标准库之前列出了库,那么您将有足够的精度。 对于gcc你需要指定

 gcc <BLAH> -nodefaultlibs <BLAH BLAH> -lYOUR_LIB <OTHER_LIBS> 

这样你的图书馆将首先被搜索和找到。