brk() , sbrk() (轉(zhuǎn)自CSDN)

原文鏈接:https://blog.csdn.net/heybeaman/article/details/80348582

brk() , sbrk() 的聲明如下:

#include<unistd.h>

intbrk(void*addr);

void*sbrk(intptr_tincrement);

這兩個(gè)函數(shù)都用來改變 "program break" (程序間斷點(diǎn))的位置,這個(gè)位置可參考下圖:

如 man 里說的:

引用

brk()??and??sbrk() change the location of the program break, which defines the end of the process's data segment (i.e., the program break is the first location after the end of the uninitialized data segment).

brk() 和 sbrk() 改變 "program brek" 的位置袍冷,這個(gè)位置定義了進(jìn)程數(shù)據(jù)段的終止處(也就是說磷醋,program break 是在未初始化數(shù)據(jù)段終止處后的第一個(gè)位置)。

如此翻譯過來胡诗,似乎會(huì)讓人認(rèn)為這個(gè) program break 是和上圖中矛盾的邓线,上圖中的 program break 是在堆的增長(zhǎng)方向的第一個(gè)位置處(堆和棧的增長(zhǎng)方向是相對(duì)的)淌友,而按照說明手冊(cè)來理解,似乎是在 bss segment 結(jié)束那里(因?yàn)槲闯跏蓟瘮?shù)據(jù)段一般認(rèn)為是 bss segment)骇陈。

首先說明一點(diǎn)震庭,一個(gè)程序一旦編譯好后,text segment 你雌,data segment 和 bss segment 是確定下來的器联,這也可以通過 objdump 觀察到。下面通過一個(gè)程序來測(cè)試這個(gè) program break 是不是在 bss segment 結(jié)束那里:

#include<stdio.h>

#include<unistd.h>

#include<stdlib.h>

#include<sys/time.h>

#include<sys/resource.h>

intbssvar;//聲明一個(gè)味定義的變量婿崭,它會(huì)放在 bss segment 中

intmain(void)

{

char*pmem;

longheap_gap_bss;

printf("end of bss section:%p\n", (long)&bssvar +4);

pmem = (char*)malloc(32);//從堆中分配一塊內(nèi)存區(qū)拨拓,一般從堆的開始處獲取

if(pmem ==NULL) {

perror("malloc");

exit(EXIT_FAILURE);

? ? }

printf("pmem:%p\n", pmem);

//計(jì)算堆的開始地址和 bss segment 結(jié)束處得空隙大小,注意每次加載程序時(shí)這個(gè)空隙都是變化的氓栈,但是在同一次加載中它不會(huì)改變

heap_gap_bss = (long)pmem - (long)&bssvar -4;

printf("1-gap between heap and bss:%lu\n", heap_gap_bss);

free(pmem);//釋放內(nèi)存渣磷,歸還給堆


sbrk(32);//調(diào)整 program break 位置(假設(shè)現(xiàn)在不知道這個(gè)位置在堆頭還是堆尾)

pmem = (char*)malloc(32);//再一次獲取內(nèi)存區(qū)

if(pmem ==NULL) {

perror("malloc");

exit(EXIT_FAILURE);

? ? ? ? }

printf("pmem:%p\n", pmem);//檢查和第一次獲取的內(nèi)存區(qū)的起始地址是否一樣

heap_gap_bss = (long)pmem - (long)&bssvar -4;//計(jì)算調(diào)整 program break 后的空隙

printf("2-gap between heap and bss:%lu\n", heap_gap_bss);

free(pmem);//釋放

return0;

}

下面,我們分別運(yùn)行兩次程序授瘦,并查看其輸出:

引用

[beyes@localhost C]$ ./sbrk?

end of bss section:0x8049938

pmem:0x82ec008

1-gap between heap and bss:2762448

pmem:0x82ec008

2-gap between heap and bss:2762448

[beyes@localhost C]$ ./sbrk?

end of bss section:0x8049938

pmem:0x8dbc008

1-gap between heap and bss:14100176

pmem:0x8dbc008

2-gap between heap and bss:14100176

從上面的輸出中醋界,可以發(fā)現(xiàn)幾點(diǎn):

1. bss 段一旦在在程序編譯好后,它的地址就已經(jīng)規(guī)定下來提完。

