高通Camx内存问题排查

高通Camx框架拥有庞大的代码并且各个厂商都有定制开发专有的功能,一旦遇到内存问题面对庞大的代码排查比较麻烦。本身Linux就提供了地址消毒剂的功能,可以利用其来有效定位潜在的隐患内存问题或者遇到的内存引发的崩溃,是有个利器。

一、如何开启camx地址消毒剂

这里需要配置bitbak中的poky/meta-qti-camera-prop/recipes/camx/*.bb配置,具体如下:

makefile 复制代码
# 在 camx_1.0.bb 中添加
TARGET_CFLAGS += "-fsanitize=address -fno-omit-frame-pointer"
TARGET_CXXFLAGS:append = " -fsanitize=address -fno-omit-frame-pointer"
TARGET_LDFLAGS += "-static-libsan"
# 排除不需要 ASan 的库
ASAN_EXCLUDE_LIBS = "libmmcamera libqtiutil"
INSANE_SKIP_${PN} += "ldflags"
  • -fsanitize=address:启用AddressSanitizer。
  • -fno-omit-frame-pointer:确保生成帧指针,以便获得完整的堆栈跟踪信息。
  • -static-libsan:静态链接ASan运行时库。这是关键点,因为在嵌入式设备上可能没有动态的ASan库。

⚠️这里使用-static-libsan而不是-static-libasan

二、如何配置指定程序能检测内存问题

这里需要添加指定程序的启动脚本,或者添加环境变量来启动需要指定的程序,具体如下:

bash 复制代码
#!/bin/bash
​
export ASAN_SYMBOLIZER_PATH=$(which llvm-symbolizer)
export ASAN_OPTIONS="symbolize=1:print_stacktrace=1:halt_on_error=0:abort_on_error=0"
/sbin/main [args]

三、如何让地址消毒剂能符号化

  • 这里需要代码编译支持地址消毒剂外,还需要开启编译调试模式,这里具体修改poky/meta-qti-camera-prop/recipes/camx/*.bb配置,具体修改如下:

    ini 复制代码
    INSANE_SKIP:${PN}-dbg = "arch"
    INSANE_SKIP:${PN} = "already-stripped"
    INHIBIT_PACKAGE_STRIP = "1" #添加这一行
    INHIBIT_SYSROOT_STRIP = "1"
  • 使用符号化工具llvm-symbolizer来自动解析代码的符号以及行号等信息,具体工具以及依赖库

    • llvm-symbolizer工具至/usr/bin
    • 依赖库libtinfo.so.6放至/usr/lib
  • 替换硬件平台系统的camx相关的动态库为包含调试信息的动态库

四、地址消毒剂错误类型及示例

1. 堆缓冲区溢出 (Heap-buffer-overflow)
c 复制代码
// 示例代码
int *arr = malloc(10 * sizeof(int));
arr[10] = 42; // 越界访问

ASan 报告:

arduino 复制代码
==10988==ERROR: AddressSanitizer: heap-buffer-overflow
WRITE of size 4 at 0x60200000eff4 thread T0
    #0 0x4012d6 in main program.c:5
2. 栈缓冲区溢出 (Stack-buffer-overflow)
arduino 复制代码
void func() {
    char buffer[10];
    strcpy(buffer, "This string is too long!");
}

ASan 报告:

arduino 复制代码
==10989==ERROR: AddressSanitizer: stack-buffer-overflow
WRITE of size 25 at 0x7ffc7e3a0df0 thread T0
    #0 0x4013a2 in func program.c:3
3. 使用后释放 (Use-after-free)
ini 复制代码
int *ptr = malloc(sizeof(int));
free(ptr);
*ptr = 42; // 危险操作

ASan 报告:

ini 复制代码
==10990==ERROR: AddressSanitizer: heap-use-after-free
WRITE of size 4 at 0x60200000eff0 thread T0
    #0 0x4012f6 in main program.c:6
4. 内存泄漏 (Memory leak)
scss 复制代码
void leak_memory() {
    malloc(100); // 未释放
}

ASan 报告:

csharp 复制代码
==10991==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 100 byte(s) in 1 object(s) allocated from:
    #0 0x7f0a5b in malloc
    #1 0x40125f in leak_memory program.c:2

五、地址消毒剂高级使用技巧

1. 忽略特定错误
scss 复制代码
// 使用 __attribute__((no_sanitize("address")))
void __attribute__((no_sanitize("address"))) ignore_this_function() {
    // 该函数内的内存错误将被忽略
}

// 或在代码中临时禁用
void sensitive_operation() {
    __asan_disable();
    // 不受 ASan 监控的操作
    __asan_enable();
}
2. 自定义报告处理
c 复制代码
// 自定义错误回调函数
void __asan_on_error() {
    fprintf(stderr, "Custom ASan error handler!\n");
    // 保存额外调试信息
}
3. 与调试器配合使用
bash 复制代码
# GDB 调试 ASan 程序
gdb --args ./program args...

# 常用 GDB 命令
(gdb) break __asan_report_error  # 在 ASan 报错时中断
(gdb) p __asan_describe_address(0x60200000eff4)  # 查看地址信息
相关推荐
AskHarries2 分钟前
在 AI 快速发展的今天,“人还重要吗?
后端
SimonKing3 分钟前
OpenCode 20 个斜杠命令,90% 的人只用过 3 个
java·后端·程序员
Gopher_HBo4 分钟前
BlockingQueue详解
java·后端
米糕闯编程5 分钟前
IDEA新建springboot项目
spring boot·后端·intellij-idea
用户5458429869585 分钟前
Linux磁盘空间排查实战:从df到du的完整诊断链路
前端·后端
Edward111111117 分钟前
TS安装
linux·运维·服务器
ZzzZZzzzZZZzzzz…7 分钟前
Docker 数据持久化:4种挂载方式 + 备份还原实战
linux·运维·docker·云原生·容器·数据持久化
弹简特7 分钟前
【Linux命令饲养指南】03-Linux文件操作与编辑:从“摸鱼”到“搬砖”,这篇让你把文件玩出花
linux
咚为8 分钟前
深入理解 Rust 的静态分发与动态分发:从 `impl Trait` 到 `dyn Trait`
开发语言·后端·rust
dualven_in_csdn11 分钟前
EMQX 开启 **MySQL + password_based** 认证
android·数据库·mysql