• OpenSSL 内存管理分析笔记


    面向开发者使用的最外层接口:

    OPENSSL_malloc(num)

    <===> CRYPTO_malloc((int)num,__FILE__,__LINE__)

    OPENSSL_realloc(addr,num)

    <===> CRYPTO_realloc((char *)addr, (int)num__FILE____LINE__)

    OPENSSL_realloc_clean(addr,old_num,num)

    <===> CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__)

    OPENSSL_remalloc(addr,num)

    <===> CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__)

    OPENSSL_free(addr)

    <===> CRYPTO_free(addr)

    OPENSSL_malloc_locked(num)

    <===> CRYPTO_malloc_locked((int)num,__FILE__,__LINE__)

    OPENSSL_free_locked(addr)

    <===> CRYPTO_free_locked(addr)

    CRYPTO_XXXX Crypto.h中声明, Mem.c来实现。Mem.c中,使用了两类内存申请函数,

    一类为直接调用mallocdefault_XXXXX), 一类为调用Mem_dbg.c中的dbg版本的函数(CRYPTO_dbg_XXXX)

    ================================================================================

    malloc_func, malloc_ex_func, realloc_func, realloc_ex_func, free_func

    malloc_locked_func, malloc_locked_ex_funcmalloc_debug_funcrealloc_debug_func

    free_debug_funcset_debug_options_funcget_debug_options_func

    这些函数由,CRYPTO_XXXX 来调用(其内部首先判断Debug版本的是否为NULL,如果不为NULL

    则调用Debug版本的,否则调用非Debug版本的。Debug版本的调用比较特殊,会调用两次。

    0: called before the actual memory allocation has taken place

    1: called after the actual memory allocation has taken place

    ================================================================================

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

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

    { return malloc_func(num); }

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

    = default_malloc_ex;

    static void *(*realloc_func)(void *, size_t)= realloc;

    static void *default_realloc_ex(void *str, size_t num,

    const char *file, int line)

    { return realloc_func(str,num); }

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

    = default_realloc_ex;

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

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

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

    { return malloc_locked_func(num); }

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

    = default_malloc_locked_ex;

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

    ================================================================================

    #ifdef CRYPTO_MDEBUG

    /* use default functions from mem_dbg.c */

    static void (*malloc_debug_func)(void *,int,const char *,int,int)

    = CRYPTO_dbg_malloc;

    static void (*realloc_debug_func)(void *,void *,int,const char *,int,int)

    = CRYPTO_dbg_realloc;

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

    static void (*set_debug_options_func)(long) = CRYPTO_dbg_set_options;

    static long (*get_debug_options_func)(void) = CRYPTO_dbg_get_options;

    #else

    /* applications can use CRYPTO_malloc_debug_init() to select above case

    * at run-time */

    static void (*malloc_debug_func)(void *,int,const char *,int,int) = NULL;

    static void (*realloc_debug_func)(void *,void *,int,const char *,int,int)

    = NULL;

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

    static void (*set_debug_options_func)(long) = NULL;

    static long (*get_debug_options_func)(void) = NULL;

    #endif

    ================================================================================

    如何使用(使用最外层函数,也就俗称的接口,这里成为Openssl API):

    1. 初始化

    #define CRYPTO_malloc_init() CRYPTO_set_mem_functions(malloc, realloc, free)

    如果编译Openssl的时候定义了CRYPTO_MDEBUG  CRYPTO_MDEBUG_ALL

     CRYPTO_MDEBUG_TIME  CRYPTO_MDEBUG_THREAD,则此函数无需调用,默认是被设置好的。详情见Mem.c

    #define CRYPTO_malloc_debug_init() do {

    CRYPTO_set_mem_debug_functions(

    CRYPTO_dbg_malloc,

    CRYPTO_dbg_realloc,

    CRYPTO_dbg_free,

    CRYPTO_dbg_set_options,

    CRYPTO_dbg_get_options);

    } while(0)

    2. 配置选项

    /* Adds time to the memory checking information */

    #define V_CRYPTO_MDEBUG_TIME 0x1

    /* Adds thread number to the memory checking information */

    #define V_CRYPTO_MDEBUG_THREAD 0x2

    #define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD)

    // 设置显示信息,显示时间和Thread ID

    CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);

        /* for applications */

    #define CRYPTO_MEM_CHECK_OFF 0x0

    #define CRYPTO_MEM_CHECK_ON 0x1

    /* for libs*/

    #define CRYPTO_MEM_CHECK_ENABLE 0x2

    #define CRYPTO_MEM_CHECK_DISABLE 0x3

    // 可以直接调用这个,也可以调用底下的接口函数

    int CRYPTO_mem_ctrl(int mode);

    int CRYPTO_is_mem_check_on(void);

    /* for applications */

    #define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON)

    #define MemCheck_stop() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF)

    /* for library-internal use */

    #define MemCheck_on() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE)

    #define MemCheck_off() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE)

    #define is_MemCheck_on() CRYPTO_is_mem_check_on()

    3. 使用最外层接口

    OPENSSL_malloc(num)

    OPENSSL_realloc(addr,num)

    OPENSSL_realloc_clean(addr,old_num,num)

    OPENSSL_remalloc(addr,num)

    OPENSSL_free(addr)

    OPENSSL_malloc_locked(num)

    OPENSSL_free_locked(addr)

    示例:

    int main()

    {

    char *= NULL;

    BIO *= NULL;

    CRYPTO_malloc_debug_init();

    CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);

    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

    = (char*)OPENSSL_malloc(4);

    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);

    = 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;

    }

    所以,提取OpenSSL中部分代码,只需要重新定义OPENSSL_XXXX这几个宏即可。

  • 相关阅读:
    别再重复造轮子了,利用list创建任意数据类型的链表
    可配置内存池实现
    简单内存池实现
    基于本博客版本中的循环缓冲的测试(Linux环境)
    循环缓冲实现(ring buffer/circular buffer)
    recvfrom超时设置
    Linux系统如何做性能测试?
    深入理解虚拟内存机制
    Linux 内核的测试和调试
    python学习之路 实现简单的计算机功能。
  • 原文地址:https://www.cnblogs.com/yestreen/p/3206554.html
Copyright © 2020-2023  润新知