2. 一般及簡(jiǎn)單的情況下形纺,使用 malloc() 申請(qǐng)的內(nèi)存,釋放后徒欣,仍然歸還回原處逐样,再次申請(qǐng)同樣大小的內(nèi)存區(qū)時(shí),還是從第 1 次那里獲得帚称。

3. bss segment 結(jié)束處和堆的開始處的空隙大小,并不因?yàn)?sbrk() 的調(diào)整而改變秽澳,也就是說明了 program break 不是調(diào)整堆頭部闯睹。

所以,man 手冊(cè)里所說的??“program break 是在未初始化數(shù)據(jù)段終止處后的第一個(gè)位置” 担神,不能將這個(gè)位置理解為堆頭部楼吃。這時(shí),可以猜想應(yīng)該是在堆尾部妄讯,也就是堆增長(zhǎng)方向的最前方孩锡。下面用程序進(jìn)行檢驗(yàn):

當(dāng) sbrk() 中的參數(shù)為 0 時(shí),我們可以找到 program break 的位置亥贸。那么根據(jù)這一點(diǎn)躬窜,檢查一下每次在程序加載時(shí),系統(tǒng)給堆的分配是不是等同大小的:

#include<stdio.h>

#include<unistd.h>

#include<stdlib.h>

#include<sys/time.h>

#include<sys/resource.h>

intmain(void)

{

void*tret;

char*pmem;

pmem = (char*)malloc(32);

if(pmem ==NULL) {

perror("malloc");

exit(EXIT_FAILURE);

? ? ? ? }

printf("pmem:%p\n", pmem);

tret = sbrk(0);

if(tret != (void*)-1)

printf("heap size on each load: %lu\n", (long)tret - (long)pmem);

return0;

}

運(yùn)行上面的程序 3 次:

引用

[beyes@localhost C]$ ./sbrk?

pmem:0x80c9008

heap size on each load: 135160

[beyes@localhost C]$ ./sbrk?

pmem:0x9682008

heap size on each load: 135160

[beyes@localhost C]$ ./sbrk?

pmem:0x9a7d008

heap size on each load: 135160

[beyes@localhost C]$ ./sbrk?

pmem:0x8d92008

heap size on each load: 135160

[beyes@localhost C]$ vi sbrk.c

從輸出可以看到炕置,雖然堆的頭部地址在每次程序加載后都不一樣荣挨,但是每次加載后男韧,堆的大小默認(rèn)分配是一致的。但是這不是不能改的默垄,可以使用 sysctl 命令修改一下內(nèi)核參數(shù):

引用

#sysctl -w kernel/randomize_va_space=0

這么做之后此虑,再運(yùn)行 3 次這個(gè)程序看看:

引用

[beyes@localhost C]$ ./sbrk?

pmem:0x804a008

heap size on each load: 135160

[beyes@localhost C]$ ./sbrk?

pmem:0x804a008

heap size on each load: 135160

[beyes@localhost C]$ ./sbrk?

pmem:0x804a008

heap size on each load: 135160

從輸出看到,每次加載后口锭,堆頭部的其實(shí)地址都一樣了朦前。但我們不需要這么做,每次堆都一樣鹃操,容易帶來緩沖區(qū)溢出攻擊(以前老的 linux 內(nèi)核就是特定地址加載的)韭寸,所以還是需要保持 randomize_va_space 這個(gè)內(nèi)核變量值為 1 。

下面就來驗(yàn)證 sbrk() 改變的 program break 位置在堆的增長(zhǎng)方向處:

#include<stdio.h>

#include<unistd.h>

#include<stdlib.h>

#include<sys/time.h>

#include<sys/resource.h>

intmain(void)

{

void*tret;

char*pmem;

inti;

longsbrkret;

pmem = (char*)malloc(32);

if(pmem ==NULL) {

perror("malloc");

exit(EXIT_FAILURE);

? ? ? ? }

printf("pmem:%p\n", pmem);

for(i =0; i <65; i++) {

sbrk(1);

printf("%d\n", sbrk(0) - (long)pmem -0x20ff8);//0x20ff8 就是堆和 bss段 之間的空隙常數(shù)组民;改變后要用 sbrk(0) 再次獲取更新后的program break位置

? ? ? ? }

free(pmem);


return0;

}

運(yùn)行輸出:

引用

[beyes@localhost C]$ ./sbrk?

pmem:0x804a008

1

2

3

4

5

... ...

