在运行时间中替换动态共享库[英] replace a dynamic shared library in run time

本文是小编为大家收集整理的关于在运行时间中替换动态共享库的处理方法,想解了在运行时间中替换动态共享库的问题怎么解决?在运行时间中替换动态共享库问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我需要在程序的执行周期内使用不同的动态库.看dlfcn.h我认为这是可能的.我承认不阅读有关动态库加载的很多文献.

好,这是我做的 -

  • 我创建了共享库,称为" libdynamictest.so.1"
  • 主应用程序打开此solib( dlopen ),获取函数指针( dlsym ),运行它然后将其关闭( dlclose )

一切都很好,直到这里为止.

  • 现在假设我将我的libdynamictest.so.1替换为另一个libdynamictest.so.1(某些代码差异),我看到了一个分段故障.此外,我还确保在 dlclose dlopen 之前替换了solib.

有人可以解释为什么这种分割错误?

我注意到即使我删除了libdynamictest.so.1该程序仍然执行,安静奇怪.

    SysTrace(("opening dynamic library"));
    handle = dlopen("libdynamicTest.so.1",RTLD_LAZY);
    fn     = dlsym (handle,"dylib_print_msg");
    SysTrace(("Using dynamic library"));
    if(!fn)
    {
        printf("unknown dylib_print_msg..!!\n");
    }
    else
    {
        (*fn)();
    }
    ret = dlclose(handle);
    SysTrace(("closed dynamic library status = [%s]", (ret==0?"OK":"NOK")));

p.s.我不是要修改任何现有程序的行为,也不构成任何威胁.我正在做可行性检查以作为共享库进行集成测试.


编辑

我尝试使用GDB,以下是堆栈跟踪,当发生故障时.

Program received signal SIGSEGV, Segmentation fault.
0x0000003e92408b7b in check_match.8509 () from /lib64/ld-linux-x86-64.so.2
#0  0x0000003e92408b7b in check_match.8509 ()
   from /lib64/ld-linux-x86-64.so.2
#1  0x0000003e92409024 in do_lookup_x () from /lib64/ld-linux-x86-64.so.2
#2  0x0000003e92409222 in _dl_lookup_symbol_x ()
   from /lib64/ld-linux-x86-64.so.2
#3  0x0000003e92908f14 in do_sym () from /lib64/libc.so.6
#4  0x0000003e93001104 in dlsym_doit () from /lib64/libdl.so.2
#5  0x0000003e9240ced6 in _dl_catch_error ()
   from /lib64/ld-linux-x86-64.so.2
#6  0x0000003e9300150d in _dlerror_run () from /lib64/libdl.so.2
#7  0x0000003e930010ba in dlsym () from /lib64/libdl.so.2

编辑

SVN Checkout共享的代码库http://subversion.assembla.com/svn/dynamic_libso


编辑: - 添加日志ld_debug = all

32564:     binding file ./test_agent [0] to /lib64/libc.so.6 [0]: normal symbol `__libc_start_main' [GLIBC_2.2.5]
     32564:
     32564:     initialize program: ./test_agent
     32564:
     32564:
     32564:     transferring control: ./test_agent
     32564:
     32564:     symbol=printf;  lookup in file=./test_agent [0]
     32564:     symbol=printf;  lookup in file=/lib64/libdl.so.2 [0]
     32564:     symbol=printf;  lookup in file=/user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0]
     32564:     symbol=printf;  lookup in file=/lib64/libc.so.6 [0]
     32564:     binding file ./test_agent [0] to /lib64/libc.so.6 [0]: normal symbol `printf' [GLIBC_2.2.5]
     32564:     symbol=putchar;  lookup in file=./test_agent [0]
     32564:     symbol=putchar;  lookup in file=/lib64/libdl.so.2 [0]
     32564:     symbol=putchar;  lookup in file=/user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0]
     32564:     symbol=putchar;  lookup in file=/lib64/libc.so.6 [0]
     32564:     binding file ./test_agent [0] to /lib64/libc.so.6 [0]: normal symbol `putchar' [GLIBC_2.2.5]
-hello.c main():20 Msg : hello world ..!!
-hello.c main():24 Msg : opening dynamic library
     32564:     symbol=dlopen;  lookup in file=./test_agent [0]
     32564:     symbol=dlopen;  lookup in file=/lib64/libdl.so.2 [0]
     32564:     binding file ./test_agent [0] to /lib64/libdl.so.2 [0]: normal symbol `dlopen' [GLIBC_2.2.5]
     32564:     opening file=/user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0]; direct_opencount=1
     32564:
     32564:     symbol=dlerror;  lookup in file=./test_agent [0]
     32564:     symbol=dlerror;  lookup in file=/lib64/libdl.so.2 [0]
     32564:     binding file ./test_agent [0] to /lib64/libdl.so.2 [0]: normal symbol `dlerror' [GLIBC_2.2.5]
-hello.c main():26 Msg : Opened dynamic library handle = [a16d9000]
     32564:     symbol=dlsym;  lookup in file=./test_agent [0]
     32564:     symbol=dlsym;  lookup in file=/lib64/libdl.so.2 [0]
     32564:     binding file ./test_agent [0] to /lib64/libdl.so.2 [0]: normal symbol `dlsym' [GLIBC_2.2.5]
     32564:     symbol=_dl_sym;  lookup in file=./test_agent [0]
     32564:     symbol=_dl_sym;  lookup in file=/lib64/libdl.so.2 [0]
     32564:     symbol=_dl_sym;  lookup in file=/user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0]
     32564:     symbol=_dl_sym;  lookup in file=/lib64/libc.so.6 [0]
     32564:     binding file /lib64/libdl.so.2 [0] to /lib64/libc.so.6 [0]: normal symbol `_dl_sym' [GLIBC_PRIVATE]
     32564:     symbol=solib_print_msg;  lookup in file=/user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0]
     32564:     binding file /user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0] to /user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0]: normal symbol `solib_print_msg'
