私たちが知っているように、実行中のすべての実行可能ファイルはRAMにロードされます。
また、静的リンクライブラリとダイナミックリンクライブラリという2種類のライブラリがあります。
必要に応じて、両方のライブラリをRAMにロードする必要があります。
私が知る限り、動的ライブラリをロードする方法は2つあります。
- たとえば、コンパイル時に接続します。
g++ -lsofile
- コードから動的にロードするには、次のことが必要です
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にロードされません。私は正しいですか?dlopen
mysofile
mysofile
それでは、ソースコードを読むだけでなく、実行可能ファイルに必要な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.so
dlopen
dlsym
私は2番目のアプローチが本当に好きです。参考にしてくださいCでコンパイル良い習慣です。現在のコンパイラは、一部のREPLインタラクションを通じてこれを達成するのに十分なほど高速です。
しかし、Linuxデスクトップでは、プロセスはdlopen
多くの共有オブジェクトつまり、プラグイン(最小数十万、おそらく数百万)です。私を見てmanydl.c
はい(一時ファイルに「ランダム」Cコードを生成して繰り返します)。
PS。また注ダウンタイムの問題dlopen
、すべての将来のルートを予測する理論的可能性に関連しています。
答え2
そうですね。dlopen
ターゲットライブラリは、呼び出されないと(プロセスの)メモリにロードされません。
ソースコードを読み取らずに必要なライブラリを決定することは、停止問題のバリエーションのように感じられます。いくつかの経験的な方法が利用可能です。プログラムがに接続されていないとlibdl
使用できませんdlopen
。その場合は使用できますstrace
(参照)。実行時にどの動的ライブラリ実行可能ファイルがロードされているかを確認するには?dlopen
)または静的分析の使用に関する主張を特定しようとします。ただし、プログラムはlibdl
直接含めることができます(静的リンクまたはビルドコード経由)。動的リンカーは魔法ではないので、プログラム自体を再実装するのを防ぐ方法はありません。完全にこれらの経験的な方法を使用して、必要なすべてのライブラリを見つけたことを確認してください。たぶん、いくつかのプログラムは自分が追跡していることを発見し、ライブラリのロードをスキップするかもしれません。
必要なすべてのライブラリを一覧表示する唯一の信頼できる方法は、ソースコードを読むことです。