簡體   English   中英

有沒有辦法知道在Linux中傳遞給__free_hook的指針的大小?

[英]Is there a way to know size of a pointer passed to a __free_hook in Linux?

我想跟蹤大型應用程序當前分配的內存量。

我發現我可以在malloc / free / realloc周圍安裝鈎子以攔截內存分配調用:

http://man7.org/linux/man-pages/man3/malloc_hook.3.html

所以我要跟蹤的是分配的總字節數 - 釋放的總字節數。

現在問題是free只接受指針而不是大小。

在我的malloc鈎子中可以創建我自己的map或hashmap,它跟蹤為該指針分配了多少內存,但這會導致相當多的開銷。

有沒有辦法(即使它有點像黑客)在調用free時使用ptr的大小(使用默認的g ++ malloc)獲得Linux(64位)的大小?

linux man malloc_usable_size

malloc_usable_size()返回動態分配的緩沖區ptr中可用的字節數,該緩沖區可能大於請求的大小(但如果請求成功,則保證至少同樣大)。 通常,您應該存儲請求的分配大小,而不是使用此函數。

這不是你問題的直接答案,但看到你對總分配內存感興趣,那么這就是解決方案:

我想你最感興趣的是它返回的struct的uordblks字段。

請注意,這不是標准的POSIX函數,但我想這就是你對非標准內省的預期......

存儲塊的大小通常存儲在指針的正下方。 雖然這是一個黑客(你說我可以......),但我的Linux機器上運行以下代碼:

#include <stdio.h>
#include <stdlib.h>

int main(){
int *p, n=123;
p = (int*)malloc(n*sizeof(int));
printf("allocated %d bytes for p\n", n*sizeof(int));
printf("p[-2] : %d \n", *(p-2));
printf("malloc_useable_size(p) : %d\n", malloc_usable_size(p));
free(p);
}

它產生的輸出是這樣的:

allocated 492 bytes to p
p[-2] : 513
malloc_useable_size(p): 504

請注意,p [-2]中的大小並不完全是492 - 由於內務和邊界對齊等原因,還有一些額外的空間用完了。

還要注意 - 這適用於gcc編譯器; 但是g++抱怨指針轉換,而且我沒有聲明malloc_useable_size() 在看到@ fanl的回答后,我出於好奇而添加了這一行。 在看到mallinfo的答案之后,我還在mallinfo的輸出中mallinfo了一下。

你可以改變n的值,你會發現事情非常吻合 - 例如,如果你從n(在我的上面的代碼中)從100到119步,那么感興趣的不同變量的值如下:

  n | p[-2] | usable | uordblks
----+-------+--------+---------
100    417     408       416
101    417     408       416
102    417     408       416
103    433     424       432
104    433     424       432
105    433     424       432
106    433     424       432
107    449     440       448
108    449     440       448
109    449     440       448 
110    449     440       448
111    465     456       464   
112    465     456       464
113    465     456       464
114    465     456       464
115    481     472       480
116    481     472       480
117    481     472       480
118    481     472       480
119    497     488       496 

usablep[-2]之間總是有9的差異, p[-2]uordblks之間的差異總是1 p[-2]方法的優點是它可以准確地告訴您所要求的內容 - 指針的大小。 其他電話可能實際上告訴你你真正想要的是什么......

PS很可能對於非常大的內存塊,你需要查看生成*((long int*)(p)-1)long integer 這給了我一個漂亮的宏的靈感:

#define PSIZE(a) (*((long int*)(a)-1))

然后你可以找出任何指針的大小

printf("my pointer size is %ld\n", PSIZE(myPointer));

無需擔心指針的類型。 我確認這適用於不同類型的指針,以及塊> 4G。 顯然你可以決定在宏中減去1,這樣數字就與mallinfo()完全一致。

編輯:在此前一個問題的答案中給出了對指針下方存儲內容的更完整描述。 這表明我觀察到的“+1”實際上是由於存儲在LSB中的標志。 正確的方法是將結果與~3一起清除兩個LSB,然后從結果中減去(long int *)的大小(實際上原始答案減去2 * sizeof(unsigned long int)但我認為是錯誤):

#define PSIZE(a) ((*((long int*)(a)-1))&~3 - sizeof(long int*))

鏈接的答案強烈建議僅將其用於調試,而不是將其用於實際代碼。 我不得不重復這一警告。

您需要在malloc中安裝一個鈎子來構建一個緩存所請求塊大小的指針表,然后在釋放時,在上一個malloc項目數據庫中搜索指針。

通過這種方式,您將知道減少當前分配的堆總和(如果這是您的目標),並且將有一個方便的位置來列出仍保留在內存中的堆的所有“區域”。

暫無
暫無

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

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