ความหมายของการส่งออกของ PMAP


12

ฉันเขียน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ไม่ได้ช่วย


กลุ่มข้อความอ่านอย่างเดียวจริง ๆ แล้วดังนั้นจึงอยู่ที่ 0000000000600000
Danila Ladner

ขอบคุณ! ส่วนข้อความไม่ควรที่จะใช้งานได้เช่นกัน?
Thorsten Staerk

1
ใช่คุณถูก. r และ rx 0000000000400000 เช่นกัน
Danila Ladner

คำตอบ:


15

ส่วนของข้อความคือการทำแผนที่ที่ 0x400000 - มันถูกทำเครื่องหมาย 'rx' เพื่อให้สามารถอ่านและปฏิบัติการได้ การแมปที่ 0x600000 นั้นเป็นแบบอ่านอย่างเดียวดังนั้นเกือบจะแน่นอนว่าเป็นส่วน ".rodata" ของไฟล์ที่เรียกใช้งานได้ GCC ใส่ C สตริงตัวอักษรลงในส่วนอ่านอย่างเดียว การทำแผนที่ที่ 0x601000 คือ 'rw-' ดังนั้นอาจเป็นฮีปที่โด่งดัง คุณสามารถใช้งานได้malloc()1024 ไบต์และพิมพ์ที่อยู่เพื่อดูแน่นอน

คุณอาจได้รับข้อมูลเพิ่มเติมเล็กน้อยโดยค้นหา PID ของกระบวนการและทำ: cat /proc/$PID/maps- บนแล็ปท็อป Arch ของฉันซึ่งให้ข้อมูลเพิ่มเติมบางอย่าง มันใช้เคอร์เนล 3.12 ดังนั้นมันจึงมี/proc/$PID/numa_mapsและจัดการที่อาจให้ข้อมูลเชิงลึกด้วยเช่นกัน

สิ่งอื่น ๆ ที่ทำงานในแฟ้มที่ปฏิบัติการ: และnm objdump -xอดีตสามารถบอกให้คุณทราบถึงสิ่งต่าง ๆ ที่อยู่ในแผนที่หน่วยความจำดังนั้นคุณสามารถดูสิ่งที่อยู่ในส่วน 0x4000000 เทียบกับส่วนอื่น ๆ objdump -xแสดงส่วนหัวของไฟล์ ELF ให้คุณเห็นในหลาย ๆ สิ่งเพื่อให้คุณสามารถดูทุกส่วนพร้อมด้วยชื่อส่วนและไม่ว่าจะถูกแมปในเวลาทำงานหรือไม่

เท่าที่หาคำอธิบายเป็นลายลักษณ์อักษรของ "อะไรอยู่ที่ไหน" คุณจะต้องทำสิ่งต่าง ๆ เช่น google สำหรับ "รูปแบบหน่วยความจำ ELF FILE" โปรดทราบว่ารูปแบบไฟล์ ELF สามารถรองรับรูปแบบหน่วยความจำที่แปลกใหม่กว่าการใช้งานทั่วไป GCC และ Gnu ld และ glibc ทั้งหมดสร้างสมมติฐานที่ง่ายขึ้นเกี่ยวกับวิธีการวางไฟล์ปฏิบัติการและแมปลงในหน่วยความจำ ณ รันไทม์ หน้าเว็บจำนวนมากมีอยู่ที่อ้างถึงเอกสารนี้ แต่ใช้เฉพาะกับ Linux รุ่นเก่ากว่า, GCC หรือ glibc เวอร์ชันเก่าหรือนำไปใช้กับ x86 executables เท่านั้น หากคุณไม่มีมันให้readelfรับคำสั่ง หากคุณสามารถเขียนโปรแกรม C ให้สร้างเวอร์ชันของคุณเองobjdump -xหรือreadelfทำความคุ้นเคยกับวิธีการทำงานของไฟล์ที่ใช้งานได้และสิ่งที่อยู่ในนั้น


2
คำตอบที่ดี ตอนนี้ฮีปของโปรแกรมอยู่ที่ไหน [anon] นี้หมายความว่าอย่างไร ฉันต้อง google เพื่อหาอะไร
Thorsten Staerk

1
คุณรู้อะไรไหม? ฉันผิดเกี่ยวกับการทำแผนที่ที่อยู่ 0x601000 นั่นคือกองอาจ คุณจะต้องใช้readelfหรือobjdumpคิดออกและสิ่งที่ปฏิบัติการที่คุณได้ทำ กล่อง Arch linux ของฉันใช้ /usr/lib/libc-2.18.so ดังนั้นจึงค่อนข้างแตกต่างจากกล่องของคุณ
Bruce Ediger

2
0x601000เป็นส่วนข้อมูล มันมี.data, และสามารถขยายผ่าน.bss แสดงที่ไม่ได้รับการสนับสนุนไฟล์หน่วยความจำ (ได้รับการสนับสนุนดังกล่าวได้โดยการแลก) ได้รับผ่านทาง dlmalloc ใช้สำหรับการจัดสรรที่เล็กกว่า ~ 64Kb IIRC และสำหรับการจัดสรรที่ใหญ่ขึ้น ฮีปคือทุกอย่างที่จัดสรรโดย malloc ทั้งส่วนที่ขยายของเซ็กเมนต์ข้อมูลและการจัดสรรแบบอิง brk()[anon]mmap()brk()mmap()mmap()
ninjalj
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.