-hello.c main():28 Msg : Using dynamic library
     32564:     symbol=printf;  lookup in file=./test_agent [0]
     32564:     symbol=printf;  lookup in file=/lib64/libdl.so.2 [0]
     32564:     symbol=printf;  lookup in file=/user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0]
     32564:     symbol=printf;  lookup in file=/lib64/libc.so.6 [0]
     32564:     binding file /user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0] to /lib64/libc.so.6 [0]: normal symbol `printf' [GLIBC_2.2.5]
     32564:     symbol=putchar;  lookup in file=./test_agent [0]
     32564:     symbol=putchar;  lookup in file=/lib64/libdl.so.2 [0]
     32564:     symbol=putchar;  lookup in file=/user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0]
     32564:     symbol=putchar;  lookup in file=/lib64/libc.so.6 [0]
     32564:     binding file /user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0] to /lib64/libc.so.6 [0]: normal symbol `putchar' [GLIBC_2.2.5]
-dynamic.c solib_print_msg():9 Msg : nice nice..!!
     32564:     symbol=dlclose;  lookup in file=./test_agent [0]
     32564:     symbol=dlclose;  lookup in file=/lib64/libdl.so.2 [0]
     32564:     binding file ./test_agent [0] to /lib64/libdl.so.2 [0]: normal symbol `dlclose' [GLIBC_2.2.5]
     32564:
     32564:     closing file=/user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1; direct_opencount=0
-hello.c main():40 Msg : closed dynamic library status = [OK]
-hello.c main():24 Msg : opening dynamic library
     32564:     opening file=/user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0]; direct_opencount=1
     32564:
-hello.c main():26 Msg : Opened dynamic library handle = [0]
     32564:     symbol=solib_print_msg;  lookup in file=/user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0]
     32564:     binding file /user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0] to /user/skm/coding/fTest/approach/dynamic_library/gravity/contribs/libs/libdynamicTest.so.1 [0]: normal symbol `solib_print_msg'
-hello.c main():28 Msg : Using dynamic library
Segmentation fault

推荐答案

来自" Man dlclose":

The function dlclose() decrements the reference count on the dynamic
library handle handle.  If the reference count drops to zero and
no other loaded libraries use symbols in it, then the dynamic library
is unloaded.

我猜想您正在运行"没有其他已加载的库在其中使用符号" part.

进行调试,使用LD_DEBUG=bindings运行您的程序,然后查找诸如:

的消息
binding file <some.so> [0] to libdynamicTest.so.1 [0]: normal symbol `<symbol>'

更新:

您有几个错误:

  1. 您正在链接test_agent与libdynamic.so.1 直接:
    cc -o test_agent -L. ...-ldl build/test_agent/hello.o libdynamic.so.1

    完成此操作后,您将不再期望此库是 ever 卸载.

  2. 这样做:

    *((int *)handle) = 0;

    您实际上正在损坏动态装载机的状态, 会导致后续dlsym给您伪造地址,这在您尝试使用时会导致您的SIGSEGV. >

解决问题2后,您的程序将不再崩溃,尽管它仍然不会卸载库. 实际上让库卸载,您还需要解决问题#1.

如果首先解决了问题#1,则问题#2将不再损坏动态加载程序.它会损坏堆,您可以用Valgrind琐碎地观察到.

其他推荐答案

根据man 8 ld.so:

BUGS
       Currently ld.so has no means of unloading and searching for com‐
       patible or newer version of libraries.

我不是100%确定这是相关的,但听起来可能是.

本文地址:https://www.itbaoku.cn/post/358978.html