This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: va_list bug?
- From: Kai Tietz <Kai dot Tietz at onevision dot com>
- To: "Peter A. Felvegi" <petschy at praire-chicken dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Wed, 19 Mar 2008 09:55:22 +0100
- Subject: Re: va_list bug?
gcc-owner@gcc.gnu.org wrote on 19.03.2008 01:59:04:
> hello,
>
> please try the little program at the end. my naive assumption was that
> it will print "hello world" two times.
>
> if compiled with gcc 3.4, 4.1, 4.2 or 4.3 for i386, it will print "hello
> world" two times all right.
>
> however, if compiled with 3.3, 3.4, 4.1 or 4.3 for amd64, the second
> time it will print "hello @#!@#$" (garbage).
>
> it seems that the gp_offset field of the va struct gets modified by
> someone, so the second vprintf prints garbage:
>
> vp (fmt=0x400672 "hello %s\n", args=0x7fff0e83aec0) at v.c:6
> 6 vprintf(fmt, args);
> (gdb) display *args
> 1: *args = {gp_offset = 8, fp_offset = 48, overflow_arg_area =
> 0x7fff0e83afa0, reg_save_area = 0x7fff0e83aee0}
> (gdb) n
> hello world
> 7 vprintf(fmt, args);
> 1: *args = {gp_offset = 16, fp_offset = 48, overflow_arg_area =
> 0x7fff0e83afa0, reg_save_area = 0x7fff0e83aee0}
>
> i don't know whether this is a gcc issue or a libc issue, but i suspect
> that it's a bug. please clarify.
> i have a debian etch amd64 system, glibc is 2.3.6.
>
> searching for "gcc glibc variadic argument bug" didn't give any relevant
> pages.
>
> regards, peter
>
> ----8<----8<----8<----8<----8<----8<----8<----8<----8<----
> #include <stdarg.h>
> #include <stdio.h>
>
> void vp(const char* fmt, va_list args)
> {
> vprintf(fmt, args);
> vprintf(fmt, args);
> }
>
> void p(const char* fmt, ...)
> {
> va_list args;
> va_start(args, fmt);
> vp(fmt, args);
> va_end(args);
> }
>
> int main()
> {
> p("hello %s\n", "world");
> }
You should use va_copy with amd64 abi. See
http://www.linuxmanpages.com/man3/stdarg.3.php for more details. The amd64
abi passes arguments in registers.
Cheers,
Kai
| (\_/) This is Bunny. Copy and paste Bunny
| (='.'=) into your signature to help him gain
| (")_(") world domination.