[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
(lack of) va_copy, and segfaults on x86_64
From: |
Wim Lewis |
Subject: |
(lack of) va_copy, and segfaults on x86_64 |
Date: |
Tue, 2 Mar 2010 22:59:28 -0800 (PST) |
Compiling ncurses-5.7 on macosx-x86_64, I find that it segfaults
frequently within _nc_printf_string() in printw(). The reason seems to be
the way that the va_list is used twice (once to compute the buffer's
length, and once to actually format the string). Like some other
architectures with a register passing convention, va_list on this machine
is a (pointer to a) structure, not a simple pointer to stack memory as it
is on an i386 or vax, and so the implicit copy made by a function call
doesn't actually keep the caller's argument pointer from being modified by
the callee.
The solution is pretty simple, to use va_copy() to explicitly make a copy
of the argument pointer. It looks like an (unrelated?) use of va_copy was
added and then reverted in 20061202/20061217, though, so I'm not sure what
issue needs to be dealt with in order to use va_copy(). (Perhaps just an
autoconf test for its existence?)
I'd guess that this problem affects other architectures too --- I've had
to make similar changes in the past to get stuff to run on linux-ppc, eg.
This is the change I made to my local copy --- not intended as a patch
submission, just to show what I'm talking about. With this change
ncurses seems to work fine:
_nc_printf_string(const char *fmt, va_list ap)
{
char *result = 0;
if (fmt != 0) {
#if USE_SAFE_SPRINTF
! va_list ap_copy;
! va_copy(ap_copy, ap);
! int len = _nc_printf_length(fmt, ap_copy);
! va_end(ap_copy);
if ((int) my_length < len + 1) {
my_length = 2 * (len + 1);
- (lack of) va_copy, and segfaults on x86_64,
Wim Lewis <=