タグ付けされた質問 「dynamic-linking」

コンピューティングでは、動的リンクとは、実行時に実行可能ファイルに必要な共有ライブラリをロード(永続ストレージからRAMにコピー)およびリンク(ジャンプテーブルを埋め、ポインタを再配置)するオペレーティングシステム(OS)のプロセスです。実行されたとき。

4
SO(共有オブジェクト)番号はどのように機能しますか?
Linuxでの共有オブジェクトは「so番号」を使用していること、つまり、共有オブジェクトの異なるバージョンには異なる拡張子が与えられていることを知っています。たとえば: example.so.1 example.so.2 (Windowsの「DLL Hell」とは対照的に)2つのバージョンのライブラリがシステム上に存在できるように、2つの異なるファイルを作成するという考え方だと理解しています。これが実際にどのように機能するか知りたいですか?多くの場合、それexample.soは実際example.so.2に.2は最新バージョンがどこにあるのかを示すシンボリックリンクであることがわかります。それでは、古いバージョンに依存するアプリケーションはどのようexample.soに正しく識別しますか?使用しなければならない番号に関する規則はありますか?または、これは単なる慣習ですか?ソフトウェアバイナリがシステム間で転送されるWindowsとは異なり、システムに新しいバージョンの共有オブジェクトがある場合、ソースからコンパイルするときに古いバージョンに自動的にリンクされますか? これは関連していると思われますldconfigが、どうすればよいかわかりません。

4
実行可能ファイルは、実行時に共有オブジェクトをどこで検索しますか?
リンク/コンパイル時に共有オブジェクトを含める定義方法を理解しています。ただし、*.so実行時に実行可能ファイルが共有オブジェクト(ライブラリ)をどのように検索するのか、まだ疑問に思います。 たとえば、私のアプリa.outはlib.soライブラリで定義された関数を呼び出します。コンパイル後lib.so、の新しいディレクトリに移動し$HOMEます。 a.outそこに探しに行くと言うことができますか?

2
64ビットシステムで32ビットバイナリを実行しているときに「Not found」メッセージが表示される
現在、debian(wheezy / amd64)に奇妙な問題があります。 サーバーをインストールするためにchrootを作成しました(詳細については説明できませんが、申し訳ありません)。そのパスを呼び出しましょう/chr_path/。物事を簡単にするために、このchrootをdebootstrap(wheezy / amd64も)で初期化しました。 すべてはchroot内でうまく機能しているように見えましたが、サーバーのインストーラースクリプトを起動したとき、次のようになりました:( zsh: Not found /some_path/perlインストーラーには何らかの理由でperlバイナリが含まれています) 当然、/some_path/場所を確認し、「perl」バイナリを見つけました。filechroot環境では以下を返します。 /some_path/perl ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped ファイルが存在し、問題ないようで、正しい権限があります。使用できますfileがls、vimそれを実行しようとするとすぐに- ./perl例えば-私は得る:zsh: Not found ./perl。 この状況は私にはかなり理解できます。さらに: エラーを発生させることなく、chrootで他の基本的なバイナリ(/ bin / ls、...)を実行できます。 プロジェクトに付属している他のバイナリにも同じ問題があります メインルート(/chr_path/some_path/perl)からバイナリを実行しようとすると、動作します。 私は私のバイナリのコピーでバイナリの1つを入れようとしましたls。アクセス権が同じであることを確認しましたが、これは何も変更しませんでした(1つは機能していましたが、もう1つは機能していませんでした)


5
Linuxでライブラリをロードするために使用されるシステムコールは何ですか?
strace出力、実行可能ファイルが呼び出すことをライブラリへのパスが呼び出しですopen()。これは、動的にリンクされる実行可能ファイルで使用されるシステムコールですか?どうdlopen()?open()プログラムの実行に役割を果たすとは思いませんでした。

3
ライブシステムで定義されている共有ライブラリシンボルの場所を見つける/システムでエクスポートされたすべてのシンボルを一覧表示する
基本的に、これは1つに2つの質問です。なぜなら、システム内でエクスポートされたすべてのシンボルとそれらの共有ライブラリパスを一覧表示できれば、単純にgrepその出力ができるからです。 カーネルシンボルの場合cat /proc/kallsyms、メモリにロードされたモジュールのすべてのシンボルのリストをいつでも取得できるため、多少簡単だと思います。次にsudo cat /proc/modules、ロードされたモジュールとそのア​​ドレスのリストが表示されますが、モジュールがロードされたパスは表示されません(別のツリー外の.koオブジェクトとしてビルドされている場合) たとえば、次をkst使用してプログラムをトレースしようとしますltrace。 $ ltrace kst2 ... _ZNK13QGraphicsItem10parentItemEv(0xa1ccdb4, 0, 0xbfe631a8, 0x823652b, 0xbfe63298) = 0xa1ce854 __dynamic_cast(0xa1ce854, 0x839ff00, 0x8306b80, 84, 0xbfe63298) = 0xa1ce800 _ZNK13QGraphicsItem10parentItemEv(0xa1ccdb4, 0x839ff00, 0x8306b80, 84, 0xbfe63298) = 0xa1ce854 __dynamic_cast(0xa1ce854, 0x839ff00, 0x8306b80, 84, 0xbfe63298) = 0xa1ce800 ... ...そして、これがどこにあるのか知りたい_ZNK13QGraphicsItem10parentItemEvです。 では、共有ライブラリシンボルについてはどうすればよいでしょうか?[gcc-help]を読むRe:シンボルが定義されているライブラリを見つける。; 私はこのようなものを試しました: $ find /usr/lib -name '*.so*' -exec nm --print-file-name …

