[cxx-abi-dev] C++0x std::rethrow_exception, data races and the Itanium ABI

Michael Wong michaelw at ca.ibm.com
Wed Feb 2 23:35:17 UTC 2011


Hi, I wonder if Nathan Sidwell, Mark Michell or others can comment on the
feasibility of these 2 enhancement choices to enable copyable exception
objects.
A solution to this is required by C++0x LWG issue 1369 which is in review
status now:
http://lwg.github.com/issues/lwg-active.html#1369

We discussed this at Fermi Lab and one solution is that we need to start by
requiring one of the many ABI's out there starting with the C++ABI. I
realize there are other ABIs out there but it would be good to support
I like the second option, and it seems the spec as Anthony mention already
make provisions for enhancing the exception object header in the negative
direction, and in fact complete replace that header to allow a copyable
version of the exception object.

We just would like some confirmation that this is allowed from others who
have designed the original C++ ABI exception.


Regards, Michael

Rational C/C++ cafe:
http://www.ibm.com/software/rational/cafe/community/ccpp
My Blogs:
Parallel & Multi-Core Computing
http://www.ibm.com/software/rational/cafe/blogs/ccpp-parallel-multicore
C++ Language & Standard
http://www.ibm.com/software/rational/cafe/blogs/cpp-standard
Commercial Computing
http://www.ibm.com/software/rational/cafe/blogs/ccpp-commercial
Boost test results
http://www.ibm.com/support/docview.wss?rs=2239&context=SSJT9L&uid=swg27006911

C/C++ Compilers Support Page
http://www.ibm.com/software/awdtools/ccompilers/support/
C/C++ Feature Request Interface
http://www.ibm.com/support/docview.wss?uid=swg27005811
XL Fortran Compiler Support Page
http://www.ibm.com/software/awdtools/fortran/xlfortran/support/
XL Fortran Feature Request Interface
http://www.ibm.com/support/docview.wss?uid=swg27005812

Michael Wong
XL C++ Compiler kernel Development
IBM Canada Ltd., C2/KD2/8200/MKM
8200 Warden Avenue
Markham, Ontario  L6G 1C7
W:905-413-3283 F:905-413-4839

Anthony Williams <anthony at justsoftwaresolutions.co.uk> wrote on 11/17/2010
03:32:59 AM:

> [image removed]
>
> [cxx-abi-dev] C++0x std::rethrow_exception, data races and the Itanium
ABI
>
> Anthony Williams
>
> to:
>
> cxx-abi-dev
>
> 11/17/2010 04:05 AM
>
> Hi,
>
> With the current draft of the upcoming C++0x standard, it is unclear
> whether the exception thrown by std::rethrow_exception is the same
> exception object that was originally thrown, or a copy thereof. Indeed,
> different implementations do different things: gcc rethrows the same
> exception object, and MSVC2010 throws a copy.
>
> I believe that this is a mistake; std::rethrow_exception should always
> throw a copy. If it rethrows the same exception then the same exception
> object may now become active in multiple threads. This then exposes the
> **handlers** to data races should they catch by reference and call any
> member functions that modify the exception object.
>
> One use case I have seen for this is to add call stack information to an
> exception for logging purposes. e.g.
>
> void g();
>
> struct my_exception
> {
>      void add_caller(std::string const& function_name,int arg1,int arg2);
> };
>
> void f(int arg1,int arg2){
>     try{
>        g();
>     catch(my_exception& e)
>     {
>        e.add_caller("f(int,int)",arg1,arg2);
>        throw;
>     }
> }
>
> Under C++03, any exception thrown by g() must originate in this thread,
> so there is no possibility of a data race in f(). Under C++0x we must
> contend with the possibility that the exception originated in another
> thread. e.g.
>
> std::mutex m;
> std::exception_ptr ep;
>
> void g()
> {
>      std::lock_guard<std::mutex> lk(m);
>      if(ep)
>          std::rethrow_exception(ep);
> }
>
> If multiple threads call g() they may thus each rethrow the same
> exception. If this truly is the **same** exception object (and not a
> copy) then callers such as f() have now been exposed to a data race,
> **without changing f()**.
>
> Also, under the latitude provided by the C++0x draft, this behaviour may
> vary from compiler to compiler. I can write some code that is race-free
> under MSVC2010, but if I then recompile it with gcc then I have a data
> race, **without any indication from the compiler**.
>
> I am aware that the reason for gcc's behaviour in this case is that the
> Itanium ABI does not provide the necessary information to copy an
> exception object, which is why I am posting here. I would like to
> propose changing the Itanium ABI to provide the necessary information to
> copy the exception object, **whilst remaining backwards compatible**.
>
> Based on the documentation at
> http://www.codesourcery.com/public/cxx-abi/abi.html I have a couple of
> ideas on how this could be done.
>
> One option I see would be to add a new class derived from
> abi::__class_type_info that had virtual member functions for the size
> and copy constructor:
>
> class __copyable_class_type_info: public __class_type_info
> {
> public:
>      size_t __object_size;
>      virtual void __copy_construct(void* __source, void* __dest)=0;
> };
>
> You would need similar derived classes for __si_class_type_info and
> __vmi_class_type_info.
>
> Because these are derived classes, they shouldn't affect the existing
> ABI structures. The size of non-class types can be determined from the
> type directly, since all pointers have the same size and fundamental
> types have a fixed size under the ABI. Such types can also be copied
> with memcpy(). The type_info for classes for which there is no public
> copy constructor would not derive from these new type-info classes.
>
> rethrow_exception can then check the type_info pointed to by the
> exceptionType member of the __cxa_exception header, and either
>
> (i) copy the exception with memcpy (because it's a fundamental type or
> pointer)
>
> (ii) throw bad_alloc because this is an exception that cannot therefore
> be copied (i.e. it has no public copy constructor, or because it is from
> the old ABI)
>
> (iii) dynamic_cast the type info to __copyable_class_type_info use the
> new __object_size and __copy_construct virtual functions to clone the
> exception
>
> A second option is to add the size and copy construction functions to
> the __cxa_exception header. The ABI says "By convention, a
> __cxa_exception pointer points at the C++ object representing the
> exception being thrown, immediately following the header. The header
> structure is accessed at a negative offset from the __cxa_exception
> pointer. This layout allows consistent treatment of exception objects
> from different languages (or different implementations of the same
> language), and allows future extensions of the header structure while
> maintaining binary compatibility. "
>
> We could therefore take advantage of this leeway to "extend the header
> structure while maintaining binary compatibility" to add the new size
> and copy construction members. In this case, the stored copy constructor
> could be NULL if there is no public copy constructor for the class.
>
> In either case, the intention is that old code would work without
> recompilation even if the library code that it called was changed to use
> the new ABI, and new code could take advantage of the ability to copy
> exceptions where the exception was thrown from code that used the new
ABI.
>
> What do you think? Are these options implementable in a
> backwards-binary-compatible way? Is there an alternative implementation
> option?
>
> Thanks,
>
> Anthony
> --
> Author of C++ Concurrency in Action     http://www.stdthread.co.uk/book/
> just::thread C++0x thread library             http://www.stdthread.co.uk
> Just Software Solutions Ltd       http://www.justsoftwaresolutions.co.uk
> 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20110202/9bdc687e/attachment.html>


More information about the cxx-abi-dev mailing list