Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r72924 - in trunk: boost/exception boost/exception/detail libs/exception/build libs/exception/src libs/exception/test
From: emil_at_[hidden]
Date: 2011-07-05 19:53:35


Author: emildotchevski
Date: 2011-07-05 19:53:33 EDT (Tue, 05 Jul 2011)
New Revision: 72924
URL: http://svn.boost.org/trac/boost/changeset/72924

Log:
Fixing two issues with non-intrusive exception cloning support.
Added:
   trunk/libs/exception/src/clone_current_exception_non_intrusive.cpp
      - copied, changed from r72923, /trunk/libs/exception/src/clone_current_exception_msvc.cpp
Removed:
   trunk/libs/exception/src/clone_current_exception_msvc.cpp
Text files modified:
   trunk/boost/exception/detail/clone_current_exception.hpp | 15 +++++++++------
   trunk/boost/exception/detail/exception_ptr.hpp | 3 ++-
   trunk/boost/exception/exception.hpp | 10 ++++++++++
   trunk/libs/exception/build/Jamfile.v2 | 7 +++++--
   trunk/libs/exception/src/clone_current_exception_non_intrusive.cpp | 31 ++++++++++++++++++++++++++++---
   trunk/libs/exception/test/Jamfile.v2 | 11 +++++------
   6 files changed, 59 insertions(+), 18 deletions(-)

Modified: trunk/boost/exception/detail/clone_current_exception.hpp
==============================================================================
--- trunk/boost/exception/detail/clone_current_exception.hpp (original)
+++ trunk/boost/exception/detail/clone_current_exception.hpp 2011-07-05 19:53:33 EDT (Tue, 05 Jul 2011)
@@ -7,7 +7,7 @@
 #define UUID_81522C0EB56511DFAB613DB0DFD72085
 
 #ifdef BOOST_NO_EXCEPTIONS
-#error This header requires exception handling to be enabled.
+# error This header requires exception handling to be enabled.
 #endif
 
 namespace
@@ -16,6 +16,12 @@
     namespace
     exception_detail
         {
+ class clone_base;
+
+#ifdef BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR
+ int clone_current_exception_non_intrusive( clone_base const * & cloned );
+#endif
+
         namespace
         clone_current_exception_result
             {
@@ -25,15 +31,12 @@
             int const not_supported=3;
             }
 
- class clone_base;
- int clone_current_exception_msvc_x86( clone_base const * & cloned );
-
         inline
         int
         clone_current_exception( clone_base const * & cloned )
             {
-#if defined(BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR) && defined(_MSC_VER) && defined(_M_IX86) && !defined(_M_X64)
- return clone_current_exception_msvc_x86(cloned);
+#ifdef BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR
+ return clone_current_exception_non_intrusive(cloned);
 #else
             return clone_current_exception_result::not_supported;
 #endif

Modified: trunk/boost/exception/detail/exception_ptr.hpp
==============================================================================
--- trunk/boost/exception/detail/exception_ptr.hpp (original)
+++ trunk/boost/exception/detail/exception_ptr.hpp 2011-07-05 19:53:33 EDT (Tue, 05 Jul 2011)
@@ -25,6 +25,7 @@
 #include <stdexcept>
 #include <new>
 #include <ios>
+#include <cstdlib>
 
 namespace
 boost
@@ -456,7 +457,7 @@
         BOOST_ASSERT(p);
         p.ptr_->rethrow();
         BOOST_ASSERT(0);
- abort();
+ std::abort();
         }
 
     inline

Modified: trunk/boost/exception/exception.hpp
==============================================================================
--- trunk/boost/exception/exception.hpp (original)
+++ trunk/boost/exception/exception.hpp 2011-07-05 19:53:33 EDT (Tue, 05 Jul 2011)
@@ -132,7 +132,17 @@
             }
         };
 
+#if defined(__GNUC__)
+# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+# pragma GCC visibility push (default)
+# endif
+#endif
     class exception;
+#if defined(__GNUC__)
+# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+# pragma GCC visibility pop
+# endif
+#endif
 
     template <class T>
     class shared_ptr;

