pmapの出力の意味


12

私はmain.cLinuxで書いた:

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

total(3876)をKで除算するVIRTと、の出力の列に等しくなりますtop。今、テキストセグメントはどこにありますか?400000、600000、601000でしょ?どこに何があるのか​​説明をどこで読むことができますか?man pmap助けにはならなかった。


テキストセグメントは実際には読み取り専用なので、0000000000600000になります。
ダニラ・ラドナー

ありがとう!テキストセグメントも実行可能であるべきではありませんか?
トールステンスターク

1
はい、あなたは正しいです。rおよびrx。0000000000400000も同様です。
ダニラ・ラドナー

回答:


14

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

プロセスのPIDを見つけて、以下を実行することで、もう少し情報を得ることができますcat /proc/$PID/maps。3.12カーネルを実行しているので/proc/$PID/numa_maps、があり、小さな洞察を与える可能性のあるcattingもあります。

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

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


2
素晴らしい答え。さて、プログラムのヒープはどこにありますか?そして、この[anon]はどういう意味ですか?これを見つけるにはグーグルに何が必要ですか?
トールステンスターク

1
あのね?私は0x601000アドレスマッピングについて間違っていました-それはおそらくヒープです。を使用するreadelfobjdump、それを把握する必要があります。私のArch Linuxボックスは/usr/lib/libc-2.18.soを使用しているため、あなたのボックスとはまったく異なります。
ブルースエディガー

2
0x601000データセグメントです。含まれており.data.bssで拡張できますbrk()[anon]を介して取得された、非ファイルバックアップメモリ​​(スワップによってバックアップされたメモリ)を示しますmmap()。dlmallocはbrk()、〜64Kb IIRCより小さい割り当てとmmap()、より大きな割り当てに使用します。ヒープは、データセグメントの拡張部分とmmap()ベースの割り当ての両方であるmallocによって割り当てられたすべてのものです。
ninjalj
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.