2
クラッシュせずに共有ライブラリをアップグレードする方法は?
ここでは、実行可能ファイルを書き換えることができ、プロセスは正常に実行されます-プロセスが再起動すると再読み込みされます。 ただし、プロセスの実行中に(devからテストサーバーへのscpを使用して)バイナリファイルを置き換えようとすると、「file busy」と表示されます。そして、共有ライブラリファイル(* .so)を置き換えると、それをリンクするすべてのプロセスがクラッシュします。 なぜそうなのか?何か不足していますか?プロセスを停止/クラッシュせずにバイナリファイルを置き換えるにはどうすればよいですか?

4
Linux実行可能ファイルは、ファイルがPATHに存在していても「File not found」で失敗します
wine実行可能ファイル(バージョン2.12)を起動したいのですが、次のエラー($= shellプロンプト)が表示されます。 $ wine bash: /usr/bin/wine: No such file or directory $ /usr/bin/wine bash: /usr/bin/wine: No such file or directory $ cd /usr/bin $ ./wine bash: ./wine: No such file or directory ただし、ファイルは次のとおりです。 $ which wine /usr/bin/wine 実行可能ファイルは間違いなく存在し、デッドシンボリックリンクはありません。 $ stat /usr/bin/wine File: /usr/bin/wine Size: 9712 Blocks: 24 IO Block: 4096 …

