[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