0

试图从这里编译一个包装库的例子

我必须包括stdio.hand 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
4

2 回答 2

1

你错过了申报next_ioctl

只需添加

无效* next_ioctl = NULL;

int (*next_ioctl) (int, int, ...) = NULL; 

main().

于 2013-03-01T08:13:59.353 回答
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.chttps://github.com/itm/forward-sensor/blob/master/preload.c或.. .任何谷歌搜索"next_ioctl"):

static int (*next_ioctl) (int fd, int request, void *data) = NULL;

或者,如果您想要集体阅读博客,请在博客文章中添加 ioctl 重载:http ://scaryreasoner.wordpress.com/2007/11/17/using-ld_preload-libraries-and-glibc- backtrace-function-for-debugging/ (就在第一个巨大的代码片段之前)

然后,声明一个函数指针来保存来自 glibc 的“真实”ioctl() 函数的值:

static int (*next_ioctl)(int fd, int request, void *data) = NULL;

然后声明您的替换 ioctl 函数:

于 2013-03-01T08:14:24.200 回答