Resolve CPAN #58484: Devel::Size SEGVs on XSUBs post 5.9.4
Nicholas Clark [Thu, 14 Apr 2011 19:29:59 +0000 (20:29 +0100)]
CHANGES
Size.xs
t/basic.t

diff --git a/CHANGES b/CHANGES
index c0a7b05..8d45bd3 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -8,6 +8,7 @@ Revision history for Perl extension Devel::Size.
    the fatal error introduced in 0.72 when the assumption was violated.
  * Convert to XSLoader
  * Resolve CPAN #49437 (Devel::Size adds magic in Perl 5.10)
+ * Resolve CPAN #58484
 
 0.72 2008-10-14 BrowserUk 70 tests
  * Added bit-vector pointer tracking mechanism.
diff --git a/Size.xs b/Size.xs
index d0f4d29..2d33d54 100644 (file)
--- a/Size.xs
+++ b/Size.xs
@@ -3,6 +3,11 @@
 #include "XSUB.h"
 #include "ppport.h"
 
+/* Not yet in ppport.h */
+#ifndef CvISXSUB
+#  define CvISXSUB(cv)  (CvXSUB(cv) ? TRUE : FALSE)
+#endif
+
 #ifdef _MSC_VER 
 /* "structured exception" handling is a Microsoft extension to C and C++.
    It's *not* C++ exception handling - C++ exception handling can't capture
@@ -667,11 +672,13 @@ UV thing_size(const SV * const orig_thing, TRACKING *tv) {
     if (check_new(tv, CvOUTSIDE(thing))) {
       total_size += thing_size((SV *)CvOUTSIDE(thing), tv);
     }
-    if (check_new(tv, CvSTART(thing))) {
-      total_size += op_size(CvSTART(thing), tv);
-    }
-    if (check_new(tv, CvROOT(thing))) {
-      total_size += op_size(CvROOT(thing), tv);
+    if (!CvISXSUB(thing)) {
+       if (check_new(tv, CvSTART(thing))) {
+           total_size += op_size(CvSTART(thing), tv);
+       }
+       if (check_new(tv, CvROOT(thing))) {
+           total_size += op_size(CvROOT(thing), tv);
+       }
     }
 
     TAG;break;
index cc99c3a..31e1810 100644 (file)
--- a/t/basic.t
+++ b/t/basic.t
@@ -6,7 +6,7 @@ use strict;
 BEGIN
    {
    chdir 't' if -d 't';
-   plan tests => 13;
+   plan tests => 15;
 
    use lib '../lib';
    use lib '../blib/arch';
@@ -93,3 +93,10 @@ isnt (total_size($code), 0, 'total_size($code) > 0');
 ##########################################################
 # RT#14849 (& RT#26781 and possibly RT#29238?)
 isnt( total_size( sub{ do{ my $t=0 }; } ), 0, 'total_size( sub{ my $t=0 } ) > 0' );
+
+# CPAN RT #58484 and #58485
+isnt (total_size(\&total_size), 0, 'total_size(\&total_size) > 0');
+
+use constant LARGE => 'N' x 4096;
+
+isnt (total_size(\&LARGE), 0, 'total_size for a constant > 0');