| 1 |
Fix a memory leak with Scalar::Util::weaken(). (Closes: #506324)
|
| 2 |
|
| 3 |
Upstream change 34209:
|
| 4 |
|
| 5 |
DBI memory leak in 5.10.0 due to change 26530
|
| 6 |
|
| 7 |
A weakref to a HV would leak, because the xhv_backreferences
|
| 8 |
array is created with a refcount of 2 (to avoid premature freeing
|
| 9 |
during global destruction), but the RC was only decremented once
|
| 10 |
when the parent HV was freed.
|
| 11 |
Also, when thread cloned, the new array was being created with a
|
| 12 |
RC of 1, rather than 2, which coincidentally worked due to the
|
| 13 |
first bug.
|
| 14 |
|
| 15 |
p4raw-id: //depot/perl@34209
|
| 16 |
diff --git a/hv.c b/hv.c
|
| 17 |
index c8279d8..80adc1f 100644
|
| 18 |
--- a/hv.c
|
| 19 |
+++ b/hv.c
|
| 20 |
@@ -1961,6 +1961,7 @@ Perl_hv_kill_backrefs(pTHX_ HV *hv) {
|
| 21 |
if (av) {
|
| 22 |
HvAUX(hv)->xhv_backreferences = 0;
|
| 23 |
Perl_sv_kill_backrefs(aTHX_ (SV*) hv, av);
|
| 24 |
+ SvREFCNT_dec(av);
|
| 25 |
}
|
| 26 |
}
|
| 27 |
|
| 28 |
diff --git a/sv.c b/sv.c
|
| 29 |
index fe36438..7eb088b 100644
|
| 30 |
--- a/sv.c
|
| 31 |
+++ b/sv.c
|
| 32 |
@@ -10265,10 +10265,11 @@ Perl_sv_dup(pTHX_ const SV *sstr, CLONE_PARAMS* param)
|
| 33 |
daux->xhv_eiter = saux->xhv_eiter
|
| 34 |
? he_dup(saux->xhv_eiter,
|
| 35 |
(bool)!!HvSHAREKEYS(sstr), param) : 0;
|
| 36 |
+ /* backref array needs refcnt=2; see sv_add_backref */
|
| 37 |
daux->xhv_backreferences =
|
| 38 |
saux->xhv_backreferences
|
| 39 |
? (AV*) SvREFCNT_inc(
|
| 40 |
- sv_dup((SV*)saux->xhv_backreferences, param))
|
| 41 |
+ sv_dup_inc((SV*)saux->xhv_backreferences, param))
|
| 42 |
: 0;
|
| 43 |
|
| 44 |
daux->xhv_mro_meta = saux->xhv_mro_meta
|