This is a live mirror of the Perl 5 development currently hosted at
improve debugging of padlist API
authorDaniel Dragan <>
Thu, 2 Jul 2015 21:15:19 +0000 (17:15 -0400)
committerTony Cook <>
Thu, 9 Jul 2015 01:04:48 +0000 (11:04 +1000)
xpadl_alloc should really be pointer to a struct with a flexible array
member, but flexible array members aren't portable enough among CCs. While
debugging the padlist API for memory corruption (caused by an unrelated
XS module), I saw that the pointer in the first slice of xpadl_alloc
pointed to an AV head of gibberish but 2nd slice was fine. This was
confusing and led me to belive the memory corruption was a bad write to
the array in xpadl_alloc. PadlistARRAY's POD a couple pages down mentions
that index 0 is not an AV *, but the struct comments just said
"pointer to beginning of array of AVs " and didnt mention index 0.

Fix the comments to make it clear what xpadl_alloc is. Add a union so it
is easier to analyze a crash dump/breakpoint with a C debugger, without
writing new code "PADNAMELIST * pnl =  PadlistNAMES(pl);" in many places
and recompiling the interp with -O0, just to be able to inspect the
padnamelist struct.


diff --git a/pad.h b/pad.h
index 31b8715..9e3caa6 100644 (file)
--- a/pad.h
+++ b/pad.h
@@ -33,7 +33,15 @@ typedef U64TYPE PADOFFSET;
 struct padlist {
     SSize_t    xpadl_max;      /* max index for which array has space */
-    PAD **     xpadl_alloc;    /* pointer to beginning of array of AVs */
+    union {
+       PAD **  xpadlarr_alloc; /* Pointer to beginning of array of AVs.
+                                  index 0 is a padnamelist *          */
+       struct {
+           PADNAMELIST * padnl;
+           PAD * pad_1;        /* this slice of PAD * array always alloced */
+           PAD * pad_2;        /* maybe unalloced */
+       } * xpadlarr_dbg;       /* for use with a C debugger only */
+    } xpadl_arr;
     U32                xpadl_id;       /* Semi-unique ID, shared between clones */
     U32                xpadl_outid;    /* ID of outer pad */
@@ -293,7 +301,7 @@ Restore the old pad saved into the local variable opad by PAD_SAVE_LOCAL()
-#define PadlistARRAY(pl)       (pl)->xpadl_alloc
+#define PadlistARRAY(pl)       (pl)->xpadl_arr.xpadlarr_alloc
 #define PadlistMAX(pl)         (pl)->xpadl_max
 #define PadlistNAMES(pl)       *((PADNAMELIST **)PadlistARRAY(pl))
 #define PadlistNAMESARRAY(pl)  PadnamelistARRAY(PadlistNAMES(pl))