内存分配
openssl提供了自己的分配函数,如果你使用openssl的分配函数,当忘记释放的话,可以通过一些方法知道哪些内存泄露了
也可以自定义个自己的内存管理函数,openssl也定义了相关接口
openssl的内存管理函数
# define OPENSSL_malloc(num) \
CRYPTO_malloc(num, OPENSSL_FILE, OPENSSL_LINE)
# define OPENSSL_zalloc(num) \
CRYPTO_zalloc(num, OPENSSL_FILE, OPENSSL_LINE)
# define OPENSSL_realloc(addr, num) \
CRYPTO_realloc(addr, num, OPENSSL_FILE, OPENSSL_LINE)
# define OPENSSL_clear_realloc(addr, old_num, num) \
CRYPTO_clear_realloc(addr, old_num, num, OPENSSL_FILE, OPENSSL_LINE)
# define OPENSSL_clear_free(addr, num) \
CRYPTO_clear_free(addr, num, OPENSSL_FILE, OPENSSL_LINE)
# define OPENSSL_free(addr) \
CRYPTO_free(addr, OPENSSL_FILE, OPENSSL_LINE)
自定义内存管理函数接口
int CRYPTO_set_mem_functions(
void *(*m)(size_t, const char *, int),
void *(*r)(void *, size_t, const char *, int),
void (*f)(void *, const char *, int))
{
if (!allow_customize)
return 0;
if (m)
malloc_impl = m;
if (r)
realloc_impl = r;
if (f)
free_impl = f;
return 1;
}
内存泄露检查
- 执行config时需要加上enable-crypto-mdebug,这样才能打开相关的宏
- CRYPTO_set_mem_debug(1); 打开debug开关
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); //打开内存泄露检查开关
- 使用openssl提供的内存管理函数
- 处理内存泄露问题
- 调用CRYPTO_mem_leaks(bio)将内存泄露输出到文件。
- 或者调用int CRYPTO_mem_leaks_cb(int (*cb) (const char *str, size_t len, void *u),
void *u)此回调函数处理内存泄露问题。
例子程序
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/bio.h>
int main()
{
char *a = (char *)OPENSSL_malloc(4);
memset(a, 0, sizeof(a));
strcpy(a, "ab");
char *b = (char *)OPENSSL_realloc(a, 10); //会释放之前的空间,然后把之前的数据拷贝到新空间
printf("%s\n", b);
char *c = (char *)OPENSSL_clear_realloc(b, 10, 100); //分配100个字节,把之前分配的10字节置乱,虽然释放了,但是数据还存在在内存上,把他们置乱
OPENSSL_free(c);
CRYPTO_set_mem_debug(1); //打开debug开关
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); //打开开关
void *w = OPENSSL_malloc(10);
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF); //只记录上面的这次分配
BIO *bio = BIO_new_file("a.txt", "w");
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
// 默认编译会有这个宏OPENSSL_NO_CRYPTO_MDEBUG,导致无法测试,需要在config的时候加上enable-crypto-mdebug
// CRYPTO_mem_leaks(bio);
OPENSSL_free(w);
BIO_free(bio);
}