Modified: trunk/libs/exception/build/Jamfile.v2
==============================================================================
--- trunk/libs/exception/build/Jamfile.v2 (original)
+++ trunk/libs/exception/build/Jamfile.v2 2011-07-05 19:53:33 EDT (Tue, 05 Jul 2011)
@@ -5,7 +5,10 @@
 # Distributed under the Boost Software License, Version 1.0. (See accompanying
 # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
-alias boost_exception ;
-lib boost_exception : ../src/clone_current_exception_msvc.cpp : <toolset>msvc ;
+project boost/exception
+ : source-location ../src
+ : requirements <link>static
+ ;
 
+lib boost_exception : clone_current_exception_non_intrusive.cpp ;
 boost-install boost_exception ;

Deleted: trunk/libs/exception/src/clone_current_exception_msvc.cpp
==============================================================================
--- trunk/libs/exception/src/clone_current_exception_msvc.cpp 2011-07-05 19:53:33 EDT (Tue, 05 Jul 2011)
+++ (empty file)
@@ -1,295 +0,0 @@
-//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
-
-//Distributed under the Boost Software License, Version 1.0. (See accompanying
-//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-//This MSVC-specific cpp file implements non-intrusive cloning of exception objects.
-//Based on an exception_ptr implementation by Anthony Williams.
-
-#ifdef BOOST_NO_EXCEPTIONS
-#error This file requires exception handling to be enabled.
-#endif
-
-#if defined(_MSC_VER) && defined(_M_IX86) && !defined(_M_X64)
-
-#include <boost/exception/detail/clone_current_exception.hpp>
-#include <boost/exception/exception.hpp>
-#include <boost/shared_ptr.hpp>
-#ifndef BOOST_NO_RTTI
-#include <typeinfo>
-#endif
-#include <windows.h>
-#include <malloc.h>
-
-namespace
- {
- unsigned const exception_maximum_parameters=15;
- unsigned const exception_noncontinuable=1;
-
-#if _MSC_VER==1310
- int const exception_info_offset=0x74;
-#elif (_MSC_VER==1400 || _MSC_VER==1500)
- int const exception_info_offset=0x80;
-#else
- int const exception_info_offset=-1;
-#endif
-
- struct
- exception_record
- {
- unsigned long ExceptionCode;
- unsigned long ExceptionFlags;
- exception_record * ExceptionRecord;
- void * ExceptionAddress;
- unsigned long NumberParameters;
- ULONG_PTR ExceptionInformation[exception_maximum_parameters];
- };
-
- struct
- exception_pointers
- {
- exception_record * ExceptionRecord;
- void * ContextRecord;
- };
-
- unsigned const cpp_exception_code=0xE06D7363;
- unsigned const cpp_exception_magic_flag=0x19930520;
- unsigned const cpp_exception_parameter_count=3;
-
- struct
- dummy_exception_type
- {
- };
-
- typedef int(dummy_exception_type::*normal_copy_constructor_ptr)(void * src);
- typedef int(dummy_exception_type::*copy_constructor_with_virtual_base_ptr)(void * src,void * dst);
- typedef void (dummy_exception_type::*destructor_ptr)();
-
- union
- cpp_copy_constructor
- {
- normal_copy_constructor_ptr normal_copy_constructor;
- copy_constructor_with_virtual_base_ptr copy_constructor_with_virtual_base;
- };
-
- enum
- cpp_type_flags
- {
- class_is_simple_type=1,
- class_has_virtual_base=4
- };
-
- struct
- cpp_type_info
- {
- unsigned flags;
-#ifndef BOOST_NO_RTTI
- void const * type_info;
-#else
- std::type_info * type_info;
-#endif
- int this_offset;
- int vbase_descr;
- int vbase_offset;
- unsigned long size;
- cpp_copy_constructor copy_constructor;
- };
-
- struct
- cpp_type_info_table
- {
- unsigned count;
- const cpp_type_info * info[1];
- };
-
- struct
- cpp_exception_type
- {
- unsigned flags;
- destructor_ptr destructor;
- void(*custom_handler)();
- cpp_type_info_table const * type_info_table;
- };
-
- struct
- exception_object_deleter
- {
- cpp_exception_type const & et_;
-
- exception_object_deleter( cpp_exception_type const & et ):
- et_(et)
- {
- }
-
- void
- operator()( void * obj )
- {
- BOOST_ASSERT(obj!=0);
- dummy_exception_type * dummy_exception_ptr=reinterpret_cast<dummy_exception_type *>(obj);
- (dummy_exception_ptr->*(et_.destructor))();
- free(obj);
- }
- };
-
- cpp_type_info const &
- get_cpp_type_info( cpp_exception_type const & et )
- {
- cpp_type_info const * ti = et.type_info_table->info[0];
- BOOST_ASSERT(ti!=0);
- return *ti;
- }
-
- void
- copy_msvc_exception( void * dst, void * src, cpp_type_info const & ti )
- {
- if( !(ti.flags & class_is_simple_type) && ti.copy_constructor.normal_copy_constructor )
- {
- dummy_exception_type * dummy_exception_ptr = reinterpret_cast<dummy_exception_type *>(dst);
- if( ti.flags & class_has_virtual_base )
- (dummy_exception_ptr->*(ti.copy_constructor.copy_constructor_with_virtual_base))(src,dst);
- else
- (dummy_exception_ptr->*(ti.copy_constructor.normal_copy_constructor))(src);
- }
- else
- memmove(dst,src,ti.size);
- }
-
- boost::shared_ptr<void>
- clone_msvc_exception( void * src, cpp_exception_type const & et )
- {
- assert(src!=0);
- cpp_type_info const & ti=get_cpp_type_info(et);
- if( void * dst = malloc(ti.size) )
- {
- try
- {
- copy_msvc_exception(dst,src,ti);
- }
- catch(
- ... )
- {
- free(dst);
- throw;
- }
- return boost::shared_ptr<void>(dst,exception_object_deleter(et));
- }
- else
- throw std::bad_alloc();
- }
-
- class
- cloned_exception:
- public boost::exception_detail::clone_base
- {
- cloned_exception( cloned_exception const & );
- cloned_exception & operator=( cloned_exception const & );
-
- cpp_exception_type const & et_;
- boost::shared_ptr<void> exc_;
-
- public:
-
- cloned_exception( void * exc, cpp_exception_type const & et ):
- et_(et),
- exc_(clone_msvc_exception(exc,et_))
- {
- }
-
- ~cloned_exception() throw()
- {
- }
-
- boost::exception_detail::clone_base const *
- clone() const
- {
- return new cloned_exception(exc_.get(),et_);
- }
-
- void
- rethrow() const
- {
- cpp_type_info const & ti=get_cpp_type_info(et_);
- void * dst = _alloca(ti.size);
- copy_msvc_exception(dst,exc_.get(),ti);
- ULONG_PTR args[cpp_exception_parameter_count];
- args[0]=cpp_exception_magic_flag;
- args[1]=reinterpret_cast<ULONG_PTR>(dst);
- args[2]=reinterpret_cast<ULONG_PTR>(&et_);
- RaiseException(cpp_exception_code,EXCEPTION_NONCONTINUABLE,cpp_exception_parameter_count,args);
- }
- };
-
- bool
- is_cpp_exception( EXCEPTION_RECORD const * record )
- {
- return record &&
- (record->ExceptionCode==cpp_exception_code) &&
- (record->NumberParameters==cpp_exception_parameter_count) &&
- (record->ExceptionInformation[0]==cpp_exception_magic_flag);
- }
-
- unsigned long
- exception_cloning_filter( int & result, boost::exception_detail::clone_base const * & ptr, void * info_ )
- {
- BOOST_ASSERT(exception_info_offset>=0);
- BOOST_ASSERT(info_!=0);
- EXCEPTION_POINTERS * info=reinterpret_cast<EXCEPTION_POINTERS *>(info_);
- EXCEPTION_RECORD * record=info->ExceptionRecord;
- if( is_cpp_exception(record) )
- {
- if( !record->ExceptionInformation[2] )
- record = *reinterpret_cast<EXCEPTION_RECORD * *>(reinterpret_cast<char *>(_errno())+exception_info_offset);
- if( is_cpp_exception(record) && record->ExceptionInformation[2] )
- try
- {
- ptr = new cloned_exception(
- reinterpret_cast<void *>(record->ExceptionInformation[1]),
- *reinterpret_cast<cpp_exception_type const *>(record->ExceptionInformation[2]));
- result = boost::exception_detail::clone_current_exception_result::success;
- }
- catch(
- std::bad_alloc & )
- {
- result = boost::exception_detail::clone_current_exception_result::bad_alloc;
- }
- catch(
- ... )
- {
- result = boost::exception_detail::clone_current_exception_result::bad_exception;
- }
- }
- return EXCEPTION_EXECUTE_HANDLER;
- }
- }
-
-namespace
-boost
- {
- namespace
- exception_detail
- {
- int
- clone_current_exception_msvc_x86( clone_base const * & cloned )
- {
- BOOST_ASSERT(!cloned);
- int result = clone_current_exception_result::not_supported;
- if( exception_info_offset>=0 )
- {
- clone_base const * ptr=0;
- __try
- {
- throw;
- }
- __except(exception_cloning_filter(result,ptr,GetExceptionInformation()))
- {
- }
- if( result==clone_current_exception_result::success )
- cloned=ptr;
- }
- BOOST_ASSERT(result!=clone_current_exception_result::success || cloned);
- return result;
- }
- }
- }
-
-#endif

