Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Aug 2004 02:20:45 -0700
From:      Peter Wemm <peter@wemm.org>
To:        freebsd-amd64@freebsd.org
Cc:        amd64@freebsd.org
Subject:   Re: va_list structure passing as argument
Message-ID:  <200408240220.45554.peter@wemm.org>
In-Reply-To: <1093328434.6603.21.camel@server.mcneil.com>
References:  <1093328434.6603.21.camel@server.mcneil.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Monday 23 August 2004 11:20 pm, Sean McNeil wrote:
> I'm looking at a problem I have on the amd64 with bsdtar. 
> Essentially, you get a core dump if you try to run the following:
>
> tar zxvvf nonexistent.tar.gz
>
> I've tracked it down to an issue where the ap is getting changed as a
> side-effect of calling __vfprintf.  It looks like this is happening
> because the va_list structure is being passed by reference.  The
> va_list structure on amd64 is 24 bytes.  I'm guessing that it is 16
> bytes or less for i386.  It has been a while since I've looked at the
> macro that determines when a structure is passed by reference or
> value.  Does anyone know what that is?  I'm guessing that 24 passes
> that cutoff but 16 does not and that is why I see this bug on amd64
> and not i386.

Yes, its an external value.  Consider it a pointer.  It is the same on 
both ppc and amd64.

The problem is that vfprintf  "consumes" the values and advances the 
counters in the structure.  (The argument passing ABI is very complex)

What you need to do is this:
myfunc(va_list ap)
{
	va_list apcopy;

	va_copy(apcopy, ap);
	vprintf(stuff, ap1);
	va_copy(apcopy, ap);
	do_stuff_with(ap1);
}
etc.  Using va_copy is "correct" for all our platforms, but neglecting 
to use it is only fatal for amd64 and ppc.

Does that make sense?
-- 
Peter Wemm - peter@wemm.org; peter@FreeBSD.org; peter@yahoo-inc.com
"All of this is for nothing if we don't go to the stars" - JMS/B5



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200408240220.45554.peter>