動的リンクライブラリをRAMにロードする必要がありますか?

動的リンクライブラリをRAMにロードする必要がありますか?

私たちが知っているように、実行中のすべての実行可能ファイルはRAMにロードされます。

また、静的リンクライブラリとダイナミックリンクライブラリという2種類のライブラリがあります。

必要に応じて、両方のライブラリをRAMにロードする必要があります。

私が知る限り、動的ライブラリをロードする方法は2つあります。

  1. たとえば、コンパイル時に接続します。g++ -lsofile
  2. コードから動的にロードするには、次のことが必要ですdlopen

私はすでに投稿しましたこの問題しかし、まだすべてのlibファイルを一覧表示できるとは限りません。上記の最初のケースでは、を使用またはldd確認してリンクされたファイルを取得できると思います/proc/{PID}/maps。しかし、2番目のケースでは、リンクされたファイルを取得する方法があるかどうか疑問に思います。例は次のとおりです。

void SomeModule()
{
    //dlopen here to link mysofile
}

int main()
{
    if (user_enter == 'a')
    {
        printf("hello world");
    }
    else
    {
        SomeModule();
    }
}

この例で実行してAlwaysと入力すると、呼び出されないため、接続されませんa。つまり、RAMにロードされません。私は正しいですか?dlopenmysofilemysofile

それでは、ソースコードを読むだけでなく、実行可能ファイルに必要なlibファイルをどのように取得できますか?

ベストアンサー1

私たちが知っているように、実行中のすべての実行可能ファイルはRAMにロードされます。

間違った!

一つ実行可能ファイルファイルは次にマップされます。仮想アドレス空間~のプロセスそれを実行仮想メモリカーネルのサブシステムです。物理RAMはカーネルによってのみ管理されます。読むオペレーティングシステム:3つの簡単な部分もっと学ぶ。

すべてではありませんコードフラグメント実行ファイルページング(ロードされていません!)RAMに。特に、まったく使用されていない大きなコードセクション(たとえば、呼び出されない大きな関数が含まれているため)はRAMに入りません。読むページングそしてページキャッシュ

時には、必要なすべてのページを便利に処理するのに十分な物理RAMが不十分です。その場合は、観察勝つ

動的リンカー(参照)ld-Linux(8))とドロペン(3)使用マッピング(2)メモリは共有ライブラリの一部のセグメントをマッピングします。したがって、プラグインのすべてのコードスニペットをRAMにロードするわけではありません。 Drepperの記事も読んでください。共有ライブラリの作成方法紙。

これを実行して常にaを入力すると、dlopenは呼び出されないため、mysofileはリンクされません。これは、mysofileがRAMにロードされないことを意味します。

持つ完全に絶対一般的に言えば今後どの共有ライブラリが使用されるかを予測そしてdlopen-ed。次の2つのシナリオを考えてみましょう。

  • 永続プログラム(おそらくブラウザ)は、ユーザーに共有ライブラリ(おそらくWebからダウンロード)をインポートするように要求し、dlopenそれを実行します。

  • プロセスは一時ファイルにいくつかのCコードを生成し、/tmp/emittedcode.cそのファイルを一時プラグインにコンパイルし(fork一部のファイルで適切なプロセスを実行して)、一時プラグインを-s(もちろん後でそこに適切なシンボルを追加します)。gcc -O -Wall -fPIC /tmp/emittedcode.c -shared -o /tmp/emittedcode.so/tmp/emittedcode.sodlopendlsym

私は2番目のアプローチが本当に好きです。参考にしてくださいCでコンパイル良い習慣です。現在のコンパイラは、一部のREPLインタラクションを通じてこれを達成するのに十分なほど高速です。

しかし、Linuxデスクトップでは、プロセスはdlopen 多くの共有オブジェクトつまり、プラグイン(最小数十万、おそらく数百万)です。私を見てmanydl.cはい(一時ファイルに「ランダム」Cコードを生成して繰り返します)。

PS。また注ダウンタイムの問題dlopen、すべての将来のルートを予測する理論的可能性に関連しています。

おすすめ記事