OpenSSL學習筆記 記憶體分配

2021-05-22 09:50:09 字數 4296 閱讀 3746

//申請記憶體的執行緒號

const char *file;//申請記憶體的檔名

int line;//申請記憶體的行號

/* tail of thread's stack */

int references;//被引用的次數

這個結構體是用來記錄使用者申請的記憶體資訊的。

typedef struct mem_st

mem;

這個結構是用來描述記憶體塊的,使用者每使用openssl_malloc成功申請一次記憶體,就會產生乙個這樣的結構體,並把這個結構體存入雜湊表mh中。

下面,我想從兩個函式(openssl_malloc和openssl_free)來說明openssl在記憶體管理方面是怎麼做的,其實openssl 只是給我們常用的malloc和free加了乙個外殼,這使得使用者在申請記憶體時,它可以把使用者的資訊記錄下來並存入乙個雜湊表中。

函式openssl_maloc

函式openssl_malloc是openssl中在申請記憶體時,用來代替malloc的。其實,openssl_malloc是乙個巨集定義,定義在檔案/cypto/crypto.h中:

#define openssl_malloc(num)    crypto_malloc((int)num,__file__,__line__)

從這裡,很明顯可以看出,當我們呼叫openssl_malloc時,openssl可以通過巨集__file__和__line__很方便地把檔名和 行號錄下來。那麼,函式crypto_malloc又是什麼呢?它是乙個函式,定義在檔案/crypto/mem.c中:

void *crypto_malloc(int num, const char *file, int line)

ret = malloc_ex_func(num,file,line);  

//其實記憶體就是在這一句被分配的

#ifdef levitte_debug_mem

fprintf(stderr, "levitte_debug_mem:         > 0x%p (%d)/n", ret, num);

#endif

if (malloc_debug_func != null)

malloc_debug_func(ret, num, file, line, 1);

/* create a dependency on the value of 'cleanse_ctr' so our memory

* sanitisation function can't be optimised out. nb: we only do

* this for >2kb so the overhead doesn't bother us. */

if(ret && (num > 2048))

((unsigned char *)ret)[0] = cleanse_ctr;

return ret;

}從上的函式,我們可以看出記憶體分配是通過malloc_ex_func完成的,在這個函式的上下方,分別呼叫了兩次malloc_debug_func。

我們先說malloc_ex_func,它是乙個函式指標,它的定義在檔案/crypto/mem.c中:

static void *(*malloc_func)(size_t)         = malloc;

static void *default_malloc_ex(size_t num, const char *file, int line)

static void *(*malloc_ex_func)(size_t, const char *file, int line)

= default_malloc_ex;

其實,函式malloc_ex_func就是malloc。

我們再來看函式,malloc_debug_func,它也是乙個函式指標,它的定義在檔案/crypto/mem.c中:

static void (*malloc_debug_func)(void *,int,const char *,int,int) = null;//把使用者申請記憶體的資訊存入結構體m中

m->addr=addr;

m->file=file;

m->line=line;

m->num=num;

if (options & v_crypto_mdebug_thread)

m->thread=crypto_thread_id();

else

m->thread=0;

if (order == break_order_num)

if ((mm=(mem *)lh_insert(mh,(char *)m)) != null)

break;

}return;

}看完上面的**,應該不難理解函式openssl_malloc的執行過程了,通過函式malloc_ex_func(也就是malloc)分配記憶體,通過函式crypto_malloc_dbg把使用者申請記憶體的資訊存入雜湊表mh中。

函式openssl_free

函式openssl_free是openssl在釋放記憶體時,用來代替free的。openssl_free是乙個巨集定義,定義在檔案/crypto/crypto.h中:

#define openssl_free(addr)    crypto_free(addr)

我們再來看一下函式crypto_free,實現在檔案/crypto/mem.c中:

void crypto_free(void *str)

這裡,我們可以看到函式crypto_free和函式crypto_malloc的結構幾乎是一樣的。變數free_debug_func和變數free_func是兩個函式指標,定義在檔案/crypto/mem.c中:

static void (*free_func)(void *)            = free;

static void (*free_debug_func)(void *,int) = null;

從函式crypto_malloc_debug_init和函式crypto_set_mem_debug_functions中可以看出,變數 free_debug_func的值應該為crypto_dbg_free,這個函式的定義在檔案/crypto/mem_dbg.c中:

void crypto_dbg_free(void *addr, int before_p)

break;

case 1:

break;}}

所以,當我們呼叫openssl_malloc申請記憶體,而沒有呼叫openssl_free釋放記憶體時,我們只需要遍歷雜湊表mh,就可以知道哪些記憶體還沒有被釋放。

用於輸出記憶體洩露資訊的函式,我們可以使用crypto_mem_leaks,這個函式把記憶體洩露的資訊輸出到乙個bio。

下面,我們來看一下openssl一些常用的記憶體管理的函式:

1. #define openssl_malloc(num)  crypto_malloc((int)num,__file__,__line__)

2. #define openssl_strdup(str)  crypto_strdup((str),__file__,__line__)

char *crypto_strdup(const char *str, const char *file, int line)

3. #define openssl_realloc(addr,num)  crypto_realloc((char *)addr,(int)num,__file__,__line__)

此函式用法與realoc相同。

4. #define openssl_free(addr)    crypto_free(addr)

5. void crypto_mem_leaks_fp(file *fp);

此函式的作用是把記憶體洩露資訊輸出到檔案fp,這個函式是通過crypto_mem_leaks實現的。

6. void crypto_mem_leaks(struct bio_st *bio);

此函式的作用是把記憶體洩露資訊輸出到bio。

7. void crypto_malloc_debug_init(void);

C 學習筆記之記憶體分配

靜態記憶體 staitc memory 儲存區域性static物件 類static資料成員 定義在任何函式之外的變數 棧記憶體 stack 儲存定義在函式內的非static物件 自由空間 free store 或稱堆記憶體 heap 儲存動態分配 即程式執行時分配 的物件 1.分配在靜態記憶體和棧記...

記憶體分配學習

1.儲存類別 被儲存的每個值都占用一更的物理記憶體,c語言把這樣的一塊記憶體叫做物件。乙個物件可以儲存乙個或多個值。乙個物件可能未存實際的值,但是在儲存適當的值時一定具有相應的大小。可以用儲存期來描述物件,用識別符號訪問物件。用作用於和鏈結藐視識別符號。1.1作用域 作用域描述程式中可訪問識別符號的...

動態分配記憶體(學習筆記11)

函式原型 stdlib.h void malloc size 分配size大小的記憶體,返回指向所分配記憶體的指標,分配不成功,返回null void calloc num element,length of element 分配num element length of element 大小的記憶...