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

Howard Hinnant hhinnant at apple.com
Sat Jul 21 14:07:40 PDT 2012


On Jul 21, 2012, at 4:44 PM, Joe Groff <arcata at gmail.com> wrote:

> 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 {
>        rethrow_exception(x);
>    } catch (int y) {
>        printf("%d\n", y);
>    }
>    assert(!uncaught_exception());
> }
> ---
> 
> 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
> Continuing.
> 
> 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).
> 
> -Joe

Wow, awesome debugging job Joe!  Sorry about the bug.  It has been fixed in the llvm version of libc++abi (http://libcxxabi.llvm.org).

Howard




More information about the cfe-dev mailing list