高通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)  # 查看地址信息
相关推荐
咖啡啡不加糖9 小时前
贪心算法详解与应用
java·后端·算法·贪心算法
matlab的学徒9 小时前
nginx+springboot+redis+mysql+elfk
linux·spring boot·redis·nginx
IT_陈寒9 小时前
Java性能优化:3个90%开发者都忽略的高效技巧,让你的应用提速50%!
前端·人工智能·后端
00后程序员张9 小时前
苹果软件混淆的工程逻辑,从符号空间到资源扰动的体系化实现
android·ios·小程序·https·uni-app·iphone·webview
HappyGame029 小时前
Linux网络编程(上)
linux·网络
thginWalker9 小时前
软件的基础原理
后端
绝无仅有9 小时前
面试真实经历某节跳动大厂Java和算法问答以及答案总结(一)
后端·面试·github
绝无仅有9 小时前
某大厂跳动面试:计算机网络相关问题解析与总结
后端·面试·github
Janspran9 小时前
监控系统3 - LVGL
linux