[Bug c++/45249] Indirect variable parameters sometimes cause segmentation fault
rogerio at rilhas dot com
gcc-bugzilla@gcc.gnu.org
Wed Aug 11 17:04:00 GMT 2010
------- Comment #21 from rogerio at rilhas dot com 2010-08-11 17:04 -------
Subject: Re: Indirect variable parameters sometimes cause
segmentation fault
Yes, I was using that solution up to 2003, but then I stopped
using it in favour of the more confortable &format (the one I
showed you) because it is less error-prone and easier to automate
(no need for the va_list declaration, start, and end). My teams
usually have a lot of rookies (we have schollarship programs)
and bugs would popup a lot (like switching the order of
parameters, for example).
I could go back to using it, of course, but I already have a lot
of code done with this &format method, and it is not convenient
for me to go back and change anything in old code.
Anyway, I seem to have found a workaround for this problem
in GCC: it seems that if I use the &format before calling the
format_indirect then there will be no problem (still to conform).
void format_direct(char* dst_buffer, int dst_buffer_size_bytes, const
char* format, ...) {
const char** format_address=&format;
format_indirect(dst_buffer, dst_buffer_size_bytes, format_address);
}
If I confirm this then this problem would no longer be blocking
and I would be able to live with it by creating a special macro
in Linux to use the &format before calling format_indirect:
#define GCC_SPECIFIC_ADDRESS_OF(format) const char** format_address(&format)
void format_direct(char* dst_buffer, int dst_buffer_size_bytes, const
char* format, ...) {
format_indirect(dst_buffer, dst_buffer_size_bytes,
GCC_SPECIFIC_ADDRESS_OF(format));
}
... or something along these lines. Maybe I should also replace const
char** by some other GCC-specificy defined type (that would have
no effect on Windows) just to get compilation errors where people try
to pass &format directly whitout using the macro.
matz at gcc dot gnu dot org wrote:
> ------- Comment #20 from matz at gcc dot gnu dot org 2010-08-11 16:10 -------
> A conforming variant of what you probably are trying to code is:
> --------------------------------------------------------------------
> #include <stdio.h>
> #include <stdarg.h>
>
> void format_indirect(char* dst_buffer, size_t dst_buffer_size_bytes,
> const char *format, va_list va)
> {
> vsnprintf(dst_buffer, dst_buffer_size_bytes, format, va);
> dst_buffer[dst_buffer_size_bytes-1]=0;
> }
>
> void format_direct(char* dst_buffer, size_t dst_buffer_size_bytes,
> const char* format, ...)
> {
> va_list va;
> va_start (va, format);
> format_indirect(dst_buffer, dst_buffer_size_bytes, format, va);
> va_end (va);
> }
>
> int main(void)
> {
> char buffer[1000];
> format_direct((char*)buffer, sizeof(buffer), "%s %s", __DATE__, __TIME__);
> printf("Result: \"%s\"\n", buffer);
> return 0;
> }
> -----------------------------------------------------------
>
> Note how the va_list is constructed in the function that actually is
> a varargs one, in particular how the necessary parameter is mentioned.
> Note further how that va_list is passsed to the function that is not
> varargs in order to capture all variable arguments of its caller.
>
> There, no assumption on stack-layout. It will work with all types and
> ABIs, even those that happen to pass even some varargs in registers,
> not on the stack.
>
>
>
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45249
More information about the Gcc-bugs
mailing list