summaryrefslogtreecommitdiff
path: root/perl.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-10-26 06:00:59 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-10-26 06:00:59 -0700
commit8cece9139aefc96dd3920fa7908afea1581f51b7 (patch)
tree77e6ff3562783ced6268592a9717a584e2f496fb /perl.c
parentb188953e9dd3c8a2696f2e1ea1f59ccc6a80d81f (diff)
downloadperl-8cece9139aefc96dd3920fa7908afea1581f51b7.tar.gz
Make PL_DBgv and other db interp vars refcounted
$ PERL5DB=1 perl -de '*DB::DB = sub {} if 0; sub DB::DB{}' No DB::DB routine defined at -e line 1. When the ‘if’ gets folded and *DB::DB is freed, it triggers gv_try_downgrade, causing $DB::{DB} to be deleted and PL_DBgv to point to a freed SV. A higher refcount would prevent gv_try_downgrade from touching it.
Diffstat (limited to 'perl.c')
-rw-r--r--perl.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/perl.c b/perl.c
index 183506202e..c4726c48b0 100644
--- a/perl.c
+++ b/perl.c
@@ -959,9 +959,6 @@ perl_destruct(pTHXx)
PL_stderrgv = NULL;
PL_last_in_gv = NULL;
PL_replgv = NULL;
- PL_DBgv = NULL;
- PL_DBline = NULL;
- PL_DBsub = NULL;
PL_DBsingle = NULL;
PL_DBtrace = NULL;
PL_DBsignal = NULL;
@@ -969,6 +966,13 @@ perl_destruct(pTHXx)
PL_dbargs = NULL;
PL_debstash = NULL;
+ SvREFCNT_dec(PL_DBgv);
+ SvREFCNT_dec(PL_DBline);
+ SvREFCNT_dec(PL_DBsub);
+ PL_DBgv = NULL;
+ PL_DBline = NULL;
+ PL_DBsub = NULL;
+
SvREFCNT_dec(PL_argvout_stack);
PL_argvout_stack = NULL;
@@ -4043,9 +4047,15 @@ Perl_init_debugger(pTHX)
PL_curstash = (HV *)SvREFCNT_inc_simple(PL_debstash);
Perl_init_dbargs(aTHX);
- PL_DBgv = gv_fetchpvs("DB::DB", GV_ADDMULTI, SVt_PVGV);
- PL_DBline = gv_fetchpvs("DB::dbline", GV_ADDMULTI, SVt_PVAV);
- PL_DBsub = gv_HVadd(gv_fetchpvs("DB::sub", GV_ADDMULTI, SVt_PVHV));
+ PL_DBgv = MUTABLE_GV(
+ SvREFCNT_inc(gv_fetchpvs("DB::DB", GV_ADDMULTI, SVt_PVGV))
+ );
+ PL_DBline = MUTABLE_GV(
+ SvREFCNT_inc(gv_fetchpvs("DB::dbline", GV_ADDMULTI, SVt_PVAV))
+ );
+ PL_DBsub = MUTABLE_GV(SvREFCNT_inc(
+ gv_HVadd(gv_fetchpvs("DB::sub", GV_ADDMULTI, SVt_PVHV))
+ ));
PL_DBsingle = GvSV((gv_fetchpvs("DB::single", GV_ADDMULTI, SVt_PV)));
if (!SvIOK(PL_DBsingle))
sv_setiv(PL_DBsingle, 0);