61

62

63

64

從輸出看到棒仍,sbrk(1) 每次讓堆往棧的方向增加 1 個(gè)字節(jié)的大小空間。

而 brk() 這個(gè)函數(shù)的參數(shù)是一個(gè)地址臭胜,假如你已經(jīng)知道了堆的起始地址莫其,還有堆的大小,那么你就可以據(jù)此修改 brk() 中的地址參數(shù)已達(dá)到調(diào)整堆的目的耸三。

實(shí)際上乱陡,在應(yīng)用程序中,基本不直接使用這兩個(gè)函數(shù)仪壮,取而代之的是 malloc() 一類函數(shù)憨颠,這一類庫函數(shù)的執(zhí)行效率會(huì)更高。還需要注意一點(diǎn)积锅,當(dāng)使用 malloc() 分配過大的空間爽彤,比如超出 0x20ff8 這個(gè)常數(shù)(在我的系統(tǒng)(Fedora15)上是這樣,別的系統(tǒng)可能會(huì)有變)時(shí)缚陷,malloc 不再從堆中分配空間适篙,而是使用 mmap() 這個(gè)系統(tǒng)調(diào)用從映射區(qū)尋找可用的內(nèi)存空間。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末箫爷,一起剝皮案震驚了整個(gè)濱河市嚷节,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌虎锚,老刑警劉巖硫痰,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異窜护,居然都是意外死亡效斑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門柱徙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鳍悠,“玉大人税娜,你說我怎么就攤上這事〔匮校” “怎么了敬矩?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)蠢挡。 經(jīng)常有香客問我弧岳,道長(zhǎng),這世上最難降的妖魔是什么业踏? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任禽炬,我火速辦了婚禮,結(jié)果婚禮上勤家,老公的妹妹穿的比我還像新娘腹尖。我一直安慰自己,他們只是感情好伐脖,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布热幔。 她就那樣靜靜地躺著,像睡著了一般讼庇。 火紅的嫁衣襯著肌膚如雪绎巨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天蠕啄,我揣著相機(jī)與錄音场勤,去河邊找鬼。 笑死歼跟,一個(gè)胖子當(dāng)著我的面吹牛和媳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播哈街,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼留瞳,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了叹卷?” 一聲冷哼從身側(cè)響起撼港,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤坪它,失蹤者是張志新(化名)和其女友劉穎骤竹,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體往毡,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蒙揣,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了开瞭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片懒震。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡罩息,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出个扰,到底是詐尸還是另有隱情瓷炮,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布递宅,位于F島的核電站娘香,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏办龄。R本人自食惡果不足惜烘绽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望俐填。 院中可真熱鬧安接,春花似錦、人聲如沸英融。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽矢赁。三九已至糯笙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間撩银,已是汗流浹背给涕。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留额获,地道東北人够庙。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像抄邀,于是被迫代替她去往敵國(guó)和親耘眨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 在C語言中,五種基本數(shù)據(jù)類型存儲(chǔ)空間長(zhǎng)度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 3,340評(píng)論 0 2
  • 第1章 第一個(gè)C程序第2章 C語言基礎(chǔ)第3章 變量和數(shù)據(jù)類型第4章 順序結(jié)構(gòu)程序設(shè)計(jì)第5章 條件結(jié)構(gòu)程序設(shè)計(jì)第6章...
    小獅子365閱讀 10,651評(píng)論 3 71
  • 堅(jiān)信知組7號(hào)彭克軍日精進(jìn)打卡201800503 一、要謙虛不要驕傲 1.警惕固定費(fèi)用的增加奥喻、首先讓全公司的人養(yǎng)成節(jié)...
    彭克軍閱讀 149評(píng)論 0 0
  • 趙四小姐偶宫,名趙一荻,又名綺霞环鲤,出生于香港纯趋。趙四小姐出生的時(shí)候,東方天際出現(xiàn)一片綺麗多彩的霞光,因此而得名吵冒。在家中排...
    生白術(shù)閱讀 207評(píng)論 0 0
  • 樂極生悲纯命,喜極而泣,大多數(shù)時(shí)候也是物極必反的結(jié)果痹栖。為什么人在這種環(huán)境之下能夠表現(xiàn)出截然不同的態(tài)度和情感亿汞?也許是因?yàn)?..
    527296628fa8閱讀 342評(píng)論 0 3