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

为何sprintf拼接后的cmd变量输出为空?已确认相关参数有效值

分析sprintf拼接后cmd为空的原因

问题代码

static int call_apab_process()      
{
   static char *pcFnctnNm = "call_apab_process";
   int rc = SUCCESS;
   char cmd[4000];
   char pid[11];
   char logDir[2000];
   cmd[0] = '\0';
   pid[0] = '\0';
   logDir[0] = '\0';
   dbg_indent(pcFnctnNm);
   dbg_print("Entering Into call_apab_process");
   dbg_print("Print Parameters..");
   dbg_print("MY_HOME     :[%s]",getenv("MY_HOME"));
   dbg_print("SESSION_ID    :[%ld]",pvsp_env->sessionid);
   sprintf(cmd,"%s/bin/GQ19apab_DB_auto.sh %ld",getenv("MY_HOME"),pvsp_env->sessionid);
   sprintf(pid,"0%ld",pvsp_env->sessionid);
   sprintf(logDir,"%s/tmp/db",getenv("MY_HOME"));
   dbg_print("cmd :[%s]",cmd);
}

执行输出

Entering Into call_dadp_process
Print Parameters..
MY_HOME     :[/opt/apnp]
SESSION_ID    :[1054628118]
cmd :[]

核心原因:pid缓冲区溢出覆盖了cmd变量

问题出在pid数组的缓冲区大小不足,导致sprintf越界写入,破坏了栈上相邻的cmd变量:

  • pid定义为char pid[11];,但要写入的内容是"0%ld",其中SESSION_ID的值是1054628118(10位数字),拼接后生成字符串"01054628118",共11个字符,加上C字符串必需的终止符\0,总共需要12字节的空间。
  • 栈上的局部变量通常按定义顺序从高地址到低地址排列,cmd是第一个定义的数组,pid位于其下方(地址更低)。当sprintf向pid写入时,会越界写入1字节的\0到cmd的起始位置,将cmd[0]设置为\0,导致后续打印cmd时显示为空。

解决方案

  1. 增大pid缓冲区:将pid的大小调整为至少12字节,确保能容纳完整字符串加终止符:
    char pid[12];
    
  2. 改用snprintf避免溢出:所有字符串拼接操作都用snprintf替代sprintf,强制限制写入长度,从根源避免缓冲区溢出问题:
    snprintf(cmd, sizeof(cmd), "%s/bin/GQ19apab_DB_auto.sh %ld", getenv("MY_HOME"), pvsp_env->sessionid);
    snprintf(pid, sizeof(pid), "0%ld", pvsp_env->sessionid);
    snprintf(logDir, sizeof(logDir), "%s/tmp/db", getenv("MY_HOME"));
    
  3. 验证方法:暂时注释掉sprintf(pid,...)这一行,重新运行程序,若cmd能正常输出内容,即可确认是pid溢出导致的问题。

内容的提问来源于stack exchange,提问作者Vimal Bhaskar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 21:45:44