diff options
author | David Mitchell <davem@iabyn.com> | 2019-03-22 15:43:56 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2019-03-25 12:35:27 +0000 |
commit | 803bd7c91c63f8f263bed592a33b10cf69f567cf (patch) | |
tree | 5281ed1d9c1183dc31eee59a3484a9345ab83512 | |
parent | 75bb5aa48dfcf930533cd069393fc8a45e4ece18 (diff) | |
download | perl-803bd7c91c63f8f263bed592a33b10cf69f567cf.tar.gz |
fix leak in BEGIN { threads->new(...) }
Normally by the time we reach perl_destruct(), PL_parser should be null
due to having its original (null) value restored by SAVEt_PARSER during
leaving scope (usually before run-time starts in fact). But if a thread
is created within a BEGIN block, the parser is duped, but the
SAVEt_PARSER savestack entry isn't. So PL_parser never gets cleaned up.
Clean it up in perl_destruct() instead. This is a bit of a hack.
-rw-r--r-- | perl.c | 15 |
1 files changed, 15 insertions, 0 deletions
@@ -668,6 +668,21 @@ perl_destruct(pTHXx) FREETMPS; assert(PL_scopestack_ix == 0); + /* normally when we get here, PL_parser should be null due to having + * its original (null) value restored by SAVEt_PARSER during leaving + * scope (usually before run-time starts in fact). + * But if a thread is created within a BEGIN block, the parser is + * duped, but the SAVEt_PARSER savestack entry isn't. So PL_parser + * never gets cleaned up. + * Clean it up here instead. This is a bit of a hack. + */ + if (PL_parser) { + /* stop parser_free() stomping on PL_curcop */ + PL_parser->saved_curcop = PL_curcop; + parser_free(PL_parser); + } + + /* Need to flush since END blocks can produce output */ /* flush stdout separately, since we can identify it */ #ifdef USE_PERLIO |