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内存分配,查看内存泄露的更多相关文章

  1. C++ 动态分配 和 内存分配和内存释放

    动态分配 动态分配可以说是指针的关键所在.不需要通过定义变量,就可以将指针指向分配的内存.也许这个概念看起来比较模糊,但是确实比较简单.下面的代码示范如何为一个整数分配内存: int *pNumber ...

  2. 鸿蒙内核源码分析(内存分配篇) | 内存有哪些分配方式  | 百篇博客分析OpenHarmony源码 | v11.02

    百篇博客系列篇.本篇为: v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有哪些分配方式 | 51.c.h .o 内存管理相关篇为: v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有哪些 ...

  3. Android 之 内存管理-查看内存泄露(三)

    概述 在android的开发中,要时刻主要内存的分配和垃圾回收,因为系统为每一个dalvik虚拟机分配的内存是有限的,在google的G1中,分配的最大堆大小只有16M,后来的机器一般都为24M,实在 ...

  4. C:内存分配、内存中五大区

     1.内存的划分  (从高到低依次是: 栈区 . 堆区 .全局静态区 . 常量区 . 代码区 )栈区是系统自动回收,堆区是我们手动回收  2. 栈区   在函数内部定义的局部变量和数组.都存放在栈区, ...

  5. linux 清理内存命令 查看内存命令

    查看内存: 我们可以用free命令查看内存信息: free -g total used free shared buffers cachedMem: 15   15    0     0       ...

  6. Java内存分配和内存管理

    首先是概念层面的几个问题: Java中运行时内存结构有哪几种? Java中为什么要设计堆栈分离? Java多线程中是如何实现数据共享的? Java反射的基础是什么? 然后是运用层面: 引用类型变量和对 ...

  7. linux 释放内存及查看内存命令

    查看内存使用情况: free -m 清理内存: echo 1 > /proc/sys/vm/drop_caches 再次查看内存使用情况 free -m 查看内存条数命令: dmidecode  ...

  8. Android中如何查看内存

    文章参照自:http://stackoverflow.com/questions/2298208/how-to-discover-memory-usage-of-my-application-in-a ...

  9. Android中如何查看内存(上)

    文章参照自:http://stackoverflow.com/questions/2298208/how-to-discover-memory-usage-of-my-application-in-a ...

  10. Android 查看内存

    文章参照自:http://stackoverflow.com/questions/2298208/how-to-discover-memory-usage-of-my-application-in-a ...

随机推荐

  1. git 知识罗列

    git pull is basically a shortcut for two operations: git fetch which downloads the history from the ...

  2. 84.常用的返回QuerySet对象的方法使用详解:select_related, prefetch_related

    1.select_related: 只能用在一对多或者是一对一的关联模型之间,不能用在多对多或者是多对一的关联模型间,比如可以提前获取文章的作者,但是不能通过作者获取作者的文章,或者是通过某篇文章获取 ...

  3. delphi数据类型列表

    Delphi 数据类型列表 分类 范围 字节 备注 简单类型 序数 整数 Integer -2147483648 .. 2147483647 4 有符号32位 Cardinal 0 .. 429496 ...

  4. 绩效软件交流-ZQDJ

    积分制(主管激励下属)短期任务积分 长期任务积分 制度积分 固定积分任务工作项 评估表 ,取中间值工时调整 工作表现 创新加分 难度加分 贡献加分 绩效分-积分(软件亮点)  分开做 没有管理员的中层 ...

  5. 京东云数据库 RDS助力企业便捷运维

    iPhone6发布那年,京东在国贸等商圈送货最快速度数分钟,包括从下单到送达.这是一个极端的富含营销因素例子.即便如此,常态来看,隔天到货的这种业务模式,也是基于同样的支撑:营销业务.物流业务,大数据 ...

  6. MyBatis从入门到精通(第9章):Spring集成MyBatis(中)

    MyBatis从入门到精通(第9章):Spring集成MyBatis(中) 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法.应该将应用自身的设计和具体 ...

  7. [原]排错实战——使用process explorer替换任务管理器

    原Aha总结注册表process explorersysinternalsprocess monitor 前言 一般,我们会使用任务管理器查看系统中有哪些进程正在运行,强制杀掉某个进程.可是系统自带的 ...

  8. [原]调试实战——程序CPU占用率飙升,你知道如何快速定位吗?

    原调试debugwindbghangprocess explorer 前言 如果我们自己的程序的CPU Usage(CPU占用率)飙升,并且居高不下,很有可能陷入了死循环.你知道怎么快速定位并解决吗? ...

  9. Linux进程的引入

    1.什么是进程? (1).进程是一个动态过程而不是静态实物 (2).进程就是程序的一次运行过程,一个静态的可执行程序a.out的一次运行过程(./a.out从运行到结束)就是一个进程. (3).进程控 ...

  10. LeetCode——376.摆动序列

    如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列.第一个差(如果存在的话)可能是正数或负数.少于两个元素的序列也是摆动序列. 例如, [1,7,4,9,2,5] 是一个摆动序列, ...