From: Nicholas Clark Date: Thu, 14 Apr 2011 13:19:15 +0000 (+0100) Subject: Catching SEGVs with __try/__except is MSVC only, not general C++ X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=1a36ac09c25a034362359c60d9f6599073d3108f;p=p5sagit%2FDevel-Size.git Catching SEGVs with __try/__except is MSVC only, not general C++ __try/__except is an MSVC extension to C++ *and* C, and is orthogonal to "regular" C++ exception handling. As there's no way to catch a SEGV with C++ exceptions (certainly not portably), and __try/__except is available in C, there's nothing to be gained from using C++ exceptions, and hence making the code require a C++ compiler. Hence remove the logic from Makefile.PL to force compilation with a C++ compiler, which didn't even work well on "both" kinds of OS, as it assumed that the C compiler was named *exactly* qr/\Ag?cc\z/, and that the analogous C++ compiler was available and named g++. [Which isn't true when it's named 'ccache gcc', 'gcc-mp-4.6' etc, or when cc isn't gcc] --- diff --git a/CHANGES b/CHANGES index 2fc570f..32adffb 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ Revision history for Perl extension Devel::Size. 0.72_50 2011-04-14 nicholas + * Exception handling is totally MSVC specific, so only use it there + - this means that we don't need to use a C++ compiler anywhere * Resolve CPAN #49437 (Devel::Size adds magic in Perl 5.10) 0.72 2008-10-14 BrowserUk 70 tests diff --git a/Makefile.PL b/Makefile.PL index 2f441a6..633ab1c 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,11 +1,6 @@ use ExtUtils::MakeMaker; -use Config; -my %options = ( +WriteMakefile( NAME => 'Devel::Size', - LIBS => $Config{cc} eq 'gcc' || $Config{cc} eq 'cc' ? ['-lstdc++'] : '', VERSION_FROM => 'lib/Devel/Size.pm', - CC => $Config{cc} eq 'cl' ? 'cl' : 'g++', ); - -WriteMakefile(%options); diff --git a/README b/README index 15e173c..e6963c5 100644 --- a/README +++ b/README @@ -38,13 +38,6 @@ On Linux, Cygwin, or Unix: make test sudo make install -On most systems, it is necessary to link to libstdc++. On such systems, -libstdc++ should be found automatically (by default). -If libstdc++ is *not* being found automatically (in which case you'll get -link errors),then instead of running 'perl Makefile.PL', you'll need to run: - - perl Makefile.pl LIBS="-L/path/to/libstdc++ -lstdc++" - On Windows: perl Makefile.PL diff --git a/Size.xs b/Size.xs index 19725a0..e155852 100644 --- a/Size.xs +++ b/Size.xs @@ -2,14 +2,17 @@ #include "perl.h" #include "XSUB.h" - #ifdef _MSC_VER -# include -# define try __try -# define catch __except -# define EXCEPTION EXCEPTION_EXECUTE_HANDLER +/* "structured exception" handling is a Microsoft extension to C and C++. + It's *not* C++ exception handling - C++ exception handling can't capture + SEGVs and suchlike, whereas this can. There's no known analagous + functionality on other platforms. */ +# include +# define TRY_TO_CATCH_SEGV __try +# define CAUGHT_EXCEPTION __except(EXCEPTION EXCEPTION_EXECUTE_HANDLER) #else -# define EXCEPTION ... +# define TRY_TO_CATCH_SEGV if(1) +# define CAUGHT_EXCEPTION else #endif #ifdef __GNUC__ @@ -50,10 +53,10 @@ IV check_new( TRACKING *tv, void *p ) { unsigned int nop = (unsigned long)p & 0x3U; if (NULL == p || NULL == tv) return FALSE; - try { + TRY_TO_CATCH_SEGV { char c = *(char *)p; } - catch ( EXCEPTION ) { + CAUGHT_EXCEPTION { if( dangle_whine ) warn( "Devel::Size: Encountered invalid pointer: %p\n", p ); return FALSE; @@ -101,7 +104,7 @@ cc_opclass(const OP * const o) { if (!o) return OPc_NULL; - try { + TRY_TO_CATCH_SEGV { if (o->op_type == 0) return (o->op_flags & OPf_KIDS) ? OPc_UNOP : OPc_BASEOP; @@ -205,7 +208,7 @@ cc_opclass(const OP * const o) warn("Devel::Size: Can't determine class of operator %s, assuming BASEOP\n", PL_op_name[o->op_type]); } - catch( EXCEPTION ) { } + CAUGHT_EXCEPTION { } return OPc_BASEOP; } @@ -235,7 +238,7 @@ IV magic_size(const SV * const thing, TRACKING *tv) { while (magic_pointer && check_new(tv, magic_pointer)) { total_size += sizeof(MAGIC); - try { + TRY_TO_CATCH_SEGV { /* Have we seen the magic vtable? */ if (magic_pointer->mg_virtual && check_new(tv, magic_pointer->mg_virtual)) { @@ -245,7 +248,7 @@ IV magic_size(const SV * const thing, TRACKING *tv) { /* Get the next in the chain */ // ?try magic_pointer = magic_pointer->mg_moremagic; } - catch( EXCEPTION ) { + CAUGHT_EXCEPTION { if( dangle_whine ) warn( "Devel::Size: Encountered bad magic at: %p\n", magic_pointer ); } @@ -276,7 +279,7 @@ UV regex_size(const REGEXP * const baseregex, TRACKING *tv) { UV op_size(const OP * const baseop, TRACKING *tv) { UV total_size = 0; - try { + TRY_TO_CATCH_SEGV { TAG; if (check_new(tv, baseop->op_next)) { total_size += op_size(baseop->op_next, tv); @@ -422,7 +425,7 @@ UV op_size(const OP * const baseop, TRACKING *tv) { TAG;break; } } - catch( EXCEPTION ) { + CAUGHT_EXCEPTION { if( dangle_whine ) warn( "Devel::Size: Encountered dangling pointer in opcode at: %p\n", baseop ); } diff --git a/lib/Devel/Size.pm b/lib/Devel/Size.pm index 2355afc..4be6c8a 100644 --- a/lib/Devel/Size.pm +++ b/lib/Devel/Size.pm @@ -255,9 +255,10 @@ These may be disabled by setting Devel::Size has always been vulnerable to trapping when traversing Perl's internal data structures, if it encounters uninitialised (dangling) pointers. -Exception handling has been added to deal with this possibility, and Devel::Size -will now attempt to ignore (or log) them and continue. These messages are mainly -of interest to Devel::Size and core developers, and so are disabled by default. +MSVC provides exception handling able to deal with this possibility, and when +built with MSVC Devel::Size will now attempt to ignore (or log) them and +continue. These messages are mainly of interest to Devel::Size and core +developers, and so are disabled by default. They may be enabled by setting