簡體   English   中英

關於sbrk()和malloc()

[英]About sbrk() and malloc()

我已經閱讀了有關sbrk()的linux手冊:

sbrk()更改程序中斷的位置,該位置定義了進程數據段的結尾(即,程序中斷是未初始化數據段結束之后的第一個位置)。

而且我確實知道用戶空間內存的組織如下: 在此處輸入圖片說明

問題是: 當我調用sbrk(1)時,為什么會說我在增加堆的大小? 如手冊所述,我正在更改“數據段和bss”的結束位置。 那么,數據段和bss的大小應該增加什么呢?

data和bss段是固定大小的。 因此,在這些段結束之后分配給進程的空間不是這些段的一部分; 它只是與它們相鄰。 該空間稱為堆空間,用於動態內存分配。

如果您想將其視為“擴展數據/ bss段”,那也很好。 它不會對程序的行為,分配的空間或其他任何行為產生任何影響。

Mac OS X上的手冊頁指示您確實不應該過多使用它們:

brk和sbrk函數是虛擬內存管理出現之前的早期歷史遺留問題。 brk()函數將進程的數據段(未初始化的數據)的中斷或最低地址設置為addr (緊隨bss之上)。 數據尋址限制在addr和指向堆棧段的最低堆棧指針之間。 內存由brk按頁面大小分配; 如果addr不能被系統頁面大小均分,則將其增加到下一個頁面邊界。

sbrk(0)可靠地返回程序中斷的當前值(另請參見end(3) )。 可以使用getrlimit(2)系統調用來確定數據段的最大允許大小。 不可能將中斷設置為超出對getrlimit的調用返回的rlim_max值,例如etext + rlp->rlim_max (有關etext的定義,請參見end(3) )。

盡管找不到指針,但我找不到end(3)的手冊頁,這有點令人氣憤。 甚至這個sbrk() )的手冊頁面(稍舊)也沒有鏈接。

請注意,今天很少使用sbrk(2) 大多數malloc實現都使用mmap(2)(至少對於大分配而言)來獲取內存段(並用munmap釋放它)。 通常, free只是將內存區域標記為將來的某些malloc可重用(並且不會將任何內存釋放給Linux內核 )。

(因此,實際上,現代linux進程的堆由多個段組成,因此比您的圖片更微妙;多線程進程每個線程只有一個堆棧)

使用proc(5) (尤其是/proc/self/maps/proc/$pid/maps )來了解某些進程虛擬地址空間 首先嘗試了解cat /proc/self/maps (顯示該cat命令的地址空間)和cat /proc/$$/maps (顯示您的shell的地址空間)的輸出。 還嘗試查看您的Web瀏覽器的maps偽文件(例如cat /proc/$(pidof firefox)/mapscat /proc/$(pidof iceweasel)/maps等...); 我有一千多行(所以是處理段)。

使用strace(1)可以了解由給定命令或進程完成的系統調用

充分利用Linux(大多數(可能是全部)) 標准庫實現是免費軟件的優勢 ,因此您可以研究其源代碼。 musl-libc的源代碼很容易閱讀。

還閱讀有關ELFASLR動態鏈接LD-Linux操作系統(8) ,以及高級Linux編程的書,然后系統調用(2)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM