openssl内存分配,查看内存泄露
openssl内存分配
用户在使用内存时,容易犯的错误就是内存泄露。当用户调用内存分配和释放函数时,查找内存泄露比较麻烦。openssl提供了内置的内存分配/释放函数。如果用户完全调用openssl的内存分配和释放函数,可以方便的找到内存泄露点。openssl分配内存时,在其内部维护一个内存分配哈希表,用于存放已经分配但未释放的内存信息。当用户申请内存分配时,在哈希表中添加此项信息,内存释放时删除该信息。当用户通过openssl函数查找内存泄露点时,只需查询该哈希表即可。用户通过openssl回调函数还能处理那些泄露的内存。
openssl供用户调用的内存分配等函数主要在crypto/mem.c中实现,其内置的分配函数在crypto/mem_dbg.c中实现。默认情况下mem.c中的函数调用mem_dbg.c中的实现。如果用户实现了自己的内存分配函数以及查找内存泄露的函数,可以通过调用CRYPTO_set_mem_functions函数和CRYPTO_set_mem_debug_functions函数来设置。下面主要介绍了openssl内置的内存分配和释放函数。
5.2 内存数据结构
openssl内存分配数据结构是一个内部数据结构,定义在crypto/mem_dbg.c中。如下所示:
typedef struct app_mem_info_st
{
unsigned long thread;
const char *file;
int line;
const char *info;
struct app_mem_info_st *next; /* tail of thread's stack */
int references;
} APP_INFO;
typedef struct mem_st
{
void *addr;
int num;
const char *file;
int line;
unsigned long thread;
unsigned long order;
time_t time;
APP_INFO *app_info;
} MEM;
各项意义:
addr:分配内存的地址。
num:分配内存的大小。
file:分配内存的文件。
line:分配内存的行号。
thread:分配内存的线程ID。
order:第几次内存分配。
time:内存分配时间。
app_info:用于存放用户应用信息,为一个链表,里面存放了文件、行号以及线程ID等信息。
references:被引用次数。
5.3 主要函数
1) CRYPTO_mem_ctrl
本函数主要用于控制内存分配时,是否记录内存信息。如果不记录内存信息,将不能查找内存泄露。开启内存记录调用CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON),关闭内存记录调用CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF)。一旦CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON)被调用,直到用户调用CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF)前,用户 所有的opessl内存分配都会被记录。
2) CRYPTO_is_mem_check_on
查询内存记录标记是否开启。
3) CRYPTO_dbg_malloc
本函数用于分配内存空间,如果内存记录标记开启,则记录用户申请的内存。当需要记录内存信息时,该函数本身也需要申请内存插入哈希表,为了防止递归申请错误,它申请内存记录信息前必须暂时关闭内存记录标记,申请完毕再放开。
4) CRYPTO_dbg_free
释放内存,如果内存记录标记开启,还需要删除哈希表中对应的记录。
5) CRYPTO_mem_leaks
将内存泄露输出到BIO中。
6) CRYPTO_mem_leaks_fp
将内存泄露输出到FILE中(文件或者标准输出),该函数调用了CRYPTO_mem_leaks。
7) CRYPTO_mem_leaks_cb
处理内存泄露,输入参数为用户自己实现的处理内存泄露的函数地址。该函数只需要处理一个内存泄露,openssl通过lh_doall_arg调用用户函数来处理所有记录(泄露的内存)。
5.4 编程示例
1)示例1
#include <string.h>
#include <openssl/crypto.h>
int main()
{
char *p;
int i;
p=OPENSSL_malloc(4);
p=OPENSSL_remalloc(p,40);
p=OPENSSL_realloc(p,32);
for(i=0;i<32;i++)
memset(&p[i],i,1);
/* realloc时将以前的内存区清除(置乱) */
p=OPENSSL_realloc_clean(p,32,77);
p=OPENSSL_remalloc(p,40);
OPENSSL_malloc_locked(3);
OPENSSL_free(p);
return 0;
}
上述示例使用了基本的openssl内存分配和释放函数。
OPENSSL_malloc: 分配内存空间。
OPENSSL_remalloc: 重新分配内存空间。
OPENSSL_realloc_clean: 重新分配内存空间,将老的数据进行拷贝,置乱老的数据空间并释放。
OPENSSL_malloc_locked 与锁有关。
OPENSSL_free: 释放空间。
2)示例2
include <openssl/crypto.h>
#include <openssl/bio.h>
int main()
{
char *p;
BIO *b;
CRYPTO_malloc_debug_init();
CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
p=OPENSSL_malloc(4);
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
b=BIO_new_file("leak.log","w");
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
CRYPTO_mem_leaks(b);
OPENSSL_free(p);
BIO_free(b);
return 0;
}
void InitLeaks()
{
CRYPTO_malloc_debug_init();
CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
}
void LogLeaks()
{
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
BIO *bLog=BIO_new_file("D:/leak.log","w");
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
CRYPTO_mem_leaks(bLog);
BIO_free(bLog);
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
}
From:http://i.mtime.com/chevalier/blog/1824652/
openssl内存分配,查看内存泄露的更多相关文章
- C++ 动态分配 和 内存分配和内存释放
动态分配 动态分配可以说是指针的关键所在.不需要通过定义变量,就可以将指针指向分配的内存.也许这个概念看起来比较模糊,但是确实比较简单.下面的代码示范如何为一个整数分配内存: int *pNumber ...
- 鸿蒙内核源码分析(内存分配篇) | 内存有哪些分配方式 | 百篇博客分析OpenHarmony源码 | v11.02
百篇博客系列篇.本篇为: v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有哪些分配方式 | 51.c.h .o 内存管理相关篇为: v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有哪些 ...
- Android 之 内存管理-查看内存泄露(三)
概述 在android的开发中,要时刻主要内存的分配和垃圾回收,因为系统为每一个dalvik虚拟机分配的内存是有限的,在google的G1中,分配的最大堆大小只有16M,后来的机器一般都为24M,实在 ...
- C:内存分配、内存中五大区
1.内存的划分 (从高到低依次是: 栈区 . 堆区 .全局静态区 . 常量区 . 代码区 )栈区是系统自动回收,堆区是我们手动回收 2. 栈区 在函数内部定义的局部变量和数组.都存放在栈区, ...
- linux 清理内存命令 查看内存命令
查看内存: 我们可以用free命令查看内存信息: free -g total used free shared buffers cachedMem: 15 15 0 0 ...
- Java内存分配和内存管理
首先是概念层面的几个问题: Java中运行时内存结构有哪几种? Java中为什么要设计堆栈分离? Java多线程中是如何实现数据共享的? Java反射的基础是什么? 然后是运用层面: 引用类型变量和对 ...
- linux 释放内存及查看内存命令
查看内存使用情况: free -m 清理内存: echo 1 > /proc/sys/vm/drop_caches 再次查看内存使用情况 free -m 查看内存条数命令: dmidecode ...
- Android中如何查看内存
文章参照自:http://stackoverflow.com/questions/2298208/how-to-discover-memory-usage-of-my-application-in-a ...
- Android中如何查看内存(上)
文章参照自:http://stackoverflow.com/questions/2298208/how-to-discover-memory-usage-of-my-application-in-a ...
- Android 查看内存
文章参照自:http://stackoverflow.com/questions/2298208/how-to-discover-memory-usage-of-my-application-in-a ...
随机推荐
- h5-过度
1.过度的基本介绍及写法 .div{ width: 200px; height: 200px; background-color: red; position: absolute; left: 100 ...
- Android studio个人常用快捷键
个人常用重点: 电脑模式不一样需要加上fn键进行切换 Alt+回车/Enter 导入包,实现接口的方法.自动修正 Ctrl+X 删除行 Ctrl+D 复制行 Ctrl+Shift+Space 自动补 ...
- 109.大型的csv文件的处理方式
HttpResponse对象将会将响应的数据作为一个整体返回,此时如果数据量非常大的话,长时间浏览器没有得到服务器的响应,就会超过默认的超时时间,返回超时.而StreamingHttpResponse ...
- Properties in Algebra
附录-Properties in Algebra 部分证明转载自标注,仅作个人整理查阅用. 范数 (norm) \(^{[1]}\) 要更好的理解范数,就要从函数.几何与矩阵的角度去理解,我尽量讲的通 ...
- UML-领域模型-定义
领域模型是OO分析中最重要和经典的模型(用例是重要的需求分析制品,但不是面向对象的).领域模型也是重点. 1.关系 2.例子 3.定义 领域模型没有定义方法的类图.只包括: 1).领域对象或概念类 2 ...
- 关于 TCP 和 UDP 协议
TCP\UDP 两者区别总结:https://blog.csdn.net/striveb/article/details/84063712 图解HTTP,状态码,TCP.UDP等网络协议相关总结(持续 ...
- 34)static 静态成员和静态成员函数
1) static修饰的方法,只能在这个文件中使用,比如你是多文件编程,别的文件即使引入了我的 .h文件 但那时我的static方法也是不能用 2)C++的static的成员变量 比如 sta ...
- 【ccf-csp201512-5】矩阵
click 试题编号: 201512-5 试题名称: 矩阵 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 创造一个世界只需要定义一个初状态和状态转移规则. 宏观世界的物体运动 ...
- Sex linkage
I.8 Sex linkage 单倍体:性别决定基因(S\s)和与性别决定基因连锁的等位基因(A\a)存在于同一套遗传物质上,其配子结合和减数分裂图示如下: 如果性别是由染色体区域决定的,自然选择会避 ...
- mysql 数据库保存\n 微信分享时不能换行
主要因为保存的是\n 但是查询出来是\\n 所以需要把\\n替换为\n即可(不转换的话不会换行并且显示\n)