web-dev-qa-db-ja.com

pmapの出力の意味

私が書いた main.c Linuxの場合:

int main()
{
  while (1){}
}

コンパイルして起動すると、pmapできます。

# pmap 28578
28578:   ./a.out
0000000000400000      4K r-x--  /root/a.out
0000000000600000      4K r----  /root/a.out
0000000000601000      4K rw---  /root/a.out
00007f87c16c2000   1524K r-x--  /lib/libc-2.11.1.so
00007f87c183f000   2044K -----  /lib/libc-2.11.1.so
00007f87c1a3e000     16K r----  /lib/libc-2.11.1.so
00007f87c1a42000      4K rw---  /lib/libc-2.11.1.so
00007f87c1a43000     20K rw---    [ anon ]
00007f87c1a48000    128K r-x--  /lib/ld-2.11.1.so
00007f87c1c55000     12K rw---    [ anon ]
00007f87c1c65000      8K rw---    [ anon ]
00007f87c1c67000      4K r----  /lib/ld-2.11.1.so
00007f87c1c68000      4K rw---  /lib/ld-2.11.1.so
00007f87c1c69000      4K rw---    [ anon ]
00007fff19b82000     84K rw---    [ stack ]
00007fff19bfe000      8K r-x--    [ anon ]
ffffffffff600000      4K r-x--    [ anon ]
 total             3876K

合計(3876)をKで除算すると、VIRTの出力のtop列に等しくなります。では、テキストセグメントはどこにありますか? 400000、600000、601000ですね。どこに何があるか説明はどこで読めますか? man pmapは役に立たなかった。

12
Thorsten Staerk

テキストセグメントは0x400000でのマッピングです。読み取り可能および実行可能であるために「r-x」とマークされています。 0x600000でのマッピングは読み取り専用であるため、これはほぼ確実に実行可能ファイルの「.rodata」セクションです。 GCCはC文字列リテラルを読み取り専用セクションに配置します。 0x601000でのマッピングは「rw-」であるため、おそらくそれは有名なヒープです。実行可能ファイルmalloc() 1024バイトを用意し、アドレスを出力して確認します。

プロセスのPIDを見つけて次のようにすると、もう少し情報が得られる場合があります。cat /proc/$PID/maps-私のArchラップトップでは、追加の情報が表示されます。それは3.12カーネルを実行しているので、/proc/$PID/numa_mapsもあり、小さな洞察を与えるかもしれないcattingも持っています。

実行可能ファイルで実行するその他のこと:nmおよびobjdump -x。前者は、メモリマップ内のさまざまなものがどこにあるのかを知ることができるため、0x4000000セクションと他のセクションの内容を確認できます。 objdump -xは、ELFファイルのヘッダーを他の多くのものの中で表示するため、すべてのセクションを表示できます。セクション名と、それらがランタイムにマップされているかどうかを確認できます。

「どこにあるのか」について書かれた説明を見つける限り、「ELFファイルのメモリレイアウト」については、googleなどのことを行う必要があります。 ELFファイル形式は、一般的に使用されるよりもエキゾチックなメモリレイアウトをサポートできることに注意してください。 GCCとGnu ldとglibcはすべて、実行可能ファイルがどのようにレイアウトされ、実行時にメモリにマップされるかについて、単純化した仮定を行います。これを文書化することを意図した多くのWebページが存在しますが、古いバージョンのLinux、古いバージョンのGCCまたはglibcにのみ適用されるか、x86実行可能ファイルにのみ適用されます。お持ちでない場合は、readelfコマンドを入手してください。 Cプログラムを記述できる場合は、独自のバージョンのobjdump -xまたはreadelfを作成して、実行可能ファイルがどのように機能するか、およびそれらの内容を理解してください。

15
Bruce Ediger