You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:15:12