14

プログラムの実行サイクル全体で異なるダイナミックライブラリを使用する必要があります。見て、dlfcn.hこれは可能だと思いました。ダイナミックライブラリのロードに関する多くの文献を読んでいないことを告白します。

OKここが私がすることです-

  • `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")));

PS私は、既存のプログラムの動作を変更したり、脅威を与えたりするつもりはありません。共有ライブラリとして統合テストを実行するために、実現可能性チェックを行っていました。


編集

障害が発生したときのスタックトレースは次のとおりです。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チェックアウトで共有されるコードベース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
4

2 に答える 2

10

「mandlclose」から:

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.

「ロードされた他のライブラリはシンボルを使用していません」という部分に反していると思います。

デバッグするには、でプログラムを実行し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

    これを実行すると、このライブラリがアンロードされることは期待できなくなります。

  2. これを行うことによって:

    *((int *)handle) = 0;

    あなたは実際にダイナミックローダーの状態を破壊しているので、その後に偽のアドレスが与えられ、それを使おうとするとあなたはそれを引き起こします。dlsymSIGSEGV

問題#2を修正すると、プログラムはクラッシュしなくなりますが、ライブラリはアンロードされません。ライブラリを実際にアンロードするには、問題#1も修正する必要があります。

問題#1を最初に修正すると、問題#2でダイナミックローダーが破損することはなくなります。代わりにヒープが破損し、Valgrindでそれを簡単に観察できます。

于 2012-05-03T15:09:05.333 に答える
2

によるとman 8 ld.so

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

これが関連しているとは100%確信していませんが、関連しているようです。

于 2012-05-03T15:05:54.017 に答える