Android x86_64模拟器调用vsprintf崩溃,x86及真机正常
问题修复方案
问题根源
x86_64架构下,va_list的存储结构是包含指针与偏移量的结构体,而非x86架构的单一指针。直接将初始化后的va_list多级传递(exif_entry_log → exif_logv → log_func)会导致参数解析异常,这就是仅x86_64模拟器崩溃的原因。arm64真机未触发问题属于未定义行为,不能依赖。
修复方案
方案1:传递va_list前复制实例
在exif_entry_log中,使用va_copy复制一份独立的va_list再传递给exif_logv,避免原va_list状态被破坏:
static void exif_entry_log (ExifEntry *e, ExifLogCode code, const char *format, ...) { va_list args, args_copy; ExifLog *l = NULL; if (e && e->parent && e->parent->parent) l = exif_data_get_log (e->parent->parent); va_start (args, format); va_copy(args_copy, args); // 复制va_list,保证传递后参数完整性 exif_logv (l, code, "ExifEntry", format, args_copy); va_end(args_copy); // 释放复制的va_list va_end (args); }
方案2:替换为安全的格式化函数
原代码使用vsprintf存在缓冲区溢出风险,同时结合va_list的问题,改用vsnprintf可以同时解决溢出与参数解析问题:
static void log_func (ExifLog *log, ExifLogCode code, const char *domain, const char *format, va_list args, void *data) { char dest[1024] = {0, }; // 使用vsnprintf限制写入长度,避免缓冲区溢出,同时保障参数解析正确 vsnprintf(dest, sizeof(dest), format, args); // 后续使用dest的业务逻辑... }
方案3:检查exif_logv实现(若可修改)
如果exif_logv内部会先遍历args做其他处理,需在该函数内也复制va_list,确保传递给log_func的参数未被破坏:
void exif_logv(ExifLog *l, ExifLogCode code, const char *domain, const char *format, va_list args) { va_list args_copy; va_copy(args_copy, args); // 此处若有其他使用args_copy的逻辑... log_func(l, code, domain, format, args_copy); va_end(args_copy); }
内容的提问来源于stack exchange,提问作者usilo
相关产品推荐
相关产品推荐

