New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
5.8.0 Unbalanced string table refcount #6387
Comments
From Paul@dyerhouse.comHi, This happened on Perl 5.8.0, RedHat 8.0. Here is a code fragment that use IO::File (); foreach (sort keys %altnames) { I have found that I get the error even for one loop. I inserted "last;" If I comment the print($_) statement, I still get the error. If I comment the "while (<$fh>)" loop entirely, the errors go away!! Here is the error log: Unbalanced string table refcount: (1) for "Oracle.txt" during global destruction. I was able to correct the error by using a lexical variable in the outer my $fh = IO::File->new; foreach* my $file* (sort keys %altnames) { # insert each file into |
From @rgsPaul Dyer (via RT) wrote:
I can't reproduce this. Is your code fragment sufficient ? I don't There have been reports of problems due to UTF8 locales, notably under |
From Paul@dyerhouse.comRafael Garcia-Suarez (via RT) wrote:
Hi, I'm attaching the whole script. I am running under Apache, ModPerl. I am using RedHat 8.0 and 7.3 with the same results. I don't know what Paul |
From Paul@dyerhouse.compackage MyApache::BookPicture; use strict; sub handler { my $dir_uri = $r->dir_config('PictureDir'); my $subr = $r->lookup_uri($dir_uri); my @files; $r->content_type('text/html'); print(<<END); my $fh; return OK; 1; |
From @rgsPaul Dyer wrote:
It's possible that it's a mod_perl problem. The startup/shutdown process of It's possible also that the problem is not related at all to mod_perl, but Anyway, the error you're getting is an (undocumented) internal warning
The output of the locale command is usually sufficient. |
From @nwc10On Wed, Mar 19, 2003 at 03:57:21AM -0000, Paul Dyer wrote:
On Fri, Mar 21, 2003 at 05:52:49PM +0100, Rafael Garcia-Suarez wrote:
I'll second that. I can't replicate it here with pure perl - I don't have
I'm surprised that there is only 1 error line. I thought that unbalanced string
the output from perl -V would contain it. (plus a lot of other information) If you're able to make a test case that doesn't need mod_perl that would be $ perl5.8.0-32-g -D -e0 EXECUTING... This perl is not: $ perl5.8.0 -D -e0 Nicholas Clark |
From @nwc10OK. My suspicions were wrong, in that it's not a UTF8 local issue. On Sat, Mar 22, 2003 at 10:16:17PM -0600, Paul Dyer wrote:
On Sat, Mar 22, 2003 at 10:45:01PM -0600, Paul Dyer wrote:
When I run that test code under valgrind (on x86 Debian), with $dir changed $ valgrind ./perl -I lib BookPicture.pl Running with maintperl (5.8.1 to be) or bleadperl (the current development I don't know if it's possible to run mod_perl under valgrind, to see if these Nicholas Clark |
From @rgsNicholas Clark wrote:
Run apache in single process mode : $ valgrind httpd -X |
From @nwc10On Sun, Mar 23, 2003 at 05:59:59PM +0000, Nicholas Clark wrote:
It's probably a different bug you're seeing. I suspect it's the same as this $ ./perl -Ilib -lwe '%hash = ("perl"=>"rules"); foreach (sort keys %hash) {while (<>) {}}' (for -DPERL_COPY_ON_WRITE) I'm not quite sure what the correct fix is. The problem is that tmplen = SvLEN(sv); /* remember if already alloced */ SvLEN() is 0 for a shared hash key scalar, so the if is true. sv_grow ends up in this else block: else { and at the end of that the shared hash key scalar: SV = PVIV(0x812f820) at 0x812f15c becomes the (incorrect) SV = PVIV(0x812f820) at 0x812f15c (FAKE and READONLY should be off) I'm not sure how to solve this. The correct thing to do would be to call But it would explain how the warning about unbalanced string tables. Nicholas Clark |
From @iabynOn Sun, Mar 23, 2003 at 05:59:59PM +0000, Nicholas Clark wrote:
Most of my pad patches have recently been integrated into maintperl. -- |
From @nwc10On Sun, Mar 23, 2003 at 05:59:59PM +0000, Nicholas Clark wrote:
It's not. It can be repeated on a debugging 5.8.0 like this: $ echo | PERL_DESTRUCT_LEVEL=2 perl5.8.0-32-g -lwe '%a= qw(k v); foreach (keys %a) {$_ = <>;}' It's present in maint: nick@penfold:~/19053-g$ echo | PERL_DESTRUCT_LEVEL=2 ./perl -lwe '%a= qw(k v); foreach (keys %a) {$_ = <>;}' It's fixed in blead for the normal case (not copy on write), but not for How does one write a regression test to check for lack of warnings? Nicholas Clark |
From @rgsNicholas Clark <nick@unfortu.net> wrote:
It produces a segfault here, not a warning. #0 0x80df23b in S_sv_release_COW (sv=0x8189604,
Adding it to t/lib/warnings/perl should be sufficient ? |
From @nwc10On Tue, Mar 25, 2003 at 09:56:03AM +0100, Rafael Garcia-Suarez wrote:
That's for copy on write? That's what I see for copy on write. I'll need to think about it some more when I get home.
Except that I'm trying to test that there's no warning issued for a known It's somewhat difficult to write a correct warnings test for Nicholas Clark |
From @nwc10On Tue, Mar 25, 2003 at 09:06:08AM +0000, Nicholas Clark wrote:
er, I should be more careful. My copy of "maint" had 1 line added; an
I think that the appended works. The test fails on 5.8.0 and unpatched blead. I'm not convinced that it's the cleanest logic yet. I think that it would Nicholas Clark Inline Patch--- t/op/readline.t.orig Thu Mar 20 23:53:46 2003
+++ t/op/readline.t Tue Mar 25 22:17:42 2003
@@ -6,7 +6,7 @@ BEGIN {
require './test.pl';
}
-plan tests => 3;
+plan tests => 5;
eval { for (\2) { $_ = <FH> } };
like($@, 'Modification of a read-only value attempted', '[perl #19566]');
@@ -17,4 +17,13 @@ like($@, 'Modification of a read-only va
close A; $a = 4;
is($a .= <A>, 4, '#21628 - $a .= <A> , A closed');
unlink "a";
+}
+
+# 82 is chosen to exceed the length for sv_grow in do_readline (80)
+foreach my $k ('k', 'k'x82) {
+ my $result
+ = runperl (switches => '-l', stdin => '', stderr => 1,
+ prog => "%a = qw($k v); \$_ = <> foreach keys %a; print qw(end)",
+ );
+ is ($result, "end", '[perl #21614] for length ' . length $k);
}
--- ../s19055/sv.c Wed Mar 12 12:11:43 2003
+++ sv.c Tue Mar 25 22:16:49 2003
@@ -1585,8 +1585,15 @@ Perl_sv_grow(pTHX_ register SV *sv, regi
newlen = 0xFFFF;
#endif
}
- else
+ else {
+ /* This is annoying, because sv_force_normal_flags will fix the flags,
+ recurse into sv_grow to malloc a buffer of SvCUR(sv) + 1, then
+ return back to us, only for us to potentially realloc the buffer.
+ */
+ if (SvIsCOW(sv))
+ sv_force_normal_flags(sv, 0);
s = SvPVX(sv);
+ }
if (newlen > SvLEN(sv)) { /* need more room? */
if (SvLEN(sv) && s) {
@@ -4448,11 +4455,11 @@ Perl_sv_force_normal_flags(pTHX_ registe
char *pvx = SvPVX(sv);
STRLEN len = SvCUR(sv);
U32 hash = SvUVX(sv);
+ SvFAKE_off(sv);
+ SvREADONLY_off(sv);
SvGROW(sv, len + 1);
Move(pvx,SvPVX(sv),len,char);
*SvEND(sv) = '\0';
- SvFAKE_off(sv);
- SvREADONLY_off(sv);
unsharepvn(pvx, SvUTF8(sv) ? -(I32)len : len, hash);
}
else if (PL_curcop != &PL_compiling) |
From @rgsNicholas Clark wrote:
Anyway, thanks, applied as #19069 to bleadperl.
BTW I notice that SvIsCOW is not documented in perlapi.pod. That's un-nice. |
From @nwc10On Wed, Mar 26, 2003 at 11:30:05PM +0100, Rafael Garcia-Suarez wrote:
Oh er erk. I've been working on a better one, which is tested, and I don't $ PERL_DESTRUCT_LEVEL=2 ./perl /stuff/blead/19055-g/t/op/readline.t Without the patch, blead with COW looks like this: )
I won't manage that tonight - I'm about to go to bed. Nicholas Clark Inline Patch--- t/op/readline.t.orig Thu Mar 20 23:53:46 2003
+++ t/op/readline.t Wed Mar 26 21:28:07 2003
@@ -6,7 +6,7 @@ BEGIN {
require './test.pl';
}
-plan tests => 3;
+plan tests => 11;
eval { for (\2) { $_ = <FH> } };
like($@, 'Modification of a read-only value attempted', '[perl #19566]');
@@ -18,3 +18,43 @@ like($@, 'Modification of a read-only va
is($a .= <A>, 4, '#21628 - $a .= <A> , A closed');
unlink "a";
}
+
+# 82 is chosen to exceed the length for sv_grow in do_readline (80)
+foreach my $k ('k', 'k'x82) {
+ my $result
+ = runperl (switches => '-l', stdin => '', stderr => 1,
+ prog => "%a = qw($k v); \$_ = <> foreach keys %a; print qw(end)",
+ );
+ is ($result, "end", '[perl #21614] for length ' . length $k);
+}
+
+
+foreach my $k ('perl', 'perl'x21) {
+ my $result
+ = runperl (switches => '-l', stdin => ' rules', stderr => 1,
+ prog => "%a = qw($k v); foreach (keys %a) {\$_ .= <>; print}",
+ );
+ is ($result, "$k rules", 'rcatline to shared sv for length ' . length $k);
+}
+
+foreach my $l (1, 82) {
+ my $k = $l;
+ $k = 'k' x $k;
+ my $copy = $k;
+ $k = <DATA>;
+ is ($k, "moo\n", 'catline to COW sv for length ' . length $copy);
+}
+
+
+foreach my $l (1, 21) {
+ my $k = $l;
+ $k = 'perl' x $k;
+ my $perl = $k;
+ $k .= <DATA>;
+ is ($k, "$perl rules\n", 'rcatline to COW sv for length ' . length $perl);
+}
+__DATA__
+moo
+moo
+ rules
+ rules
--- pp_hot.c.orig Thu Mar 20 23:53:46 2003
+++ pp_hot.c Wed Mar 26 22:08:59 2003
@@ -1509,7 +1509,7 @@ Perl_do_readline(pTHX)
sv_unref(sv);
(void)SvUPGRADE(sv, SVt_PV);
tmplen = SvLEN(sv); /* remember if already alloced */
- if (!tmplen)
+ if (!tmplen && !SvREADONLY(sv))
Sv_Grow(sv, 80); /* try short-buffering it */
offset = 0;
if (type == OP_RCATLINE && SvOK(sv)) {
--- sv.c.orig Wed Mar 12 12:11:43 2003
+++ sv.c Wed Mar 26 22:09:47 2003
@@ -4448,11 +4448,11 @@ Perl_sv_force_normal_flags(pTHX_ registe
char *pvx = SvPVX(sv);
STRLEN len = SvCUR(sv);
U32 hash = SvUVX(sv);
+ SvFAKE_off(sv);
+ SvREADONLY_off(sv);
SvGROW(sv, len + 1);
Move(pvx,SvPVX(sv),len,char);
*SvEND(sv) = '\0';
- SvFAKE_off(sv);
- SvREADONLY_off(sv);
unsharepvn(pvx, SvUTF8(sv) ? -(I32)len : len, hash);
}
else if (PL_curcop != &PL_compiling)
@@ -6289,7 +6289,8 @@ Perl_sv_gets(pTHX_ register SV *sv, regi
I32 rspara = 0;
I32 recsize;
- SV_CHECK_THINKFIRST_COW_DROP(sv);
+ if (SvTHINKFIRST(sv))
+ sv_force_normal_flags(sv, append ? 0 : SV_COW_DROP_PV);
/* XXX. If you make this PVIV, then copy on write can copy scalars read
from <>.
However, perlbench says it's slower, because the existing swipe code |
From @rgsNicholas Clark wrote:
Yup, it's possible. Thanks, applied as #19071. |
From @nwc10On Tue, Mar 25, 2003 at 10:59:17PM +0000, Nicholas Clark wrote:
I can't see a clean way to do this. (which is annoying). It's do-able, but On Thu, Mar 27, 2003 at 12:21:39AM +0100, Rafael Garcia-Suarez wrote:
Thanks On Wed, Mar 26, 2003 at 11:30:05PM +0100, Rafael Garcia-Suarez wrote:
Is this suitable? Nicholas Clark Inline Patch--- sv.h.orig Tue Mar 11 19:29:28 2003
+++ sv.h Thu Mar 27 22:28:53 2003
@@ -920,6 +920,14 @@ Like C<SvPV>, but converts sv to byte re
Guarantees to evaluate sv only once; use the more efficient C<SvPVbyte>
otherwise.
+=for apidoc Am|bool|SvIsCOW|SV* sv
+Returns a boolean indicating whether the SV is Copy-On-Write. (either shared
+hash key scalars, or full Copy On Write scalars if 5.9.0 is configured for
+COW)
+
+=for apidoc Am|bool|SvIsCOW_shared_hash|SV* sv
+Returns a boolean indicating whether the SV is Copy-On-Write shared hash key
+scalar.
=cut
*/ |
@rspier - Status changed from 'new' to 'resolved' |
Migrated from rt.perl.org#21614 (status was 'resolved')
Searchable as RT21614$
The text was updated successfully, but these errors were encountered: