public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
From: gp@qnx.com
To: gcc-gnats@gcc.gnu.org
Subject: other/6312: libiberty and vasprintf() sigsegv's on some platforms
Date: Mon, 15 Apr 2002 12:36:00 -0000	[thread overview]
Message-ID: <20020415193050.7842.qmail@sources.redhat.com> (raw)


>Number:         6312
>Category:       other
>Synopsis:       libiberty and vasprintf() sigsegv's on some platforms
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Apr 15 12:36:12 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Graeme Peterson
>Release:        unknown-1.0
>Organization:
>Environment:
I observed this with the head branch of gdb hosted on i386-qnx6 targetting ppc-qnx6, but it is a generic issue in libiberty.
>Description:
The exact bug is in vasprintf() in libiberty/vasprintf.c.

Consider the following example. All looks good, but on the PPC (ppc-qnx6) it won't print out "2". See below for an explanation.

==================
#include <stdio.h>
#include <stdarg.h>

void
handle_foo(char *fmt, va_list *pva) {
    printf("%d\n", va_arg(*pva, int));
}

void
vfoo(char *fmt, va_list va) {
    handle_foo(fmt, &va);
}

void
foo(char *fmt, ...) {
    va_list va;

    va_start(va, fmt);
    vfoo(fmt, va);
    va_end(va);
}

int
main() {
    foo("", 2);
    return 0;
}
===============

The problem is that sometimes the va_list type is an array (as on the PPC) and sometimes not (X86, etc). The C standard says that prototypes such as vfoo() have the array type silently coerced to be a pointer to a base type. This makes things work when you pass an array object to the function. An array-typed expression
is converted to a pointer to the first element when used in an rvalued context, the coercion in the function makes everybody happy. The problem comes when you then pass the address of the va_list parameter to another function. It's expecting a pointer to the array, but what it _really_ gets is a pointer to a pointer (because of the original conversion).

Any use of the va_list in the second function won't get the right data.

Here's the example modified so that it works in all cases:

=======================
#include <stdio.h>
#include <stdarg.h>

void
handle_foo(char *fmt, va_list *pva) {
    printf("%d\n", va_arg(*pva, int));
}

void
vfoo(char *fmt, va_list va) {
    va_list temp;

    va_copy(temp, va);
    handle_foo(fmt, &temp);
}

void
foo(char *fmt, ...) {
    va_list va;

    va_start(va, fmt);
    vfoo(fmt, va);
    va_end(va);
}

int
main() {
    foo("", 2);
    return 0;
}
=============

The use of the va_copy() 'undoes' the coercion that happens in the parameter list, so that the handle_foo() function now gets the proper data.
>How-To-Repeat:
See libiberty/vasprintf.c vasprintf().
>Fix:
Change vasprintf() from:

int
vasprintf (result, format, args)
     char **result;
     const char *format;
#if defined (_BSD_VA_LIST_) && defined (__FreeBSD__)
     _BSD_VA_LIST_ args;
#else
     va_list args;
#endif
{
  return int_vasprintf (result, format, &args);
}

to:

int
vasprintf (result, format, args)
     char **result;
     const char *format;
#if defined (_BSD_VA_LIST_) && defined (__FreeBSD__)
     _BSD_VA_LIST_ args;
#else
     va_list args;
#endif
{
  /* Handle both array and non-array va_list types. */
  va_list temp;
  va_copy(temp, args);
  return int_vasprintf (result, format, &temp);
}
>Release-Note:
>Audit-Trail:
>Unformatted:


                 reply	other threads:[~2002-04-15 19:36 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20020415193050.7842.qmail@sources.redhat.com \
    --to=gp@qnx.com \
    --cc=gcc-gnats@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).