summaryrefslogtreecommitdiff
path: root/perl.c
diff options
context:
space:
mode:
authorDaniel Dragan <bulk88@hotmail.com>2012-08-22 02:19:55 -0400
committerTony Cook <tony@develop-help.com>2012-08-24 15:32:59 +1000
commit36e77d4126acf84c7d0007ed7c58e004ed3f3600 (patch)
tree8a2a4bc412d644d5673eb88c5983cf2bfee91340 /perl.c
parent63adfed234ee0db21960b145d10fbfe3592c535f (diff)
downloadperl-36e77d4126acf84c7d0007ed7c58e004ed3f3600.tar.gz
don't use PerlHost's getenv after perl_destruct
On Win32, perl_free calls PerlHost's getenv which calls win32_getenv. win32_getenv and its children use SVs and mortal stack. After perl_destruct SVs and mortal stack don't exist but the old Itmps_stack pointer remains unchanged/un-nulled. Depending on the memory allocator randomness, previous mortaled SV would be written to allocator freed but page allocated memory and it silently worked. Recently in 5.17 the page started to be freed and now this bug segvs. This patch fixes the problem by using PL_perl_destruct_level and calling getenv earlier.
Diffstat (limited to 'perl.c')
-rw-r--r--perl.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/perl.c b/perl.c
index 84c901f64e..982b4309a2 100644
--- a/perl.c
+++ b/perl.c
@@ -522,13 +522,18 @@ perl_destruct(pTHXx)
PERL_WAIT_FOR_CHILDREN;
destruct_level = PL_perl_destruct_level;
-#ifdef DEBUGGING
+#if defined(DEBUGGING) || defined(PERL_TRACK_MEMPOOL)
{
const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL");
if (s) {
- const int i = atoi(s);
- if (destruct_level < i)
- destruct_level = i;
+ const int i = atoi(s);
+#ifdef DEBUGGING
+ if (destruct_level < i) destruct_level = i;
+#endif
+#ifdef PERL_TRACK_MEMPOOL
+ /* RT #114496, for perl_free */
+ PL_perl_destruct_level = i;
+#endif
}
}
#endif
@@ -1294,8 +1299,7 @@ perl_free(pTHXx)
* Don't free thread memory if PERL_DESTRUCT_LEVEL is set to a non-zero
* value as we're probably hunting memory leaks then
*/
- const char * const s = PerlEnv_getenv("PERL_DESTRUCT_LEVEL");
- if (!s || atoi(s) == 0) {
+ if (PL_perl_destruct_level == 0) {
const U32 old_debug = PL_debug;
/* Emulate the PerlHost behaviour of free()ing all memory allocated in this
thread at thread exit. */