[cfe-dev] Any known issues with libc++ exceptions and cross-thread exception propagation?

Joe Groff arcata at gmail.com
Sat Jul 21 13:44:53 PDT 2012

On Sat, Jul 21, 2012 at 11:06 AM, Howard Hinnant <hhinnant at apple.com> wrote:
> I was under the impression that make_exception_ptr shipped on Lion and that copy_exception did not.  Though I could be mistaken.  But there should be no semantic difference between the two.

Thanks for the reply, Howard. You're right about make_exception_ptr. I
had to alter TBB to use make_exception_ptr because it currently tries
to use copy_exception. I was just making sure that doing so didn't
also change the meaning of the program.

I tracked down a problem in Lion's libc++abi. It appears that
__cxa_rethrow_primary_exception doesn't update the internal
uncaughtExceptions count, which causes it to underflow at the next
catch and thereby causes uncaught_exception to erroneously return true
when there are no exceptions in flight. The following test case
aggravates it:

#include <cassert>
#include <cstdio>
#include <exception>

int main()
    using namespace std;
    exception_ptr x = make_exception_ptr(2);
    try {
    } catch (int y) {
        printf("%d\n", y);

You can see this happen by peeking into __cxa_get_globals() with gdb:

(gdb) break __cxa_rethrow_primary_exception
Breakpoint 1 at 0x7fff8c4204d1
(gdb) run

Breakpoint 1, 0x00007fff8c4204d1 in __cxa_rethrow_primary_exception ()
(gdb) break __cxa_begin_catch

Breakpoint 3 at 0x7fff8c42035e
(gdb) c

Breakpoint 3, 0x00007fff8c42035e in __cxa_begin_catch ()
(gdb) finish

Run till exit from #0  0x00007fff8c42035e in __cxa_begin_catch ()
0x0000000100000c01 in main () at rethrow_exception.cpp:11
11	    } catch (int y) {
(gdb) p *(void**)__cxa_get_globals()@2
$1 = {0x100100980, 0xffffffff}

(The first value is the head of the caughtExceptions chain, which
didn't get cleaned up, and the second value is the uncaughtExceptions
counter, which has wrapped around to -1).


More information about the cfe-dev mailing list