1
リンクされたライブラリの必要なバージョンを見つけるまで、Unix / Linuxシステムがディレクトリを横断しないのはなぜですか?
リンクされたライブラリ(libz.so.1.2.7)を必要とする「alpha」という名前のバイナリ実行可能ファイルがあります。 /home/username/myproduct/lib/libz.so.1.2.7 次のコマンドを実行してバイナリ実行可能ファイルを生成する前に、同じものをターミナルインスタンスにエクスポートします。 export LD_LIBRARY_PATH=/home/username/myproduct/lib/:$LD_LIBRARY_PATH さて、同じライブラリを必要とするがバージョンが異なる別のアプリケーション「bravo」、つまりで使用可能な(libz.so.1.2.8)を生成すると /lib/x86_64-linux-gnu/libz.so.1.2.8、システムは次のエラーをスローします。 version `ZLIB_1.2.3.3' not found (required by /usr/lib/x86_64-linux-gnu/libxml2.so.2) の設定を解除するとLD_LIBRARY_PATH、「bravo」が正常に起動します。上記の動作は、リンクされたライブラリの検索中にLD_LIBRARY_PATH定義されたディレクトリパスよりも優先される/etc/ld.so.confため、上記のエラーが発生することを理解しています。ライブラリの最初のインスタンスが異なるバージョンである場合、UNIX / LINUXの開発者が、階層に従って他のディレクトリ内のリンクされたライブラリを検索するようにOSを設計しなかった理由に興味があります。 簡単に言えば、UNIX / LINUXシステムは、必要なライブラリが見つかるまで一連のディレクトリを走査します。しかし、バージョンに関係なくライブラリの最初のインスタンスを受け入れるのではなく、予想されるバージョンが見つかるまで同じことをしないのはなぜですか?

9
DebianでJavaを起動する際の問題:「共有ライブラリの読み込み中のエラー:libjli.so」
私はJavaを起動しようとしています: $ java -version java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory $ ldd /usr/lib/jvm/java-6-openjdk/jre/bin/java linux-gate.so.1 => (0xb779f000) libz.so.1 => /usr/lib/libz.so.1 (0xb7780000) libpthread.so.0 => /lib/i686/cmov/libpthread.so.0 (0xb7767000) libjli.so => /usr/lib/jvm/java-6-openjdk/jre/bin/../lib/i386/jli/libjli.so (0xb7762000) libdl.so.2 => /lib/i686/cmov/libdl.so.2 (0xb775e000) libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7603000) /lib/ld-linux.so.2 (0xb77a0000 $ …

1
debian / ubuntuに2つのglibcを一緒にインストールする
同じマシンに2つの異なるglibcバージョンをインストールして使用することは可能ですか?古いglibcバイナリに依存するレガシーソフトウェアを実行するために1つのバージョンのみが使用される場合 /opt/old-glibcひどく管理する代わりに、パッケージマネージャー(「このパッケージとその依存関係をインストールする」など)を使用してそれを行うことは可能ですか?


1
ld-linux.soハックで代替libcを使用します。クリーナーメソッド?
私は非常に古いglibcを備えたレガシーシステムを持っています。これは、膨大なテスト/検証作業を行わなければアップグレードできません。 そのシステム上で新しいプログラム(Java 1.7など)を数回実行する必要がありました。私は、必要なすべてのライブラリをパッケージ化し、chrootでサービスを実行するchrootソリューションを選択しました。 ただし、chrootは非常に制限されているため、LD_LIBRARY_PATHの問題を解決したいと考えています。残念なことに、私はそれlibc.so.6: cannot handle TLS dataを試みるときにエラーを受け取ります。 /lib/ld-linux.so.2chrootからも必要であることがわかりました。これは動作します: LD_LIBRARY_PATH=/home/chroot/lib /home/chroot/lib/ld-linux.so.2 /home/chroot/bin/program ただし、ライブラリのロード元を決定するためにjava検査/proc/self/cmdlineすることにより、私のトリックを阻止します。バイナリの名前が「bin / java」でない場合は失敗します。また、起動時にjava自体が実行されるため、問題がさらに複雑になります。 この作業を行う最後の試みとして、Javaバイナリを16進エディタで開き、文字列/lib/ld-linux.so.2を/home/chroot/ld.so(にシンボリックリンクしましたld-linux.so.2)に置き換えました。 しかし、すべての新しいバイナリのパスをネストされたシステムの絶対パスに書き換えるのは非常に面倒だと誰もが同意すると思います。 カスタムld-linux.so を含むカスタムライブラリパスを使用するよりクリーンな方法を知っている人はいますか?

2
独自のld.so.cacheを使用できますか?
ldconfig 2つの興味深いオプションがあります。 -f conf Use conf instead of /etc/ld.so.conf. -C cache Use cache instead of /etc/ld.so.cache. 私は/etc/ld.so.conf自分のホームディレクトリにコピーしてみて、ローカルライブラリへのパス/home/syockit/local/usr/libなどを含むように編集しました。 ldconfig -f /home/syockit/ld.so.conf -C /home/syockit/ld.so.cache その後、ライブラリがキャッシュされていることを確認するために、実行しました ldconfig -f /home/syockit/ld.so.conf -C /home/syockit/ld.so.cache -p | less システムライブラリも含めて、すべてのライブラリが含まれています。 ここで、デフォルトのリンカーがこれら2つを使用するようにします。しかし、man ld.soでは、カスタム.confまたはを使用できるという言及はありません.cache。では、上記の2つのオプションのポイントは何ldconfigですか?

1
Linux、GNU GCC、ld、バージョンスクリプト、ELFバイナリ形式—仕組み
Linuxでのライブラリのバージョン管理と、それをすべて機能させる方法について詳しく学習しようとしています。コンテキストは次のとおりです。 -動的ライブラリの2つのバージョンがあり、同じインターフェイスセットを公開します(例:libsome1.soと)libsome2.so。 -アプリケーションはに対してリンクされていlibsome1.soます。 -このアプリケーションはlibdl.so、たとえば、別のモジュールを動的にロードするために使用しますlibmagic.so。 -今libmagic.soに対してリンクされていlibsome2.soます。明らかに、リンカスクリプトを使用してシンボルを非表示にせずにlibmagic.so、実行時のすべてのインターフェイスの呼び出しlibsome2.soはに解決されlibsome1.soます。これlibVersion()は、マクロの値に対して返される値をチェックすることで確認できますLIB_VERSION。 -だから、次にlibmagic.so、リンカスクリプトでコンパイルおよびリンクを試みます。リンカスクリプトは、3を除くすべてのシンボルを定義しlibmagic.so、それによってエクスポートされます。この作品...または少なくともlibVersion()とLIB_VERSION値が一致する(そしてそれは、バージョン2ではない1を報告します)。 -ただし、一部のデータ構造がディスクにシリアル化されると、破損が発生しました。アプリケーションのディレクトリlibsome1.soで、を指すようlibsome2.soにソフトリンクを削除して作成すると、すべてが期待どおりに機能し、同じ破損は発生しません。 私は仕方がありませんが、これは、実行時リンカーのシンボルの解決におけるいくつかの競合が原因であると考えられます。私は多くのことを試しましたlibsome2.so、すべてのシンボルが安定するようにリンクしようとしましたsymbol@@VER_2(コマンドがnm -CD libsome2.soまだシンボルをリストしているので、まだリストしsymbolていないので混乱していますsymbol@@VER_2)...何もうまくいかないようです!!! 助けて!!!!!!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.