高通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)  # 查看地址信息
相关推荐
无垠的广袤1 天前
【VisionFive 2 Lite 单板计算机】边缘AI视觉应用部署:缺陷检测
linux·人工智能·python·opencv·开发板
有来技术1 天前
Spring Boot 4 + Vue3 企业级多租户 SaaS:从共享 Schema 架构到商业化套餐设计
java·vue.js·spring boot·后端
阿波罗尼亚1 天前
Kubectl 命令记录
linux·运维·服务器
Fᴏʀ ʏ꯭ᴏ꯭ᴜ꯭.1 天前
Keepalived单播模式配置与实战指南
linux·服务器·负载均衡
IDC02_FEIYA1 天前
Linux文件搜索命令有哪些?Linux常用命令之文件搜索命令find详解
linux·运维·服务器
江畔何人初1 天前
kubectl apply与kubectl create的区别
linux·运维·云原生
M158227690551 天前
四通道全能组网!SG-Canet-410 CAN转以太网网关,破解工业CAN通信瓶颈
linux·运维·服务器
誰能久伴不乏1 天前
【Qt实战】工业级多线程串口通信:从底层协议设计到完美收发闭环
linux·c++·qt
东东5161 天前
学院个人信息管理系统 (springboot+vue)
vue.js·spring boot·后端·个人开发·毕设
bjxiaxueliang1 天前
一文解决蓝牙连接难题:Ubuntu命令行蓝牙强制配对
linux·ubuntu·蓝牙连接命令