MallocMonitor 使用指南
概述
MallocMonitor 是一个运行时内存调试工具,用于检测 C/C++ 程序中的内存泄漏和缓冲区溢出问题。它无需修改源代码即可透明运行。
主要特性
| 特性 | 说明 |
|---|---|
| 内存泄漏检测 | 跟踪所有内存分配,识别未释放的内存 |
| 缓冲区溢出检测 | 检测内存写入越界违规 |
| 调用栈记录 | 在分配时捕获调用栈,便于调试定位 |
| 零代码修改 | 通过链接器符号包装实现,无需修改源码 |
| C/C++ 支持 | 完全兼容 C 和 C++ 程序 |
源码位置
platform/allwinner/eyesee-mpp/middleware/{chip}/MallocMonitor
技术原理
GCC 符号包装机制
MallocMonitor 利用 GCC 的 --wrap 链接器特性来拦截内存分配函数。该机制在链接阶段将标准内存函数替换为包装版本:
+------------------+ +------------------+ +------------------+
| Application | | Linker | | MallocMonitor |
| | | --wrap flag | | |
| malloc() ----->|-------->| Redirects to -->|-------->| __wrap_malloc() |
| free() ----->| | __wrap_xxx() -->|-------->| __wrap_free() |
| realloc() ----->| | | | __wrap_realloc()|
| calloc() ----->| +------------------+ +------------------+
+------------------+
整体架构图
MallocMonitor Architecture
┌──────────────────────────────────────────────────────────────────────────────┐
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ Application Layer │ │
│ │ │ │
│ │ malloc() ──┐ │ │
│ │ free() ──┼──► Standard Memory API Calls │ │
│ │ realloc() ─┤ │ │
│ │ calloc() ──┘ │ │
│ └──────────────────────── ────────┬───────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ MallocMonitor Layer │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐ │ │
│ │ │ __wrap_malloc │ │ __wrap_free │ │ __wrap_realloc/calloc │ │ │
│ │ └────────┬────────┘ └────────┬────────┘ └───────────┬─────────────┘ │ │
│ │ │ │ │ │ │
│ │ ▼ ▼ ▼ │ │
│ │ ┌─────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Memory Tracking List │ │ │
│ │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │
│ │ │ │ Node 1 │───►│ Node 2 │───►│ Node N │ │ │ │
│ │ │ │ • address │ │ • address │ │ • address │ │ │ │
│ │ │ │ • size │ │ • size │ │ • size │ │ │ │
│ │ │ │ • callstack│ │ • callstack│ │ • callstack│ │ │ │
│ │ │ └───────────┘ └───────────┘ └───────────┘ │ │ │
│ │ └─────────────────────────────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ System Layer │ │
│ │ Real malloc/free Implementation │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────┘
内存分配流程
Memory Allocation Flow
│
▼
┌─────────────────────────┐
│ Application calls │
│ malloc(size) │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ __wrap_malloc() │
│ intercepts the call │
└───────────┬─────────────┘
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────────┐
│ Call real │ │ Capture │ │ Create tracking│
│ malloc() │ │ call stack │ │ node │
└────────────┘ └────────────┘ └───────┬────────┘
│
▼
┌─────────────────────────┐
│ Store in tracking list: │
│ • Memory address │
│ • Allocation size │
│ • Call stack trace │
└───────────┬────── ───────┘
│
▼
┌─────────────────────────┐
│ Return pointer to │
│ application │
└─────────────────────────┘
内存释放流程
Memory Deallocation Flow
│
▼
┌─────────────────────────┐
│ Application calls │
│ free(ptr) │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐
│ __wrap_free() │
│ intercepts the call │
└───────────┬─────────────┘
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌────────────┐ ┌────────────────┐ ┌────────────┐
│ Find node │ │ Check for │ │ Report │
│ in list │ │ buffer overflow│ │ if overflow│
└────────────┘ └────────────────┘ └────────────┘
│
▼
┌────────────────────┐
│ Remove tracking │
│ node from list │
└─────────┬──────────┘
│
▼
┌────────────────────┐
│ Call real free() │
└────────────────────┘
API 参考
函数概览
| 函数 | 说明 |
|---|---|
ShowMallocStatistics() | 打印内存总体统计信息 |
ShowUnreleasedMemoryInfo() | 查看并打印当前未释放内 存的信息,包括分配时的调用栈 |
CheckMemoryOverflow() | 查看当前存在内存写越界的内存节点信息 |
StartOverflowReportThread() | 启动检测线程,周期性检查溢出 |
StopOverflowReportThread() | 关闭检测线程 |
详细 API 说明
1. ShowMallocStatistics()
void ShowMallocStatistics(void);
功能:打印内存分配统计摘要,包括总分配次数、释放次数和当前内存使用情况。
使用示例:
// 在程序任意位置检查内存统计
ShowMallocStatistics();
2. ShowUnreleasedMemoryInfo()
void ShowUnreleasedMemoryInfo(void);
功能:列出所有已分配但未释放的内存块,显示每个内存块的地址、大小和分配时的完整调用栈。
使用示例:
// 程序退出或检查点时调用
ShowUnreleasedMemoryInfo();
3. CheckMemoryOverflow()
void CheckMemoryOverflow(void);
功能:扫描所有跟踪的内存块,检测缓冲区溢出违规。发现溢出时报告内存地址、大小和分配调用栈。
使用示例:
// 周期性检查溢出
CheckMemoryOverflow();
4. StartOverflowReportThread()
int StartOverflowReportThread(int nIntervalMs);
功能:启动后台线程,自动周期性检查内存溢出。
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
nIntervalMs | int | 检查间隔,单位毫秒 |
返回值:成功返回 0,失败返回非零值
使用示例:
// 每 5 秒检查一次溢出
StartOverflowReportThread(5000);
5. StopOverflowReportThread()
int StopOverflowReportThread(void);
功能:停止后台溢出检查线程。
返回值:成功返回 0,失败返回非零值