Ich schrieb main.c
in Linux:
int main()
{
while (1){}
}
Wenn ich es kompiliere und starte, kann ich pmap
es:
# 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) geteilt durch K entspricht der VIRT
Spalte in der Ausgabe von top
. Wo ist nun das Textsegment? Bei 400000, 600000 und 601000, richtig? Wo kann ich eine Erklärung lesen, was ist wo? man pmap
hat nicht geholfen.
linux
process
memory
virtual-memory
Thorsten Staerk
quelle
quelle
Antworten:
Das Textsegment ist das Mapping bei 0x400000 - es ist als 'rx' für lesbar und ausführbar markiert. Die Zuordnung bei 0x600000 ist schreibgeschützt, das ist also mit ziemlicher Sicherheit der Abschnitt ".rodata" der ausführbaren Datei. GCC fügt C-String-Literale in einen schreibgeschützten Abschnitt ein. Die Zuordnung bei 0x601000 ist 'rw-', das ist also wahrscheinlich der berühmte Haufen. Sie könnten Ihre ausführbare Datei
malloc()
1024 Bytes haben und die Adresse ausdrucken, um sicher zu gehen.Möglicherweise erhalten Sie ein wenig mehr Informationen, indem Sie die PID Ihres Prozesses ermitteln und Folgendes ausführen:
cat /proc/$PID/maps
- Auf meinem Arch-Laptop werden einige zusätzliche Informationen angezeigt. Es wird ein 3.12-Kernel ausgeführt, also auch ein/proc/$PID/numa_maps
Catting, das möglicherweise auch einen kleinen Einblick gibt.Andere Dinge, die für die ausführbare Datei ausgeführt werden müssen:
nm
undobjdump -x
. Ersteres kann Ihnen eine Vorstellung davon geben, wo verschiedene Dinge in der Speicherzuordnung liegen, sodass Sie sehen können, was sich im Abschnitt 0x4000000 im Vergleich zu den anderen Abschnitten befindet.objdump -x
Zeigt Ihnen unter anderem ELF-Dateikopfzeilen an, sodass Sie alle Abschnitte einschließlich der Abschnittsnamen und der Zuordnung zu einer Laufzeit anzeigen können.Um eine schriftliche Erklärung für "Was ist wo?" Zu finden, müssen Sie beispielsweise Google für "ELF-DATEI-Speicherlayout" ausführen. Beachten Sie, dass das ELF-Dateiformat mehr exotische Speicherlayouts unterstützt, als normalerweise verwendet werden. GCC, Gnu ld und glibc machen alle vereinfachende Annahmen darüber, wie eine ausführbare Datei angeordnet und dann zur Laufzeit in den Speicher abgebildet wird. Es gibt viele Webseiten, die dies dokumentieren sollen, aber nur für ältere Versionen von Linux, ältere Versionen von GCC oder glibc oder nur für x86-ausführbare Dateien gelten. Wenn Sie es nicht haben, rufen Sie den
readelf
Befehl ab. Wenn Sie C-Programme schreiben können, erstellen Sie eine eigene Version vonobjdump -x
oderreadelf
machen Sie sich mit der Funktionsweise und den darin enthaltenen ausführbaren Dateien vertraut.quelle
readelf
oder verwenden,objdump
um es herauszufinden, und was auch immer die ausführbare Datei, die Sie gemacht haben. Meine Arch Linux Box verwendet /usr/lib/libc-2.18.so, es ist also ganz anders als deine Box.0x601000
ist das Datensegment. Es enthält.data
,.bss
und kann über verlängert werdenbrk()
.[anon]
Gibt an, dass der Speicher nicht dateigesichert ist (also durch Auslagerung gesichert ist), der über abgerufen wurdemmap()
. dlmalloc verwendetbrk()
für Zuordnungen, die kleiner als ~ 64 KB IIRC sind, undmmap()
für größere Zuordnungen. Der Heap ist alles, was von malloc zugewiesen wird, sowohl der erweiterte Teil des Datensegments als auch die aufmmap()
-basierten Zuweisungen.