I'm running ActiveState build 809 under Windows 2000.
Main file what.perl:
use utf8;
use charnames ':full';
use Foo;
print "Hello world\n";
Module Foo.pm:
use utf8;
use charnames ':full';
package Foo;
my $LN= "\N{POUND SIGN}";
1; # loaded OK
The error I get is
Attempt to free unreferenced scalar: SV 0x1ad1bd8 at what.perl line 4.
I could not reduce the problem down to one file; apparently having use
charnames in the main program is necessary to see the problem with the
module file!
--John
Thanks for the report.
P5Pers: I've reduced it to the following two-file setup which fails under
bleed:
main:
#!/usr/bin/perl -w
$^H |= 0x20000;
require Foo;
Foo.pm:
BEGIN { $^H |= 0x20000 }
1;
But it's too late in the evening for my cold-ridden brain to work out what
it all means. NB: 0x20000 is HINT_LOCALIZE_HH.
Dave.
--
"Emacs isn't a bad OS once you get used to it.
It just lacks a decent editor."
Note that the use-s in Foo.pm are before the package line so
are still in main::
I suspect the problem is calling charnames::->import(':full') twice in same
package?
I've reduced it further to:
$^H |= 0x20000; eval q{BEGIN { $^H |= 0x20000 }}
When a new hints scope was pushed, a SAVEFREESV() of the hints hash was
done if (PL_hint & 0x20000). When a (possibly different) hints scope was
being popped, the current hints hash would also be freed if (PL_hint &
0x20000). This could lead to the hints hash being double-freed.
The change below to bleedperl fixes it.
Dave.
--
You never really learn to swear until you learn to drive.
Change 22594 by davem@davem-percy on 2004/03/26 13:05:50
[perl #27040] - hints hash was being double freed on scope exit
Affected files ...
... //depot/perl/op.c#620 edit
... //depot/perl/scope.c#122 edit
... //depot/perl/scope.h#65 edit
... //depot/perl/t/comp/hints.t#3 edit
Differences ...
==== //depot/perl/op.c#620 (text) ====
@@ -1763,13 +1763,11 @@
return o;
}
+/* XXX kept for BINCOMPAT only */
void
Perl_save_hints(pTHX)
{
- SAVEI32(PL_hints);
- SAVESPTR(GvHV(PL_hintgv));
- GvHV(PL_hintgv) = newHVhv(GvHV(PL_hintgv));
- SAVEFREESV(GvHV(PL_hintgv));
+ Perl_croak(aTHX_ "internal error: obsolete function save_hints() called");
}
int
==== //depot/perl/scope.c#122 (text) ====
@@ -1042,6 +1042,11 @@
GvHV(PL_hintgv) = NULL;
}
*(I32*)&PL_hints = (I32)SSPOPINT;
+ if (PL_hints & HINT_LOCALIZE_HH) {
+ SvREFCNT_dec((SV*)GvHV(PL_hintgv));
+ GvHV(PL_hintgv) = (HV*)SSPOPPTR;
+ }
+
break;
case SAVEt_COMPPAD:
PL_comppad = (PAD*)SSPOPPTR;
==== //depot/perl/scope.h#65 (text) ====
@@ -152,14 +152,14 @@
#define SAVEOP() save_op()
#define SAVEHINTS() \
- STMT_START { \
- if (PL_hints & HINT_LOCALIZE_HH) \
- save_hints(); \
- else { \
- SSCHECK(2); \
- SSPUSHINT(PL_hints); \
- SSPUSHINT(SAVEt_HINTS); \
- } \
+ STMT_START { \
+ SSCHECK(3); \
+ if (PL_hints & HINT_LOCALIZE_HH) { \
+ SSPUSHPTR(GvHV(PL_hintgv)); \
+ GvHV(PL_hintgv) = newHVhv(GvHV(PL_hintgv)); \
+ } \
+ SSPUSHINT(PL_hints); \
+ SSPUSHINT(SAVEt_HINTS); \
} STMT_END
#define SAVECOMPPAD() \
==== //depot/perl/t/comp/hints.t#3 (text) ====
@@ -2,7 +2,7 @@
# Tests the scoping of $^H and %^H
-BEGIN { print "1..14\n"; }
+BEGIN { print "1..15\n"; }
BEGIN {
print "not " if exists $^H{foo};
print "ok 1 - \$^H{foo} doesn't exist initially\n";
@@ -55,3 +55,15 @@
print "not " if $^H & 0x00020000;
print "ok 8 - \$^H doesn't contain HINT_LOCALIZE_HH while finishing compilation\n";
}
+
+require 'test.pl';
+
+# bug #27040: hints hash was being double-freed
+my $result = runperl(
+ prog => '$^H |= 0x20000; eval q{BEGIN { $^H |= 0x20000 }}',
+ stderr => 1
+);
+print "not " if length $result;
+print "ok 15 - double-freeing hints hash\n";
+print "# got: $result\n" if length $result;
+