[cpp-threads] Issue 1369 --- thread safety of std::rethrow_exception

Howard Hinnant howard.hinnant at gmail.com
Tue Nov 16 14:33:20 GMT 2010


On Nov 16, 2010, at 3:00 AM, Anthony Williams wrote:

> In order to clone exceptions you need two things: the size of the object to clone (so you can allocate space for the new one), and the ability to call the copy constructor so you can actually do the copy.
> 
> I've looked at the Itanium ABI at http://www.codesourcery.com/public/cxx-abi/abi.html to try and see where 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().
> 
> 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 old ABI exception and cannot therefore be copied
> 
> (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 object 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.
> 
> What do you think?

I've only skimmed your suggestion and not studied it in detail, but it seems plausible.  And requiring a recompile of the "throwing code" for rethrow_exception to function correctly would be acceptable.

But now comes the hard part.  Getting it implemented and signed-off by http://www.codesourcery.com/public/cxx-abi/abi.html.  They worry about ABI compatibility too and have more expertise in this area than I do.

> Hmm. In C++03, exceptions had to be copyable. It looks like in C++0x they can be move-only. Was this deliberate?

It was deliberate that a move constructor could be used (or elided) in the throw expression.  However I was not aware that one could throw a move-only type.  My impression over the years has been that you couldn't.  But I can not find a CopyConstructible requirement either.  This is not an area of the standard I'm expert in.

-Howard




More information about the cpp-threads mailing list