Copied: trunk/libs/exception/src/clone_current_exception_non_intrusive.cpp (from r72923, /trunk/libs/exception/src/clone_current_exception_msvc.cpp)
==============================================================================
--- /trunk/libs/exception/src/clone_current_exception_msvc.cpp (original)
+++ trunk/libs/exception/src/clone_current_exception_non_intrusive.cpp 2011-07-05 19:53:33 EDT (Tue, 05 Jul 2011)
@@ -10,9 +10,13 @@
 #error This file requires exception handling to be enabled.
 #endif
 
-#if defined(_MSC_VER) && defined(_M_IX86) && !defined(_M_X64)
-
 #include <boost/exception/detail/clone_current_exception.hpp>
+
+#if defined(BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR) && defined(_MSC_VER) && defined(_M_IX86) && !defined(_M_X64)
+
+//Non-intrusive cloning support implemented below, only for MSVC versions mentioned above.
+//Thanks Anthony Williams!
+
 #include <boost/exception/exception.hpp>
 #include <boost/shared_ptr.hpp>
 #ifndef BOOST_NO_RTTI
@@ -269,7 +273,7 @@
     exception_detail
         {
         int
- clone_current_exception_msvc_x86( clone_base const * & cloned )
+ clone_current_exception_non_intrusive( clone_base const * & cloned )
             {
             BOOST_ASSERT(!cloned);
             int result = clone_current_exception_result::not_supported;
@@ -292,4 +296,25 @@
         }
     }
 
