在实际开发中, 我们少不了打log, 如果参数类型和个数没有完全对应, 那就等着core dump吧(更可怕的是不得不解决的低概率core dump), 为什么呢? 我们以printf为例来看看源码:
int printf(const char *fmt, ...)
{
char buf[1024];
va_list args;
int cnt;
va_start(args, fmt);
cnt = vsprintf(buf, fmt, args);
va_end(args);
putstr(buf);
return cnt;
}
继续看vsprintf,
int vsprintf(char *buf, const char *fmt, va_list args)
{
char *str, *s;
int base;
int flags = 0;
int fildwidth = -1;
int precision = -1;
int qualifier;
unsigned long num;
for(str = buf; *fmt != '\0'; fmt++) {
if(*fmt == '\t') {
int k = 8;
while(k--)
*str++ = ' ';
fmt++;
}
if(*fmt != '%') {
*str++ = *fmt;
continue;
}
handle_flags:
fmt++;
switch (*fmt) {
case '#':
flags |= PREFIX;
goto handle_flags;
}
/* handle_fldwidth: */
/* don't need this now */
/* handle_precision: */
/* don't need this now */
/* handle_lenmodifier: */
/* don't need this now */
/* handle_qualifier: */
qualifier = -1;
if(*fmt == 'l' || *fmt == 'L' || *fmt == 'h') {
qualifier = *fmt;
fmt++;
}
/* handle_convtype: */
base = 10;
switch(*fmt) {
case 'c':
/* processing alignment */
*str = (unsigned char)va_arg(args, int);
/* processing alignment */
continue;
case 's':
s = va_arg(args, char *);
str = strcpy(str, s); /* is it safe? */
str--;
continue;
case 'd':
break;
case 'o':
base = 8;
break;
case 'x':
flags |= SMALL;
case 'X':
base = 16;
break;
default:
*str++ = '%';
if(*fmt)
*str++ = *fmt;
else
fmt--;
continue;
}
if (qualifier == 'l')
num = va_arg(args, unsigned long);
else if (qualifier == 'h')
num = (unsigned short)va_arg(args, int);
else {
num = va_arg(args, int);
}
str = num2str(str, num, base, fildwidth, precision, flags);
}
*str = '\0';
return str - buf;
}
可见, 参数个数、类型不匹配, 会导致内存赋值错误, core dump也就来啦。
OK, 先说这么多, 睡觉。