0

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
#

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.hnext_それ自体は、 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;

または、集団でブログを読むセッションが必要な場合は、ブログ投稿に 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 に答える