This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug libc/3352] New: dl-minimal.c: 137: realloc: Assertion `new == ptr' failed!
- From: "rsandifo at sourceware dot org" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sources dot redhat dot com
- Date: 12 Oct 2006 09:55:28 -0000
- Subject: [Bug libc/3352] New: dl-minimal.c: 137: realloc: Assertion `new == ptr' failed!
- Reply-to: sourceware-bugzilla at sourceware dot org
I recently encountered:
dl-minimal.c: 137: realloc: Assertion `new == ptr' failed!
while running the prelink testsuite. I'll be attaching a brute-force
script that exposes the same problem on all hosts I've tried, although
the original set-up wasn't as outlandish as this. I'll also be attaching
a patch.
realloc() was being called by a loop that constructs the full pathname
of a library from a relative pathname. The loop starts out with a
buffer that is the same length as the relative pathname, then keeps
adding 128 to the length and reallocating until the buffer is big
enough. When I was running the prelink testsuite, the pathname of
the current directory was longer than 128 characters, so an extra
realloc() was needed.
realloc() says:
new = malloc (n);
assert (new == ptr);
return new;
but malloc() cannot guarantee that:
if (alloc_ptr + n >= alloc_end)
{
/* Insufficient space left; allocate another page. */
caddr_t page;
size_t nup = (n + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1);
page = __mmap (0, nup, PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0);
assert (page != MAP_FAILED);
if (page != alloc_end)
alloc_ptr = page;
alloc_end = page + nup;
}
realloc() assumes that we are lucky and either (a) the current
allocation block is big enough, or (b) the OS satisfies the mmap()
request by providing memory that is contiguous with the old block.
Neither happens in this case. The sequence of events is:
- We make various calls to malloc(). The last of these calls does
not use up the full page, leaving M bytes left over in page P.
- We load a library, mapping it to the pages after P.
- We call malloc() (via realloc()) to allocate X<=M bytes. This request
is satisfied from the space left over in page P.
- We call realloc() to grow the area to X+128>M bytes. This request must
be satisfied by pages that are not contiguous with P, because the
library is in the way.
The fact that the assert triggers so rarely is a good sign that we
aren't losing much memory to realloc() in general. However, we do
still need a fallback.
--
Summary: dl-minimal.c: 137: realloc: Assertion `new == ptr'
failed!
Product: glibc
Version: 2.4
Status: NEW
Severity: normal
Priority: P2
Component: libc
AssignedTo: drepper at redhat dot com
ReportedBy: rsandifo at sourceware dot org
CC: glibc-bugs at sources dot redhat dot com
GCC host triplet: i686-pc-linux-gnu
http://sourceware.org/bugzilla/show_bug.cgi?id=3352
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.