On Oct 24, 2007, at 17:21:10, Matthew Wilcox wrote:
On Wed, Oct 24, 2007 at 04:59:48PM -0400, Kyle Moffett wrote:
This seems unlikely to work reliably as the various "v*printf"
functions modify the va_list argument they are passed. It may
happen to work on your particular architecture depending on how
that argument data is passed and stored, but you probably actually
want to make a copy of the varargs list for the first vsnprintf call.
I based what I did on how printk works:
va_start(args, fmt);
r = vprintk(fmt, args);
va_end(args);
It doesn't call va_* anywhere else. I don't claim to be a varargs
expert, but if I'm wrong, I'm at least wrong the same way that
printk is, so not in any way that's significant for any other
architecture Linux runs on.
No, the problem is what happens when you don't have enough space
allocated: you call "vsnprintf(s, len, format, args);" and then
later call "vsprintf(s, format, args);" with the *SAME* "args".
That's what's broken.
So this is wrong:
va_list args;
va_start(args, fmt);
r1 = vprintk(fmt, args);
r2 = vprintk(fmt, args);
va_end(args);
To fix it, you have 2 options.
Option 1:
va_list args;
va_start(args, fmt);
r1 = vprintk(fmt, args);
va_end(args);
va_start(args, fmt);
r2 = vprintk(fmt, args);
va_end(args);
Option 2:
va_list args, argscopy;
va_start(args, fmt);
va_copy(argscopy, args);
r1 = vprintk(fmt, argscopy);
va_end(argscopy);
r2 = vprintk(fmt, args);
va_end(args);
Now in a function which *receives* a va_list from one of its callers,
"Option 1" isn't an option because you don't have the original stack
frame, so the result looks like this:
void func1(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
func2(fmt, ap);
va_end(ap);
}
void func2(const char *fmt, va_list ap)
{
va_list ap2;
va_copy(ap2, ap);
vprintk(fmt, ap2);
va_end(ap2);
vprintk(fmt, ap);
}
Cheers,
Kyle Moffett
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]