who stole my returned list?

M

Marc Girod

Hello,

Debugging session:

main::(blib/script/synctree:319): exit $rc unless $sync->get_addhash
|| $sync->get_modhash
main::(blib/script/synctree:320): || $sync-
get_sublist || $sync->_lsco;
DB<2> x $sync->_lsco
0 '/view/emagiro_t7/vobs/atcctest/foo/d'
DB<3> f SyncTree.pm
....
DB<4> b 224
DB<5> c
ClearCase::SyncTree::_lsco(/vobs/atcctest/ClearCase-SyncTree/blib/lib/
ClearCase/SyncTree.pm:224):
224: return sort keys %co;
DB<5> x %co
0 '/view/emagiro_t7/vobs/atcctest/foo/d'
1 1
DB<6> r
scalar context return from ClearCase::SyncTree::_lsco: undef
ClearCase::Argv::DESTROY(/home/emagiro/perl/lib/ClearCase/Argv.pm:
852):
852: my $self = shift;

I am under the debugger, there is a list value being returned, I press
'r', and the next line is:

scalar context return ...: undef !!!?

In between there was one object being destroyed:

sub DESTROY {
my $self = shift;
my $ret = $?;
$self->ipc(0) if $self->ipc;
$? |= $ret;
}

....but how could it affect the return value of the function?

I failed to reproduce the problem in a narrow snippet:

#!/vobs/cello/cade_struct/bin/perl -w

use strict;

{
package DBG;
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
return $self;
}
sub crap {
return qw(1 2 3);
}
sub DESTROY {
my $self = shift;
my $ret = $?;
system('/bin/date');
$? |= $ret;
}

1;
}
sub fun {
my $thing = DBG->new;
return $thing->crap;
}
print "Fun ", join(' ', fun), "\n";
exit 0 unless fun;
print "End\n";


This does print 'End'...
I am sure I took my brains when I left home this morning...
Marc
 
M

Marc Girod

I failed to reproduce the problem in a narrow snippet:

I narrowed one step more, calling the original DESTROY:

use strict;
use ClearCase::Argv;

sub fun {
my $thing = ClearCase::Argv->new;
return qw(1 2 3);
}
print "Fun ", join(' ', fun), "\n";
exit 0 unless fun;
print "End\n";

But, this doesn't make it fail.
Now, what could I *add* to this if I wanted to reproduce the previous
behaviour?

Thanks,
Marc
 
M

Marc Girod

I am sorry that my question didn't inspire anybody...
I continue my debugging:

DB<14> $mod = $sync->_lsco

DB<15> p $mod

DB<16> x $sync->_lsco
0 '/view/emagiro_t7/vobs/atcctest/foo/d'


Er... funny, isn't it?
I go to the return statement of the _lsco function, set 'trace' on,
and do a 'r'.
I get a transcript of running the DESTROY members for two objects (and
I did fix something related since yesterday), and get now (end only):

ClearCase::Argv::DESTROY(/home/emagiro/perl/lib/ClearCase/Argv.pm:
855):
855: $? |= $ret;
list context return from ClearCase::SyncTree::_lsco:
0 '/view/emagiro_t7/vobs/atcctest/foo/d'
ClearCase::SyncTree::checkin(/vobs/atcctest/ClearCase-SyncTree/blib/
lib/ClearCase/SyncTree.pm:1218):
1218: my %checkedout = map {$_ => 1} $self->_lsco;

So, now the function would return something, but the address returned
to is completely weird! That's not where I started from!
As it seems, a different place in the code, where the same function is
called!?

I have corrupted my stack, as it seems...

I'll run the same under an other perl...

Marc
 
M

Marc Girod

I am back to my problem...

I'll run the same under an other perl...

I tried with perl 5.10.0 (until now, it was 5.8.8), and got a similar
behaviour, albeit as it seems, with destructors called later (?!).
In my case, this makes the trace simpler:

ClearCase::SyncTree::_lsco(/vobs/atcctest/ClearCase-SyncTree/blib/lib/
ClearCase/SyncTree.pm:214):
214: return sort keys %co;
DB<4> x %co
0 '/view/emagiro_86/vobs/atcctest/foo/d'
1 1
DB<5> t
Trace = on
DB<5> r
scalar context return from ClearCase::SyncTree::_lsco: undef
main::(blib/script/synctree:321): exit $rc unless $mod;
DB<5> x $mod
main::((eval 43)[/vobs/cello/cade_A_tools_perl/lib/5.10.0/perl5db.pl:
638]:2):
2: $mod;
0 undef

This is the return from the _lsco member function, which gets assigned
to $mod.
I would expect a defined value of 1.
Am I wrong?

Marc
 
M

Marc Girod

Am I wrong?

Yes, but why?
I reproduced it:

$ cat foo
#!/usr/bin/perl -w

sub foo {
my %co = (a=>1, b=>2);
return sort keys %co;
}

my $mod = foo || foo || foo || foo;
print "$mod\n";
$ perl -d ./foo

Loading DB routines from perl5db.pl version 1.3
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(./foo:8): my $mod = foo || foo || foo || foo;
DB<1> c 5
main::foo(./foo:5): return sort keys %co;
DB<2> r
scalar context return from main::foo: undef
main::foo(./foo:4): my %co = (a=>1, b=>2);
DB<2> q
$

This works without 'sort'...

Marc
 
M

Marc Girod

I was pointed the documentation (which I had failed to read well
enough--embarrassing as this is the first paragraph):

In list context, this sorts the LIST and returns the sorted list
value. In scalar context, the behaviour of "sort()" is undefined.

OK. Now I know that 'undefined' may mean 'stack corruption'.
Cave canem... er, caveat emptor, I meant.

The fix is thus:

return wantarray? sort keys %co : scalar keys %co;

Marc
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top