Front page | perl.perl5.porters |
Postings from January 2008
not a pad error
Thread Next
From:
Nicholas Clark
Date:
January 26, 2008 06:21
Subject:
not a pad error
Message ID:
20080126142104.GW81396@plum.flirble.org
pp_enteriter has this:
#ifndef USE_ITHREADS
svp = &PAD_SVl(PL_op->op_targ); /* "my" variable */
SAVESPTR(*svp);
#else
SAVEPADSV(PL_op->op_targ);
iterdata = INT2PTR(void*, PL_op->op_targ);
cxtype |= CXp_PADVAR;
#endif
I trace it back to this:
http://public.activestate.com/cgi-bin/perlbrowse/p/7858
Change 7858 by gsar@onru on 2000/11/25 20:52:17
C<foreach my $x ...> in pseudo-fork()ed process may diddle
parent's memory; fix it by keeping track of the actual pad
offset rather than a raw pointer (this change is probably also
relevant to non-ithreads case to avoid fallout from reallocs of
the pad array, but is currently only enabled for the ithreads
case in the interests of minimal disruption to existing "well
tested" code)
I think I can see why it is needed for the dup case for ithreads, given that
previously the address to restore would be "duplicated" with
case SAVEt_SPTR: /* SV* reference */
ptr = POPPTR(ss,ix);
TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
sv = (SV*)POPPTR(ss,ix);
TOPPTR(nss,ix) = sv_dup(sv, param);
break;
and any_dup() is, well, scary:
void *
Perl_any_dup(pTHX_ void *v, const PerlInterpreter *proto_perl)
{
void *ret;
if (!v)
return (void*)NULL;
/* look for it in the table first */
ret = ptr_table_fetch(PL_ptr_table, v);
if (ret)
return ret;
/* see if it is part of the interpreter structure */
if (v >= (void*)proto_perl && v < (void*)(proto_perl+1))
ret = (void*)(((char*)aTHX) + (((char*)v) - (char*)proto_perl));
else {
ret = v;
}
return ret;
}
Note that in this case, the address to 'dup' is inside the memory allocated by
an array. The context stack has no idea of this, and no way to find out. So it
won't change it.
Sarathy comments
avoid fallout from reallocs of the pad array
which is actually something I wondered when looking at the code before
working out which patch last changed it. But I tried this:
#!perl -w
use strict;
sub boom {
my $v;
my $x = "aaaaa";
for $v (0..1) {
for (0..9999) {
eval "my \$$x = 1";
$x++;
}
}
}
boom();
which I thought would reallocate the pad, invalidating the pointer on the
save stack, and hence cause "fun" at scope exit, but it doesn't.
What am I missing? Is Sarathy's assumption wrong for some reason?
Or is there a latent bug here for the unthreaded case, and if so, how do I
provoke it?
Nicholas Clark
Thread Next
-
not a pad error
by Nicholas Clark