我得到以下代码(log
函数的一部分):
/* set to 32 on purpose */
#define MAX_LOG_MSG_SZ 32
void log(const char *fmt, ...) {
....
char msg[MAX_LOG_MSG_SZ] = {0};
int nb_bytes = 0;
/* get current time */
time_t now = time(NULL);
char time_buf[32] = {0};
/* format time as `14 Jul 20:00:08`, and exactly 16 bytes */
strftime(time_buf, sizeof(time_buf), "%d %b %H:%M:%S", localtime(&now));
nb_bytes = snprintf(msg, sizeof(msg), "%s", time_buf);
va_list ap;
va_start(ap, fmt);
vsnprintf(msg + nb_bytes, MAX_LOG_MSG_SZ, fmt, ap);
va_end(ap);
....
}
棘手的事情是当传递长参数(使其长于 32 字节)并更改time_buf
为小于 32 的其他值(大于 16,例如 31)时,这些代码会抛出堆栈粉碎。经过几分钟的调试,我将vsnprintf
调用线路更改为
vsnprintf(msg + nb_bytes, MAX_LOG_MSG_SZ - nb_bytes, fmt, ap);
堆栈粉碎消失了,我认为问题已解决。
但是:在time_buf[32]
(或其他更大的尺寸),为什么错误调用
vsnprintf(msg + nb_bytes, MAX_LOG_MSG_SZ, fmt, ap);
不扔一堆砸?更准确地说,为什么msg
堆栈粉碎与那个不相关的堆栈(time_buf
)空间有关?
更新:这是我的uname -a
输出:
Linux coanor 3.5.0-34-generic #55-Ubuntu SMP Thu Jun 6 20:20:19 UTC 2013 i686 i686 i686 GNU/Linux