develooper Front page | perl.perl5.porters | Postings from December 2006

DBI and blead exposes a 5.000 bug

Thread Next
From:
Nicholas Clark
Date:
December 30, 2006 04:05
Subject:
DBI and blead exposes a 5.000 bug
Message ID:
20061230120519.GF30742@plum.flirble.org
DBI currently fails t/zvpp_05thrclone.t on blead. It coredumps because it's
trying to print out an assertion failure warning while cloning a thread.

The assertion in question is that the SV is a PV in the if block of:

    /* XXX This is probably masking the deeper issue of why
     * SvANY(proto_perl->Ilinestr) can be NULL at this point. For test case:
     * http://archive.develooper.com/perl5-porters%40perl.org/msg83298.html
     * (A little debugging with a watchpoint on it may help.)
     */
    if (SvANY(proto_perl->Ilinestr)) {
	PL_linestr		= sv_dup_inc(proto_perl->Ilinestr, param);
	i = proto_perl->Ibufptr - SvPVX_const(proto_perl->Ilinestr);
	PL_bufptr		= SvPVX(PL_linestr) + (i < 0 ? 0 : i);
	i = proto_perl->Ioldbufptr - SvPVX_const(proto_perl->Ilinestr);
	PL_oldbufptr	= SvPVX(PL_linestr) + (i < 0 ? 0 : i);
	i = proto_perl->Ioldoldbufptr - SvPVX_const(proto_perl->Ilinestr);
	PL_oldoldbufptr	= SvPVX(PL_linestr) + (i < 0 ? 0 : i);
	i = proto_perl->Ilinestart - SvPVX_const(proto_perl->Ilinestr);
	PL_linestart	= SvPVX(PL_linestr) + (i < 0 ? 0 : i);
    }
    else {
        PL_linestr = newSV(79);
        sv_upgrade(PL_linestr,SVt_PVIV);
        sv_setpvn(PL_linestr,"",0);
	PL_bufptr = PL_oldbufptr = PL_oldoldbufptr = PL_linestart = SvPVX(PL_linestr);
    }

(all those SvPVX)...


As to why?

This seems to be a 5.000 bug.

The problem appears to be that pp_require does this:

    ENTER;
    SAVETMPS;
    lex_start(sv_2mortal(newSVpvs("")));

lex_start does


    SAVESPTR(PL_linestr);
    ...
    PL_linestr = line;
    [and then a game that puts a new mortal in place of PL_linestr but the
    effect is the same]

and all should be well - the value of PL_linestr will be restored, and the
scalar won't leak.

Problem is that the mortal gets freed way before the scope is cleared.
( lib/perl5/5.9.5/Test/Builder.pm:1624 of all places, just before
  t/05thrclone.t:6 which doesn't totally make sense given

     1  #!perl -w
     2  
     3  # --- Test DBI support for threads created after the DBI was loaded
     4  
     5  BEGIN { eval "use threads;" }   # Must be first
     6  my $use_threads_err = $@;
     7  
     8  use strict;
     9  use Config qw(%Config);
    10  use Test::More;
    11  
    12  BEGIN {
    13      if (!$Config{useithreads} || $] < 5.008) {
    14          plan skip_all => "this $^O perl $] not configured to support iThreads";
    15      }
    16      die $use_threads_err if $use_threads_err; # need threads
    17  }

but I guess is actually the return from use Test::More

Scope free is after "ok 43 - ... all tests have passed" - ie after the do
in t/zvppclone.t returns
)


So the question is why is FREETMPS getting called way before LEAVE?
And if it's supposed to be then, what's the correct way to keep a temporary
for PL_linestr around long enough.
And if there is an extra unbalanced FREETMPS, how come nothing gets upset?


It appears that the original patch leading to that SvANY hack was caused by
the DBI too: http://www.nntp.perl.org/group/perl.perl5.porters/63123

Nicholas Clark

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About