This is the mail archive of the
cygwin
mailing list for the Cygwin project.
Re: mdemo ltdl failure
- From: Charles Wilson <news at cwilson dot no dot fastmail dot spam dot com>
- To: Ralf Wildenhues <Ralf dot Wildenhues at gmx dot de>
- Cc: cygwin at cygwin dot com, libtool-patches at gnu dot org
- Date: Fri, 16 Mar 2007 11:00:53 -0500
- Subject: Re: mdemo ltdl failure
- References: <20070225191816.GB2990@iam.uni-bonn.de> <45E3B6CA.50600@cwilson.fastmail.fm> <20070227220200.GC2982@iam.uni-bonn.de> <20070307222815.5072.qmail@iam.uni-bonn.de> <45FAB925.9090200@cwilson.fastmail.fm>
Charles Wilson wrote:
What's odd is that this bug in argz_insert() is very ticklish: it
triggers on "tests/mdemo/Makefile", but not when argz_insert is called
with "./tests/mdemo/Makefile". See the attached gdb screenshots from
just before the buggy call and just after. I've highlighted in red the
location to which *pargz points, and in blue the location to which entry
(ne' buf) points.
The "after" shot indicates that the original contents of entry got
copied to some 11 bytes prior to the beginning of the *pargz buffer,
overlapping the beginning of the newly realloc'ed *pargz. Furthermore,
after the call, the *pargz buffer -- if the value of of *pargz and
*pargz_len are to be believed -- extends across where entry (e.g. buf)
points -- so the malloc subsytem obviously no longer thinks *buf is an
allocated block (otherwise, it wouldn't have included that chunk in the
memory assigned to *pargz by the realloc). So, naturally, FREE(buf) fails.
Actually, I messed up the screen shots, and some of the preceeding
paragraph is incorrect. See the attached two screencaps, instead.
In the para above, I said that *pargz extended across entry/buf. Not
so, but still -- somebody overwrote entry with junk from the old *pargz
buffer, and it happened inside cygwin's argz_insert. And also, somebody
lost track of the malloc status of entry/buf, because FREE(buf) dies
after this call to cygwin's argz_insert (and argz_insert is not supposed
to modify its const char* 'entry' argument)
Here's the code from newlib's argz_insert:
error_t
_DEFUN (argz_insert, (argz, argz_len, before, entry),
char **argz _AND
size_t *argz_len _AND
char *before _AND
const char *entry)
{
int len = 0;
if (before == NULL)
return argz_add(argz, argz_len, entry);
if (before < *argz || before >= *argz + *argz_len)
return EINVAL;
/* NOTE: on the failing call, before == *argz */
while (before != *argz && before[-1])
before--;
len = strlen(entry) + 1;
if(!(*argz = (char *)realloc(*argz, *argz_len + len)))
return ENOMEM;
memmove(before + len, before, *argz + *argz_len - before);
memcpy(before, entry, len);
*argz_len += len;
return 0;
}
Somehow, the contents of entry are being clobbered, AND the malloc
subsystem loses track of that chunk of memory such that FREE(buf) fails.
But I've got to finish building my debug kernel, first.
I need to verify this using a debug-built cygwin kernel, but it looks
like within newlib's argz_insert(), the call to realloc() is not
operating correctly in this instance.
--
Chuck
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/