This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]