From: Jarkko Hietaniemi Date: Sun, 19 May 2002 00:28:51 +0000 (+0000) Subject: Sarathy pointed out that instead of zeroing heap X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=9965345dfe11415fe4409828505acf6c7fe193b9;p=p5sagit%2Fp5-mst-13.2.git Sarathy pointed out that instead of zeroing heap it is more prudent to poison it. p4raw-id: //depot/perl@16688 --- diff --git a/handy.h b/handy.h index 2077007..fe29019 100644 --- a/handy.h +++ b/handy.h @@ -578,8 +578,12 @@ destination, C is the number of items, and C 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 affe329..0842096 100644 --- a/pod/perlapi.pod +++ b/pod/perlapi.pod @@ -1487,6 +1487,16 @@ memory is zeroed with C. =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 function. diff --git a/pod/perlclib.pod b/pod/perlclib.pod index 7c527a9..e89a67a 100644 --- a/pod/perlclib.pod +++ b/pod/perlclib.pod @@ -132,6 +132,16 @@ instead of raw C strings: Note also the existence of C and C, 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 aea346b..66023bd 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. + =back =head2 CONCLUSION diff --git a/scope.c b/scope.c index 5ae9a31..673b64c 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 ff53fae..ed40f68 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 ad91f01..3e7b6d3 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;