Open Bug 975158 Opened 10 years ago Updated 2 years ago

C++ exceptions happen and are always fatal, despite compiling with "-fno-exceptions"

Categories

(Firefox Build System :: General, defect)

All
macOS
defect

Tracking

(Not tracked)

People

(Reporter: smichaud, Unassigned)

References

Details

We don't currently support C++ exceptions in the Mozilla tree (except for a few bundled third-party projects).  So we always compile with "-fno-exceptions", to disable support for them.  But C++ exceptions still get thrown (see for example bug 700103 and bug 973971), and (as best I can tell) are always fatal when thrown.

I'm not sure what we can do about this, and I'm much more familiar with the situation on OS X than on other platforms.  But I think we should have at least one bug at bugzilla.mozilla.org that covers this topic.

As best I can tell, the situation with bug 973971 is as follows:

When clang notices a XUL method (in object code) that calls stdc++ methods (and presumably when the platform's stdc++ library was compiled with support for C++ exceptions), it adds calls to specific throw methods (from libc++abi.dylib), just past the end of the method's object code, for any exception that can be thrown by any of the stdc++ methods called from the XUL method.

So, for example, calls to std::__throw_length_error(char const*) get added past the end of the mozilla::gfx::DrawGradient() method.  DrawGradient() accesses GradientStopsCG.mStops, which is a std::vector object.

This happens even though clang was called with -fno_exceptions.

Calls to std::__throw_length_error(char const*) ultimately call __cxxabiv1::__cxa_throw().  And (as best I can tell from the source code of Apple's libcppapi.dylib at http://opensource.apple.com) __cxxabiv1::__cxa_throw() ends up calling std::terminate() because we don't have any handlers installed for "length_error" exceptions (or for any other C++ exceptions).
I know this isn't really a "build config" bug, but I don't know where else to put it.
See Also: → 973971, 700103
> it adds calls to specific throw methods (from libc++abi.dylib), just
> past the end of the method's object code

Of course clang also adds calls to these throw methods at appropriate
locations inside the XUL method.
Summary: C++ exceptions happen in stdc++ library code and are always fatal, despite compiling with "-fno-exceptions" → C++ exceptions happen and are always fatal, despite compiling with "-fno-exceptions"
The description from comment #0 of what happens wrt bug 973971 is only precisely accurate for OS X 10.7 and 10.6.  What happens on OS X 10.8 and 10.9 is slightly different.

std::terminate() isn't called from std::__throw_length_error(char const*) (via __cxa_throw()).  Instead it ends up being called from __cxa_rethrow() (which is in turn called from CFRunLoopRunSpecific() while the OS is processing native events).
See Also: → 1001994
As long as these exceptions are fatal and not exploitable this should be ok, right?

I mean, the downside of generating extra code when we try not to is sucky too of course.
No, these aren't exploitable.  But they're still a pain.  There's no way we can fix them directly -- we need to figure out what triggered the exception and avoid that behavior.

Fortunately they don't seem to happen very often.
Product: Core → Firefox Build System
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.