Sarathy pointed out that instead of zeroing heap
Jarkko Hietaniemi [Sun, 19 May 2002 00:28:51 +0000 (00:28 +0000)]
it is more prudent to poison it.

p4raw-id: //depot/perl@16688

handy.h
pod/perlapi.pod
pod/perlclib.pod
pod/perlhack.pod
scope.c
sv.c
util.c

diff --git a/handy.h b/handy.h
index 2077007..fe29019 100644 (file)
--- a/handy.h
+++ b/handy.h
@@ -578,8 +578,12 @@ destination, C<nitems> is the number of items, and C<type> is the type.
 =for apidoc Am|void|StructCopy|type src|type dest|type
 This is an architecture-independent macro to copy one structure to another.
 
-=cut
-*/
+=for apidoc Am|void|Poison|void* dest|int nitems|type
+
+Fill up memory with a pattern (byte 0xAB over and over again) that
+hopefully catches attempts to access uninitialized memory.
+
+=cut */
 
 #ifndef lint
 
@@ -623,6 +627,8 @@ extern long lastxycount[MAXXCOUNT][MAXYCOUNT];
 #define Copy(s,d,n,t)  (void)memcpy((char*)(d),(char*)(s), (n) * sizeof(t))
 #define Zero(d,n,t)    (void)memzero((char*)(d), (n) * sizeof(t))
 
+#define Poison(d,n,t)  (void)memset((char*)(d), 0xAB, (n) * sizeof(t))
+
 #else /* lint */
 
 #define New(x,v,n,s)   (v = Null(s *))
@@ -632,6 +638,7 @@ extern long lastxycount[MAXXCOUNT][MAXYCOUNT];
 #define Move(s,d,n,t)
 #define Copy(s,d,n,t)
 #define Zero(d,n,t)
+#define Poison(d,n,t)
 #define Safefree(d)    (d) = (d)
 
 #endif /* lint */
index affe329..0842096 100644 (file)
@@ -1487,6 +1487,16 @@ memory is zeroed with C<memzero>.
 =for hackers
 Found in file handy.h
 
+=item Poison
+
+Fill up memory with a pattern (byte 0xAB over and over again) that
+hopefully catches attempts to access uninitialized memory.
+
+       void    Poison(void* dest, int nitems, type)
+
+=for hackers
+Found in file handy.h
+
 =item Renew
 
 The XSUB-writer's interface to the C C<realloc> function.
index 7c527a9..e89a67a 100644 (file)
@@ -132,6 +132,16 @@ instead of raw C<char *> strings:
 Note also the existence of C<sv_catpvf> and C<sv_vcatpvfn>, combining
 concatenation with formatting.
 
+Sometimes instead of zeroing the allocated heap by using Newz() you
+should consider "poisoning" the data.  This means writing a bit
+pattern into it that should be illegal as pointers (and floating point
+numbers), and also hopefully surprising enough as integers, so that
+any code attempting to use the data without forethought will break
+sooner rather than later.  Poisoning can be done using the Poison()
+macro, which has similar arguments as Zero():
+
+    Poison(dst, n, t)
+
 =head2 Character Class Tests
 
 There are two types of character class tests that Perl implements: one
index aea346b..66023bd 100644 (file)
@@ -2291,6 +2291,11 @@ Alternatively edit the init file interactively via:
 Note: you can define up to 20 conversion shortcuts in the gdb
 section.
 
+=item *
+
+If you see in a debugger a memory area mysteriously full of 0xabababab,
+you may be seeing the effect of the Poison() macro, see L<perlclib>.
+
 =back
 
 =head2 CONCLUSION
diff --git a/scope.c b/scope.c
index 5ae9a31..673b64c 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -80,9 +80,10 @@ Perl_new_stackinfo(pTHX_ I32 stitems, I32 cxitems)
     si->si_cxmax = cxitems - 1;
     si->si_cxix = -1;
     si->si_type = PERLSI_UNDEF;
-    /* Needs to be Newz() instead of New() because PUSHSUBST()
-     * in pp_subst() might otherwise read uninitialized heap. */
-    Newz(56, si->si_cxstack, cxitems, PERL_CONTEXT);
+    New(56, si->si_cxstack, cxitems, PERL_CONTEXT);
+    /* Without any kind of initialising PUSHSUBST()
+     * in pp_subst() will read uninitialised heap. */
+    Poison(si->si_cxstack, cxitems, PERL_CONTEXT);
     return si;
 }
 
@@ -92,10 +93,9 @@ Perl_cxinc(pTHX)
     IV old_max = cxstack_max;
     cxstack_max = GROW(cxstack_max);
     Renew(cxstack, cxstack_max + 1, PERL_CONTEXT);     /* XXX should fix CXINC macro */
-    /* Needs to Zero()ed because otherwise deep enough recursion
-     * (such as in lib/Math/BigInt/t/upgrade.t) will end up reading
-     * uninitialized heap. */
-    Zero(cxstack + old_max + 1, cxstack_max - old_max, PERL_CONTEXT);
+    /* Without any kind of initialising deep enough recursion
+     * will end up reading uninitialised PERL_CONTEXTs. */
+    Poison(cxstack + old_max + 1, cxstack_max - old_max, PERL_CONTEXT);
     return cxstack_ix + 1;
 }
 
diff --git a/sv.c b/sv.c
index ff53fae..ed40f68 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -9711,7 +9711,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PERL_SET_THX(my_perl);
 
 #  ifdef DEBUGGING
-    memset(my_perl, 0xab, sizeof(PerlInterpreter));
+    Poison(my_perl, 1, PerlInterpreter);
     PL_markstack = 0;
     PL_scopestack = 0;
     PL_savestack = 0;
@@ -9742,7 +9742,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
 
 
 #    ifdef DEBUGGING
-    memset(my_perl, 0xab, sizeof(PerlInterpreter));
+    Poison(my_perl, 1, PerlInterpreter);
     PL_markstack = 0;
     PL_scopestack = 0;
     PL_savestack = 0;
diff --git a/util.c b/util.c
index ad91f01..3e7b6d3 100644 (file)
--- a/util.c
+++ b/util.c
@@ -3121,7 +3121,7 @@ Perl_new_struct_thread(pTHX_ struct perl_thread *t)
     SvCUR_set(sv, sizeof(struct perl_thread));
     thr = (Thread) SvPVX(sv);
 #ifdef DEBUGGING
-    memset(thr, 0xab, sizeof(struct perl_thread));
+    Poison(thr, 1, struct perl_thread);
     PL_markstack = 0;
     PL_scopestack = 0;
     PL_savestack = 0;