Liteos中查看内存分配的调用栈
·
Liteos中查看内存分配的调用栈
在liteos中内存分配主要是los_memory.c提供的相关方法,当设备内存有限时,内存资源紧张,需要对系统中申请内存的位置进行分析,可通过下面的步骤进行
1. 在函数开头获取调用者地址
由于嵌入式环境通常不支持完整的 backtrace(),可采用 GCC 内建函数 __builtin_return_address(n) 获取直接调用者(最常用)或上层调用者。
STATIC INLINE VOID *OsMemAlloc(struct OsMemPoolHead *pool, UINT32 size, UINT32 intSave)
{
// >>> 新增:获取直接调用者地址(即谁调用了 OsMemAlloc)
UINTPTR caller = (UINTPTR)__builtin_return_address(0);
// <<<
}
说明:
- __builtin_return_address(0) 返回 直接调用者 的返回地址(即 OsMemAlloc 被调用后要返回的位置);
- 在 ARM Cortex-M 等架构下,这通常是调用指令(如 BL)的下一条指令地址;
- 需确保编译器未优化掉帧指针(建议调试时使用 -O0 或 -fno-omit-frame-pointer)。
2. 在分配成功后打印带 caller 的日志
STATIC INLINE VOID *OsMemAlloc(struct OsMemPoolHead *pool, UINT32 size, UINT32 intSave)
{
// >>> 新增:获取直接调用者地址(即谁调用了 OsMemAlloc)
UINTPTR caller = (UINTPTR)__builtin_return_address(0);
// <<<
// 内存分配等操作
// >>> 新增:打印带 caller 的日志
PRINTK("0xc00 OsMemAlloc Caller: 0x%lx\n", (unsigned long)caller);
// <<<
}
输出日志如下:
0xc00 OsMemAlloc Caller: 0x0800c3a2
提示:
- 使用 0x%lx 打印 UINTPTR 类型(兼容 32/64 位);
- 日志前缀 0xc00 可保留,便于过滤。
将Caller地址转为函数名和位置
使用交叉编译工具链中的 addr2line和变异产物中的.elf文件
shell>riscv-none-embed-addr2line.exe -e LiteOS_m.elf -f -C 0xbd4c
OsQueueCreate
xxx/../kernel_liteos_m/kernel/src/los_queue.c:171
__builtin_return_address可传入其他的数字,表示获取更上层调用者,但可靠性随 n 增大急剧下降。
更多推荐


所有评论(0)