使用zimg库缩放JPEG触发AddressSanitizer SEGV错误求助
zimg缩放JPEG时AddressSanitizer SEGV(空地址写入)问题排查与修复
1. 检查libjpeg初始化与文件句柄
- 必须为
jpeg_decompress_struct绑定错误管理器,避免解压出错时访问空指针:struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; cinfo.err = jpeg_std_error(&jerr); // 这一步不能省略 jpeg_create_decompress(&cinfo); - 验证JPEG文件打开成功,
FILE*指针不为空:FILE* infile = fopen(argv[1], "rb"); if (!infile) { fprintf(stderr, "无法打开目标文件\n"); return 1; }
2. zimg图像格式与上下文的有效性检查
- 初始化
zimg_image_format时,必须填充所有关键字段(宽、高、像素类型、颜色空间等),不能留默认空值:zimg_image_format src_format = {0}; src_format.width = cinfo.image_width; src_format.height = cinfo.image_height; src_format.pixel_type = ZIMG_PIXEL_BYTE; src_format.color_family = ZIMG_COLOR_RGB; // 需匹配JPEG实际颜色空间(如YUV) src_format.subsample_w = cinfo.h_samp_factor; src_format.subsample_h = cinfo.v_samp_factor; zimg_image_format dst_format = {0}; dst_format.width = 640; // 目标宽度 dst_format.height = 480; // 目标高度 dst_format.pixel_type = ZIMG_PIXEL_BYTE; dst_format.color_family = src_format.color_family; dst_format.subsample_w = src_format.subsample_w; dst_format.subsample_h = src_format.subsample_h; - 创建缩放图后必须校验指针非空:
zimg_filter_graph *graph = zimg_filter_graph_create(&src_format, &dst_format, nullptr); if (!graph) { fprintf(stderr, "创建缩放处理图失败\n"); jpeg_destroy_decompress(&cinfo); fclose(infile); return 1; }
3. 图像缓冲区的内存分配校验
- JPEG解压行缓冲区必须确保分配成功:
JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, cinfo.output_width * cinfo.output_components, 1); if (!buffer) { fprintf(stderr, "分配JPEG行缓冲区失败\n"); jpeg_destroy_decompress(&cinfo); fclose(infile); return 1; } - zimg目标缓冲区需按参数计算准确大小,分配后检查非空:
size_t dst_buf_size = dst_format.width * dst_format.height * dst_format.pixel_size * dst_format.plane_count; void *dst_buf = malloc(dst_buf_size); if (!dst_buf) { fprintf(stderr, "分配目标像素缓冲区失败\n"); zimg_filter_graph_destroy(graph); jpeg_destroy_decompress(&cinfo); fclose(infile); return 1; }
4. zimg处理流程的参数正确性
- 调用
zimg_filter_graph_process时,确保输入输出缓冲区指针非空,且格式与之前定义的zimg_image_format完全匹配:- 若为平面格式(如YUV),需逐个传入每个平面的指针,不能直接传单个缓冲区地址
- 校验函数返回值,失败时及时终止流程
5. 资源释放顺序
- 出错或正常退出时,按zimg资源→libjpeg结构→文件句柄的顺序释放,避免悬空指针访问:
// 正常流程释放示例 free(dst_buf); zimg_filter_graph_destroy(graph); jpeg_destroy_decompress(&cinfo); fclose(infile);
错误堆栈精准定位提示
如果堆栈指向特定函数:
- 指向zimg内部像素写入函数:优先检查目标缓冲区是否分配、格式参数是否匹配
- 指向libjpeg解压函数:优先检查解压结构初始化、文件句柄有效性
内容的提问来源于stack exchange,提问作者aculnaig
相关产品推荐
相关产品推荐

