【问题标题】:Dynamically loading Linux shared libraries?动态加载 Linux 共享库?
【发布时间】:2011-12-01 10:57:40
【问题描述】:

我想创建一个共享库,它可以通过两种不同的方式加载到目标中:

  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返回非null?同样,nm 不会将 my_loadsomeFunc 列为 .so 的符号。
  3. 是否可以使用LD_PRELOAD 加载库?我尝试将 .so 复制到与目标相同的目录中,然后调用 LD_PRELOAD="./MyLib.so.1.0.1" ./TestProg 但似乎又没有调用 my_load

【问题讨论】:

    标签: linux shared


    【解决方案1】:

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

    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 在这两种情况下也会被调用。谢谢!
    • 其实不是空的,里面有一些libc的东西。如果您没有指定-lc,链接将会失败。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多