[ LUGOS ] free, delete ...

Andrej Presern andrejp na luz.fe.uni-lj.si
Tor Jun 23 14:17:56 CEST 1998


=?iso-8859-2?Q?Jernej_Kov=B9e?= wrote:
> Vprasanje je, kako v zgornjem primeru kasneje v programu locis med tem,
> da kazalec a kaze na staticno, kazalec b pa na dinamicno alociran pomnilni
> in odgovor je, da ne mores.

Ce detaljno poznas arhitekturo, je to vcasih mozno. Npr. pri Linuxu je
mozno lociti globalne staticne spremenljivke od dinamicno dodeljenega
pomnilnika, ker se dinamicno dodeljen pomnilnik dodeli bodisi s kopice
(dinamicna alokacija lokalnih spremenljivk) ali pa se dolocen segment
mapira direktno mapira v naslovni prostor aplikacije. Globalne
spremenljivke so zapisane bodisi v .data bodisi v .bss segmentu, oba pa
sta fiksirana na neko lokacijo; recimo ce pogledamo mape za proces init:

[root na soda /proc/1]# cat maps 
08048000-0804e000 r-xp 00000000 03:03 155686
0804e000-0804f000 rw-p 00005000 03:03 155686
0804f000-08053000 rwxp 00000000 00:00 0
40000000-40009000 r-xp 00000000 03:03 65831
40009000-4000b000 rw-p 00008000 03:03 65831
4000b000-40010000 r--p 00000000 03:03 12396
40010000-40012000 r-xp 00000000 03:03 65841
40012000-40013000 rw-p 00001000 03:03 65841
40013000-400a4000 r-xp 00000000 03:03 65832
400a4000-400ab000 rw-p 00090000 03:03 65832
400ab000-400b7000 rw-p 00000000 00:00 0
bffff000-c0000000 rwxp 00000000 00:00 0

in ce pogledamo strukturo izvrsilne datoteke za isti proces:

[andrejp na soda ~]$ objdump --section-headers `which init`

/sbin/init:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  080480d4  080480d4  000000d4  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .hash         00000294  080480e8  080480e8  000000e8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .dynsym       00000600  0804837c  0804837c  0000037c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .dynstr       00000328  0804897c  0804897c  0000097c  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .rel.got      00000008  08048ca4  08048ca4  00000ca4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .rel.bss      00000038  08048cac  08048cac  00000cac  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .rel.plt      00000260  08048ce4  08048ce4  00000ce4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .init         0000002c  08048f50  08048f50  00000f50  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  8 .plt          000004d0  08048f7c  08048f7c  00000f7c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  9 .text         000034b4  0804944c  0804944c  0000144c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .fini         0000001c  0804c900  0804c900  00004900  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .rodata       000007da  0804c91c  0804c91c  0000491c  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 12 .data         00000234  0804e0f8  0804e0f8  000050f8  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 13 .ctors        00000008  0804e32c  0804e32c  0000532c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 14 .dtors        00000008  0804e334  0804e334  00005334  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 15 .got          00000140  0804e33c  0804e33c  0000533c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 16 .dynamic      00000090  0804e47c  0804e47c  0000547c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .bss          00000204  0804e50c  0804e50c  0000550c  2**3
                  ALLOC
 18 .comment      00000078  00000000  00000000  0000550c  2**0
                  CONTENTS, READONLY
 19 .note         00000078  00000078  00000078  00005584  2**0
                  CONTENTS, READONLY

lahko vidimo, da se bo ta konkretni image mapiral na naslov 0x08048000,
pri cemer ELF headerji zavzamejo prvih 0xD4 bytov, zato se segment zacne
na 0x080480D4 (glej segment z indeksom 0). Da se je proces dejansko tja
nalozil, lahko vidimo v maps tabeli.

Zadnja vrstica mapirne tabele oznacuje kopico. Kot lahko vidis, kopica
pri x86 arhitekturi na Linux-u raste od zgoraj navzdol (pri cemer je
zgornji gigabyte naslovnega prostora (nad 0xC0000000) rezerviran za
kernel) in na njej je dodeljen prostor za lokalne spremenljivke in
alociran pomnilnik. Torej, ce zelis izvedeti, kje je bila dolocena
spremenljivka dodeljena, moras brskati po /proc/pid/maps, poznati pa
moras tudi ELF strukturo programa, da lahko o cemerkoli vsaj priblizno
sklepas (libelf.so saves the day).

Ne glede na to, da se da izvedeti, kje je bila dolocena spremenljivka
dodeljena, pa osebno ne vidim v uporabi tega znanja prav nobene
prednosti, ki jo ne bi mogli bolj ucinkovito doseci z uporabo kaksne
druge metode (beri: ne delaj tega, ker je lame:)

Andrej

-- 
Andrej Presern, andrejp na luz.fe.uni-lj.si




Dodatne informacije o seznamu Starilist