[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: (lack of) va_copy, and segfaults on x86_64
From: |
Thomas Dickey |
Subject: |
Re: (lack of) va_copy, and segfaults on x86_64 |
Date: |
Wed, 3 Mar 2010 16:41:48 -0500 (EST) |
On Tue, 2 Mar 2010, Wim Lewis wrote:
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
The change then didn't actually work (portably for sure), and none of the
platforms that I could test on had a C runtime that could exercise the
change (and need it...).
By coincidence, I hit the same issue with vile this week (predictably,
for glibc on amd64). So I worked through the kinks in the configure check
to make it usable, and can add that to ncurses.
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);
_______________________________________________
Bug-ncurses mailing list
address@hidden
http://lists.gnu.org/mailman/listinfo/bug-ncurses
--
Thomas E. Dickey
http://invisible-island.net
ftp://invisible-island.net