尝试从here编译包装库的示例
我必须包括stdio.h
和stdlib.h
,并得出该代码:
#define _GNU_SOURCE
#define _USE_GNU
#include <signal.h>
#include <execinfo.h>
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
static void show_stackframe() {
void *trace[16];
char **messages = (char **)NULL;
int i, trace_size = 0;
trace_size = backtrace(trace, 16);
messages = backtrace_symbols(trace, trace_size);
printf("[bt] Execution path:\n");
for (i=0; i < trace_size; ++i)
printf("[bt] %s\n", messages[i]);
}
int ioctl(int fd, int request, void *data)
{
char *msg;
if (next_ioctl == NULL) {
fprintf(stderr, "ioctl : wrapping ioctl\n");
fflush(stderr);
// next_ioctl = dlsym((void *) -11, /* RTLD_NEXT, */ "ioctl");
next_ioctl = dlsym(RTLD_NEXT, "ioctl");
fprintf(stderr, "next_ioctl = %p\n", next_ioctl);
fflush(stderr);
if ((msg = dlerror()) != NULL) {
fprintf(stderr, "ioctl: dlopen failed : %s\n", msg);
fflush(stderr);
exit(1);
} else
fprintf(stderr, "ioctl: wrapping done\n");
fflush(stderr);
}
if (request == 1) { /* SCSI_IOCTL_SEND_COMMAND ? */
/* call back trace */
fprintf(stderr, "SCSI_IOCTL_SEND_COMMAND ioctl\n");
fflush(stderr);
show_stackframe();
}
return next_ioctl(fd, request, data);
}
和Makefile
#
# Makefile
#
all: libs test_ioctl
libs: libwrap_ioctl.so
libwrap_ioctl.so: wrap_ioctl.c
rm -f libwrap_ioctl.so*
gcc -fPIC -shared -Wl,-soname,libwrap_ioctl.so.1 -ldl -o libwrap_ioctl.so.1.0 wrap_ioctl.c
ln -s libwrap_ioctl.so.1.0 libwrap_ioctl.so.1
ln -s libwrap_ioctl.so.1 libwrap_ioctl.so
clean:
rm -f libwrap_ioctl.so* test_ioctl
并且尽管包含了dlfcn.h,但仍停留在这些错误中。
~/my_src/native/glibc_wrapper > make
rm -f libwrap_ioctl.so*
gcc -fPIC -shared -Wl,-soname,libwrap_ioctl.so.1 -ldl -o libwrap_ioctl.so.1.0 wrap_ioctl.c
wrap_ioctl.c: In function ‘ioctl’:
wrap_ioctl.c:26: error: ‘next_ioctl’ undeclared (first use in this function)
wrap_ioctl.c:26: error: (Each undeclared identifier is reported only once
wrap_ioctl.c:26: error: for each function it appears in.)
make: *** [libwrap_ioctl.so] Ошибка 1
最佳答案
dlfcn.h
本身未定义任何名称为next_
smth的符号。 (在SUS中,dlfcn.h仅定义了几个dl*
函数和RTLD_
宏:http://pubs.opengroup.org/onlinepubs/7908799/xsh/dlfcn.h.html)
您应该以显式方式将其定义为程序代码中的函数指针。像这样:(取自https://port70.net/svn/misc/remac/remac.c或https://github.com/itm/forward-sensor/blob/master/preload.c或...任何Google搜索"next_ioctl"
的内容):
static int (*next_ioctl) (int fd, int request, void *data) = NULL;
或者,如果您希望进行集体的博客阅读 session ,那么博客文章中还有一行带有ioctl重载的行:http://scaryreasoner.wordpress.com/2007/11/17/using-ld_preload-libraries-and-glibc-backtrace-function-for-debugging/(在第一个巨大的代码片段之前)
static int (*next_ioctl)(int fd, int request, void *data) = NULL;