+#else
+
+//On all other compilers, return clone_current_exception_result::not_supported.
+//On such platforms, only the intrusive enable_current_exception() cloning will work.
+
+#include <boost/config.hpp>
+
+namespace
+boost
+ {
+ namespace
+ exception_detail
+ {
+ int
+ clone_current_exception_non_intrusive( clone_base const * & )
+ {
+ return clone_current_exception_result::not_supported;
+ }
+ }
+ }
+
 #endif

Modified: trunk/libs/exception/test/Jamfile.v2
==============================================================================
--- trunk/libs/exception/test/Jamfile.v2 (original)
+++ trunk/libs/exception/test/Jamfile.v2 2011-07-05 19:53:33 EDT (Tue, 05 Jul 2011)
@@ -8,12 +8,10 @@
 import testing ;
 
 project
- : requirements
- <link>static
- <exception-handling>on
- <source>/boost//exception
- <define>BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR
- ;
+ : requirements
+ <link>static
+ <exception-handling>on
+ ;
 
 #to_string
 
@@ -42,6 +40,7 @@
 run current_exception_cast_test.cpp ;
 run no_exceptions_test.cpp : : : <exception-handling>off ;
 run errinfos_test.cpp ;
+run exception_ptr_test.cpp/<define>BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR /boost/exception /boost//thread : : : <threading>multi : non_intrusive_exception_ptr_test ;
 run exception_ptr_test.cpp /boost//thread : : : <threading>multi ;
 
 compile-fail exception_fail.cpp ;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk