summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2002-05-19 00:28:51 +0000
committerJarkko Hietaniemi <jhi@iki.fi>2002-05-19 00:28:51 +0000
commit9965345dfe11415fe4409828505acf6c7fe193b9 (patch)
tree698244d2acf57eb8a374213afbc7d3b728b26182
parent48eb4d6f7d05204aa5e734e924c7236048de530c (diff)
downloadperl-9965345dfe11415fe4409828505acf6c7fe193b9.tar.gz
Sarathy pointed out that instead of zeroing heap
it is more prudent to poison it. p4raw-id: //depot/perl@16688
-rw-r--r--handy.h11
-rw-r--r--pod/perlapi.pod10
-rw-r--r--pod/perlclib.pod10
-rw-r--r--pod/perlhack.pod5
-rw-r--r--scope.c14
-rw-r--r--sv.c4
-rw-r--r--util.c2
7 files changed, 44 insertions, 12 deletions
diff --git a/handy.h b/handy.h
index 2077007b4c..fe29019b43 100644
--- 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 */
diff --git a/pod/perlapi.pod b/pod/perlapi.pod
index affe329bd1..08420967a8 100644
--- a/pod/perlapi.pod
+++ b/pod/perlapi.pod
@@ -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.
diff --git a/pod/perlclib.pod b/pod/perlclib.pod
index 7c527a9a7a..e89a67a140 100644
--- a/pod/perlclib.pod
+++ b/pod/perlclib.pod
@@ -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
diff --git a/pod/perlhack.pod b/pod/perlhack.pod
index aea346bc29..66023bdfdf 100644
--- a/pod/perlhack.pod
+++ b/pod/perlhack.pod
@@ -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 5ae9a31a9a..673b64cf8b 100644
--- 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 ff53fae0a2..ed40f6840f 100644
--- 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 ad91f01674..3e7b6d3232 100644
--- 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;