4

ファイル/proc/self/smapsのスニペットを次に示します。

00af8000-00b14000 r-xp 00000000 fd:00 16417      /lib/ld-2.8.so
Size:                112 kB
Rss:                  88 kB
Pss:                   1 kB
Shared_Clean:         88 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:           88 kB
Swap:                  0 kB
00b14000-00b15000 r--p 0001c000 fd:00 16417      /lib/ld-2.8.so
Size:                  4 kB
Rss:                   4 kB
Pss:                   4 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         4 kB
Referenced:            4 kB
Swap:                  0 kB

このプロセス(自己)が/lib/ld-2.8.soにリンクされており、(多数のうちの) 2 つのバイト範囲がメモリにマップされていることがわかります。

88kb の最初の範囲 (22 個の 4kb ページ) は共有されており、クリーンです。つまり、書き込まれていません。これはおそらくコードです。

4kb の 2 番目の範囲 (単一ページ) は共有されておらず、ダーティです。ディスク上のファイルからメモリ マップされているため、プロセスが書き込みを行っています。これはおそらくデータです。

しかし、その記憶には何がありますか?

メモリ範囲00b14000 ~ 00b15000を、大きな静的構造体が宣言されているファイルの行番号などの有用な情報に変換するにはどうすればよいですか?

この手法では、execshieldなどによる事前リンクとアドレス空間のランダム化を考慮し、デバッグ シンボルを分離する必要があります。

(動機は、ダーティ メモリを作成する一般的なライブラリを特定し、構造体を const と宣言するなどして修正することです)。

4

3 に答える 3

5

smap の形式は次のとおりです。

[BOTTOM]-[TOP] [PERM] [ファイルオフセット]

b80e9000-b80ea000 rw-p 0001b000 08:05 605294 /lib/ld-2.8.90.so

したがって、ファイル オフセット 0x0001b000 にあるファイル '/lib/ld-2.8.90.so' の実際のコンテンツは、そのプログラムのメモリの 0xb80e9000 にマップされます。

マップされたアドレスの行番号または C コードを抽出するには、実行可能ファイルまたはライブラリ ファイルの ELF セクションと一致させてから、GDB シンボルを抽出する必要があります (実行可能ファイルまたはライブラリにまだそれらがある場合)。

GDB ファイル形式は、http://sourceware.org/gdb/current/onlinedocs/gdbint_7.html#SEC60で (表面的には) 文書化されています。

于 2008-10-21T03:13:00.583 に答える
3

ParaDynプロジェクト (U. Wisc/U. Maryland) の SymtabAPI を見てください。これは多くのプラットフォームで動作し、ELF ファイル以上のものをサポートしています (COFF やその他のファイルもサポートしていると思います)。ここにドキュメントがあります。

具体的には、AddressLookup クラスに注目してください。私はそれがまさにあなたが望むことをすると思います。任意の時点でロードされている .so を見つけるための機能 (getLoadAddresses()) もいくつかあります。また、ロードされたモジュールのコード セクションの範囲を抽出することもできるので、メモリの特定の部分に何があるかを知ることができます。 .

警告: アドレス空間のランダム化を適切に処理すると思いますが、完全にはわかりません。

于 2008-10-21T06:05:55.790 に答える
0

Linux のメモリ ハンドラから情報を抽出して、アプリケーションの仮想メモリ マップが指定されたページにどのように関連しているかを判断する必要があります。メモリからスワップアウトされたページの情報も追跡したい場合は、さらに複雑になります。

ここでは、開始するための情報をいくつか見つけることができます。プロセス テーブルにはいくつかのページング情報が含まれていますが、探している詳細な情報をすべて取得するには、いくつかの異なる領域を調べなければならない可能性があります。

-アダム

于 2008-10-20T20:40:03.950 に答える