我可以通過sbrk(0)
獲取堆結束的地址,但是有沒有什麼方法可以通過編程方式獲取堆的開始地址,而不是通過解析/proc/self/maps
的內容?如何以編程方式獲取Linux上堆的地址
回答
我認爲解析/proc/self/maps
是Linux上查找堆段的唯一可靠方法。不要忘記,一些分配器(包括我的SLES中的一個)用於大塊mmap()
因此內存不再是堆的一部分,並且可以位於任何隨機位置。
否則,通常ld
會添加一個符號,該符號標記精靈中所有段的末尾,並且該符號被稱爲_end
。例如: -
extern void *_end;
printf("%p\n", &_end);
它的.bss
結束,傳統的小精靈的最後一段相匹配。地址之後,有一些對齊,通常跟在堆之後。堆棧和mmap()(包括共享庫)位於地址空間的較高地址處。
我不確定它的可移植性如何,但顯然它在Solaris 10上的工作方式相同。在HP-UX 11上,映射看起來不同,並且堆似乎與數據段合併,但分配確實發生在_end
。在AIX上,procmap
根本不顯示堆/數據段,但分配也獲得超過_end
符號的地址。所以現在看來目前相當便攜。
雖然,所有考慮,我不知道這是多麼有用。
P.S.測試程序:
#include <stdio.h>
#include <stdlib.h>
char *ppp1 = "hello world";
char ppp0[] = "hello world";
extern void *_end; /* any type would do, only its address is important */
int main()
{
void *p = calloc(10000,1);
printf("end:%p heap:%p rodata:%p data:%p\n", &_end, p, ppp1, ppp0);
sleep(10000); /* sleep to give chance to look at the process memory map */
return 0;
}
那麼,如果沒有辦法找到堆起始地址,malloc是如何實現的,它試圖將堆分成更小的內存塊? – Jun 2013-12-04 17:34:52
請注意,在具有隨機偏移的系統中,這可能會失敗。它可以被啓用,但默認情況下,linux模糊堆的「開始」,因此很難從機器外部找到它(防止緩衝區溢出攻擊)。 – jwarner112 2015-03-22 23:32:22
@Jun,libc調用'sbrk(0)'來查找堆的開始地址。但是這隻適用於libc:它在應用程序啓動期間,在main()之前被調用得非常早,因此堆的結束與堆的開始相同。在main()裏面,它不再是真的了。 – Dummy00001 2015-03-23 09:18:14
- 1. 如何以編程方式獲取iPhone 3G S的MAC地址?
- 2. 如何以編程方式獲取iPhone的藍牙MAC地址?
- 3. 如何以編程方式獲取Window phone 7的IP地址
- 4. 如何以編程方式獲取Lantronix XPort IP地址
- 5. 以編程方式從Yahoo!獲取聯繫人地址簿
- 6. 如何以編程方式獲取Linux內核頁面大小
- 7. 如何以編程方式獲取屏幕DPI(linux,mac)?
- 8. 如何在IRIX上以編程方式查找MAC地址?
- 9. 如何以編程方式獲取Windows 7/8/8.1/10手機的IP地址
- 10. 如何以編程方式獲取X509證書中的電子郵件地址?
- 11. 如何以編程方式獲取Linux和Linux系統窗口的分辨率?
- 12. 在彙編編程中獲取堆棧的起始地址
- 13. 如何在Linux上以編程方式獲取網絡接口速度?
- 14. 如何在Linux中以編程方式檢測IP地址更改?
- 15. 如何以編程方式獲取本地化資源?
- 16. 以編程方式獲取ASP.NET MVC應用程序的控制器地址
- 17. 如何使用SDK /以編程方式在iPhone上獲取AppID?
- 18. 如何以編程方式在此頁面上獲取圖像?
- 19. 如何在iphone地址簿中以編程方式保存家庭地址?
- 20. 以編程方式獲取堆信息使用jmx與java 5
- 21. ip.address()在aws上不起作用。如何以編程方式獲取AWS EC2的IP地址?
- 22. Java以編程方式獲得REAL環回地址
- 23. 如何以編程方式獲取Windows進程的線程數?
- 24. 如何以編程方式獲取Maven中的資源編碼
- 25. 如何獲取當前進程的起始地址--- Linux
- 26. 如何以編程方式獲取計算機的本地網絡IP地址? (C#)
- 27. 以編程方式在Android Nougat和O中獲取設備mac地址
- 28. 如何以編程方式獲取應用程序的名稱?
- 29. 如何以編程方式獲取管理中心網站網址?
- 30. linux:以編程方式獲取另一個進程的父進程?
它讓我感到困惑......如果我得到一堆p =(int *)malloc(sizeof(int)); ,那麼爲什麼我不能通過p得到堆的開始地址? – bazysong 2016-03-30 06:23:04