动态加载Linux共享库?

11
我想创建一个共享库,可以通过两种不同的方式加载到目标文件中:
  1. 使用LD_PRELOAD
  2. 通过dlsym动态加载
我的共享库如下所示:
#include "stdio.h"

void __attribute__ ((constructor)) my_load(void);

void my_load(void) {
  printf("asdf");
}

void someFunc(void) {
  printf("someFunc called");
}

我这样编译它:

all:
    gcc -fPIC -g -c -Wall MyLib.c
    gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc

我不希望使用ldconfig等方式来安装它。目标进程看起来是这样的:

#include <stdio.h>
#include <dlfcn.h>

void func1() {
  printf("%d\n", 1);
}

void func2() {
  printf("%d\n", 2);
}

void func3() {
  printf("%d\n", 3);
}

int main() {
  void* lib_handle = dlopen("/home/mike/Desktop/TargetProcess/MyLib.so.1.0.1",
                         RTLD_NOW|RTLD_GLOBAL);

  if(lib_handle == NULL) {
    printf("Failed loading lib\n");
  } else {
    printf("Loaded lib successfully\n");

    void (*some_func)() = dlsym(lib_handle, "someFunc");
    printf("%p\n", some_func);

    dlclose(lib_handle);
  }

  func1();
  func2();
  func3();

  return 0;
}

目标文件的编译方式如下:

all:
    gcc TestProg.c -ldl -o TestProg

我的问题是:

  1. 使用上述动态加载方式的 dlopen,为什么似乎没有调用 my_load 函数?
  2. 使用相同的方法,为什么 dlsym 总是返回 nil,即使 dlopen 返回非空值?类似地,nm 不会将 my_loadsomeFunc 列为 .so 文件的符号。
  3. 是否可以使用 LD_PRELOAD 来加载库?我尝试将 .so 文件复制到与目标程序相同的目录中,然后调用 LD_PRELOAD="./MyLib.so.1.0.1" ./TestProg,但是似乎仍未调用 my_load
1个回答

7

您的目标文件未链接到库中:

gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc

将其更改为包括您的目标文件MyLib.o:

gcc  MyLib.o -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc

更新:刚刚在本地尝试了您的命令(没有任何MyLib.c或MyLib.o):

$ gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc && echo ok
ok
$ nm MyLib.so.1.0.1
xxxxxxxx a _DYNAMIC
xxxxxxxx a _GLOBAL_OFFSET_TABLE_
         w _Jv_RegisterClasses
xxxxxxxx A __bss_start
         w __cxa_finalize@@xxxxxxxxxxx
xxxxxxxx d __dso_handle
         w __gmon_start__
xxxxxxxx t __i686.get_pc_thunk.bx
xxxxxxxx A _edata
xxxxxxxx A _end
xxxxxxxx T _fini
xxxxxxxx T _init

这是一个空的动态库。

完美运行。它被LR_PRELOAD和动态加载所期望的方式加载。在这两种情况下都调用了my_load。谢谢! - Mike Kwan
1
实际上它不是空的,它包含一些libc的内容。如果你没有指定-lc,链接将会失败。 :) - ninjalj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接