Segmentation fault in vsnprintf() from /lib64/tls/libc.so.6

Jakub Jelinek jakub at redhat.com
Mon Dec 4 18:54:39 UTC 2006


On Mon, Dec 04, 2006 at 11:41:02PM +0530, Agarwal, Saumya wrote:
> On executing the code (snippet below) I get a segmentation fault at run
> time. The code builds fine. The same code runs fine on a 32-bit linux
> machine.
>  
>  if (NULL != *strp) {
>         for ( ; NULL != *strp; ) {
>             left = *sizep - len - 1;
>             if (left > 0) {
>                 result = vsnprintf(&(*strp)[len], left, format, ap);
>                 if ((result != -1) && (result < left)) {  //vsnprintf
> truncated the output string
>                     break;
>                 }
>             }
>             *sizep *= 2;
>             Renew(*strp, *sizep, char); //reallocate sizep amount of
> space to strp
>         }
>     }
> 
> The crash happens in the second iteration of the for loop. It goes
> through fine in the first iteration.

No wonder, this is clearly invalid code, see ISO C99, 7.15(3):
The type declared is
    va_list
which is an object type suitable for holding information needed by the
macros va_start, va_arg, va_end, and va_copy. If access to the varying
arguments is desired, the called function shall declare an object
(generally referred to as ap in this subclause) having type va_list.
The object ap may be passed as an argument to another function; if
that function invokes the va_arg macro with parameter ap, the
value of ap in the calling function is indeterminate and shall be passed to
the va_end macro prior to any further reference to ap.

As vsnprintf uses va_arg on the 4th argument passed to it (ap), you really
need to va_copy before you call vsnprintf (and don't forget to pass
it to va_end afterwards).

The va_copy man page should explain it too.

	Jakub




More information about the amd64-list mailing list