Linux下用内存管理器的钩子函数跟踪内存泄漏(2)

memory_trace_restore();
    memory_trace_write(0, ptr, 0);
    result = realloc(ptr, size);
    memory_trace_write(1, result, size);
    memory_trace_hook();

return result;
}

static void memory_trace_flush_one_entry(int index)
...{
    int offset = 0;
    char buffer[512] = ...{0};
    int fd = fileno(g_memory_trace_fp);
    int alloc  = (int)g_memory_trace_cache[index][BACK_TRACE_DEPTH];
    void* addr = g_memory_trace_cache[index][BACK_TRACE_DEPTH+1];
    int size   = (int)g_memory_trace_cache[index][BACK_TRACE_DEPTH+2];
    void** backtrace_buffer = g_memory_trace_cache[index];

snprintf(buffer, sizeof(buffer), "%s %p %d ", alloc ? "alloc":"free", addr, size);
    if(!alloc)
    ...{
        write(fd, buffer, strlen(buffer));
        return;
    }
   
    char** symbols = backtrace_symbols(backtrace_buffer, BACK_TRACE_DEPTH);
    if(symbols != NULL)
    ...{
        int i = 0;
        offset = strlen(buffer);
        for(i = 0; i < BACK_TRACE_DEPTH; i++)
        ...{
            if(symbols[i] == NULL)
            ...{
                break;
            }
            char* begin = strchr(symbols[i], '(');
            if(begin != NULL)
            ...{
                *begin = ' ';
                char* end = strchr(begin, ')');
                if(end != NULL)
                ...{
                    strcpy(end, " ");
                }
                strncpy(buffer+offset, begin, sizeof(buffer)-offset);
                offset += strlen(begin);
            }
        }
        write(fd, buffer, offset);
        free(symbols);
    }

return;
}

static void memory_trace_flush(void)
...{
    int i = 0;
    for(i = 0; i < g_memory_trace_cache_used; i++)
    ...{
        memory_trace_flush_one_entry(i);
    }
    g_memory_trace_cache_used = 0;

return;
}

static void memory_trace_write(int alloc, void* addr, int size)
...{
    if(g_memory_trace_cache_used >= CACHE_SIZE)
    ...{
        memory_trace_flush();
    }

int i = 0;
    void* backtrace_buffer[BACK_TRACE_DEPTH] = ...{0};
    backtrace(backtrace_buffer, BACK_TRACE_DEPTH);

for(i = 0; i < BACK_TRACE_DEPTH; i++)
    ...{
        g_memory_trace_cache[g_memory_trace_cache_used][i] = backtrace_buffer[i];
    }
    g_memory_trace_cache[g_memory_trace_cache_used][BACK_TRACE_DEPTH] = (void*)alloc;
    g_memory_trace_cache[g_memory_trace_cache_used][BACK_TRACE_DEPTH+1] = addr;
    g_memory_trace_cache[g_memory_trace_cache_used][BACK_TRACE_DEPTH+2] = (void*)size;

g_memory_trace_cache_used++;

return;
}

#ifdef MEMORY_TRACE_TEST
void test(void)
...{
    char* p = malloc(100);
    p = malloc(123);

free(p);

return;
}
int main(int argc, char* argv[])
...{
    malloc(100);
    test();
    malloc(100);
    test();
    char* p = malloc(100);
    free(p);
   
    return 0;
}
#endif/*MEMORY_TRACE_TEST*/

把以上代码编译成动态库,或者直接编译到功能代码一起。如果设置了MALLOC_TRACE环境变量,分配/释放会被记录到/tmp/$PID_memory.log下。

再写个程序来分析log文件:
/**//*mtrace.c*/
#include <stdio.h>

#define MAX_ENTRY 1024*1024

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwpjdd.html