Kenneth Russell wrote:
> Got the crash again with a debug build of the x86_64 ld via your patch
> (thanks). Here's the breakdown and the bug:
[...]
> The bug is in gcc's name mangling. The "2" at the end of "gles2" is
> being confused with the length of a portion of the mangled string,
> because the identifier is in an anonymous namespace.
To be clear, the bug is in Apple ld, not in gcc. There’s nothing wrong
with your mangled name, __ZN5gles212_GLOBAL__N_116g_gl_context_keyE:
C++ decorated name
nested
length 5, gles2
length 12, _GLOBAL__N_1 (anonymous namespace)
length 16, g_gl_context_key
end
or
gles2::(anonymous namespace)::g_gl_context_key
The bug is positively in ld64’s canonicalizeAnonymousName, which takes
a fatal shortcut. Instead of parsing a symbol as a C++ decorated name,
it does a simple string search for “_GLOBAL__N_” and then looks at
everything before it that’s a digit.
This bug can also be triggered by hand-crafting names that contain
_GLOBAL__N_ - such names are, of course, invalid because C++ reserves
names with two consecutive underscores, but there’s nothing preventing
the programmer from writing these names, and from potentially causing
all sorts of mischief. usesAnonymousNamespace has a similar bug but
its negative impact is more limited.
For that matter, the code is entirely ignorant of nested anonymous
namespaces. (I’m not sure how to properly handle these, it requires a
little bit more study.)
> I have no idea why this doesn't core dump the 32-bit ld, but
> experience showed that it doesn't.
Luck. globEndPtr points to memory 212 bytes beyond the first character
of _GLOBAL__N_. In the 64-bit environment and in this very specific
case, as luck would have it, that’s unmapped memory, so you crash.
When you’re running in 32-bit mode in this very specific case, that
pointer references mapped memory and there’s a 0 byte somewhere after.
The function will return garbage and can even corrupt the stack, so
it’s still broken, it just doesn’t crash.
> The workaround from our standpoint is to take this identifier out of
> the anonymous namespace; I'll do that now. Any idea how to fix this
> properly?
Yeah, these functions need to be rewritten. I’ll file a bug with Apple
tomorrow and propose a patch to them. With luck, we can get a fix
rolled into the next Xcode release.
Mark