🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gdb.bug
Article #2322

gdb/libiberty/vasprintf.c

#2322
From: Graeme Peterson
Date: Mon, 15 Apr 2002 17:32
121 lines
3785 bytes
Hi.

I found a bug in gdb/libiberty/vasprintf.c.  Well, actually a
SIGSEGV found it for me.  One of the kernel developers here at 
QNX provided me with the explanation for the fix, which I have
appended.

Here is the change I made to fix it for me.  In vasprintf() I 
have added 2 lines before the return, and changed the va_list
parameter being passed to int_vasprintf():


  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);
  }


Thanks.
Graeme Peterson
QNX Tools Group


Explanation:
============

Consider the following example. All looks good, but on the PPC it won't
print out "2".

=======================================================================
#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.
-- 
Technical Details
Message-ID: <200204151732.NAA509440049@gp2>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-06!supernews.com!news-out.visi.com!hermes.visi.com!uunet!ash.uu.net!spool0901.news.uu.net!wendy-fate.uu.net!bug-gdb

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f5053,5df6ea670ac76c5d
X-Google-Attributes: gidf5053,public
X-Google-ArrivalTime: 2002-04-15 10:43:35 PST
x-uunet-gateway: chi6sosrv13.alter.net from bug-gdb to gnu.gdb.bug; Mon, 15 Apr 2002 17:43:34 GMT
Message-ID: <200204151732.NAA509440049@gp2>
Subject: gdb/libiberty/vasprintf.c
Date: Mon, 15 Apr 2002 13:32:59 -0400
From: "Graeme Peterson" <gp@qnx.com>
X-Mailer: ELM [version 2.5 PL2]
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Approved: bug-gdb-request@mail.gnu.org
Newsgroups: gnu.gdb.bug
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-06!supernews.com!news-out.visi.com!hermes.visi.com!uunet!ash.uu.net!spool0901.news.uu.net!wendy-fate.uu.net!bug-gdb
Sender: bug-gdb-request@mail.gnu.org
Lines: 121