Re: GDB screws up drawing behaviour under Guard Malloc
Re: GDB screws up drawing behaviour under Guard Malloc
- Subject: Re: GDB screws up drawing behaviour under Guard Malloc
- From: Eric Albert <email@hidden>
- Date: Sun, 16 Jul 2006 16:40:41 -0700
On Jul 16, 2006, at 3:54 PM, Rippit the Ogg Frog wrote:
I'm not certain, but I may have found a bug in GDB, Guard Malloc or
some other OS X component. I'll file a bug report if you think I
really have.
This is on a MacBook Pro running OS X 10.4.6 and XCode 2.3.
Also if there were a guard malloc problem, I should get a crash and
not erroneous behaviour. In general, initializing the free space
can effect behaviour without crashing, but I get the same behaviour
whether or not I initialize the free space. Also it's necessary to
set MALLOC_STRICT_SIZE to stimulate the bug, which shouldn't effect
drawing behavior, just maybe cause a crash.
I'm actually a little surprised MALLOC_STRICT_SIZE works without
crashing. On Mac OS X, malloc always aligns its allocations to 16-
byte boundaries when you ask for a buffer of 16 bytes or more. That
helps us take better advantage of AltiVec and SSE, since it means
that we can use instructions which require 16-byte aligned
allocations in more cases. MALLOC_STRICT_SIZE tells Guard Malloc to
not require 16-byte alignment, so code which assumes blocks will be
16-byte aligned may break.
Normal malloc allocations are aligned at their beginning. In other
words, a 16-byte aligned block will be 16-byte aligned at its first
byte, and if it's, say, a 17-byte allocation, its last byte will not
be 16-byte aligned. Because buffer overruns are more common than
buffer underruns, Guard Malloc flips that behavior by default. It
aligns blocks from their end, so a 17-byte allocation would have its
last byte aligned at a 16-byte boundary (specifically the end of a
page) and its first byte would not be 16-byte aligned. But that's
not quite how it works. In Guard Malloc's default configuration
allocations are 4-byte aligned, so a 17-byte allocation would be
rounded up to 20 bytes and wouldn't be 16-byte aligned at either
end. If you set MALLOC_ALTIVEC_SIZE, you'll get 16-byte
alignment...which means that our 17-byte allocation would actually
result in a 32-byte buffer.
Of those examples, only the MALLOC_ALTIVEC_SIZE case reflects the
standard system malloc's behavior for alignment. That's all because
Guard Malloc allocates its buffers at the end of each page, so
aligning odd allocations to a 16-byte boundary is tricky. In setting
MALLOC_STRICT_SIZE you're actually telling Guard Malloc to align all
of its allocations to 1-byte boundaries -- in other words, to add no
padding at all. A 17-byte allocation will therefore end at the end
of a page and start 17 bytes earlier, not aligned at all. This isn't
what various parts of the system assume, so every so often you can
end up with weird behavior.
The workaround is to set MALLOC_PROTECT_BEFORE. This causes Guard
Malloc to allocate at the beginning of each page rather than at the
end, so all blocks will be 16-byte aligned. (Actually, they'll all
be 4K aligned.) This won't catch small buffer overruns, though.
Instead, it'll catch buffer underruns. In your example,
MALLOC_PROTECT_BEFORE fixes the problem and the app draws correctly.
You're welcome to file a bug, of course. It's a somewhat awkward bug
to file because MALLOC_STRICT_SIZE breaks required behavior of the
system malloc, but it's possible that this points to a real problem
anyway.
Hope this helps,
Eric
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden