Skip to content
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

The "my" variables and "@_" in the underlying frame are corrupted. Cc: abs@auriga.ru #420

Closed
p5pRT opened this issue Aug 23, 1999 · 2 comments

Comments

@p5pRT
Copy link

p5pRT commented Aug 23, 1999

Migrated from rt.perl.org#1257 (status was 'resolved')

Searchable as RT1257$

@p5pRT
Copy link
Author

p5pRT commented Aug 23, 1999

From abs@auriga.ru

illperl.tgz

@p5pRT
Copy link
Author

p5pRT commented Aug 23, 1999

From abs@auriga.ru

 
 
 

This is a report about the possible bug in Perl.

Revision of the Perl where the bug has been encountered.

This is perl, version 5.005_03 built for MSWin32-x86-object

(with 1 registered patch, see perl -V for more detail)
Copyright 1987-1999, Larry Wall
Binary build 518 provided by ActiveState Tool Corp. http​://www.ActiveState.com

Built 13​:14​:00 Jun 24 1999

Perl may be copied only under the terms of either the Artistic License
or the

GNU General Public License, which may be found in the Perl 5.0 source
kit.
Complete documentation for Perl, including FAQ lists, should be found
on

this system using `man perl' or `perldoc perl'. If you have access
to the

Internet, point your browser at http​://www.perl.com/, the Perl Home
Page.

Disclaimer.
This is not mine program, so please don't ask me about "why did you wrote
all this stuff this way".

Also I'm a novice in Perl so I cannot give the expert conclusion about
what happens in the test case.

I was involved as a debugger and found that not everything is OK.

Up to my C-programmer experience I can suggest that my variables
in Perl works improperly (see testcase) in some situations.

How to reproduce the problem.
There are two test cases that are variants of the same program.

To generate the debugging output please use​:

# perl badguy.pl > badguy.out

# perl dbadm.pl > dbadm.out
Please keep the files that are distributed with the bug report.
Debugger sequence​:

# perl -d badguy.pl

b 1001

r

T

s

T

q
In the stack frames look at the 3rd line from the top - frame for the
CalculateExpr().

What is wrong.
What was detected​: there is a subroutine
sub CalculateExpr {

.....
It includes the following piece of code​:
my $DBName_C;

($DBName_C,$FExpr,$Reg)=@​_;

.....
print "BEFORE CalculateExpr(@​_)​:: DBName_C=$DBName_C,
FExpr=$FExpr, Reg=$Reg\n";
# $dbname=$DBName_C;

# @​save = @​_;
%RecordsMatchsCondition =
CalculateConditions($DBName_C,$Condition);
# @​_ = @​save;

# $DBName_C=$dbname;
print "AFTER CalculateExpr(@​_)​:: DBName_C=$DBName_C,
FExpr=$FExpr, Reg=$Reg\n";

We found that

1. @​_ variable is different BEFORE and AFTER the call to CalculateConditions .

2. The value of local (defined as my ) variable $DBName_C
is changed after this call.
Nobody expected that the local variable could be changed after the soubroutine
call...

And nobody expected that the arguments vector could be modified implicitly.
Please look at lines with the words BEFORE and AFTER in badguy.out log
file.
BEFORE CalculateExpr( Orders Goods.SUnitPrice * NUnitsInOrd where
Goods.<RecordNumber> == GooCode 0)​:: DBName_C=Orders , FExpr=Goods.SUnitPrice
* NUnitsInOrd where Goods.<RecordNumber> == GooCode, Reg=0
AFTER CalculateExpr( Goods Goods.SUnitPrice * NUnitsInOrd where
Goods.<RecordNumber> == GooCode 0)​:: DBName_C=Goods , FExpr=Goods.SUnitPrice
* NUnitsInOrd where Goods.<RecordNumber> == GooCode, Reg=1
Next, the function CalculateConditions has the following piece of code​:
$argc = @​_;

print(" HERE0 CalculateConditions(@​_)​::argc=$argc, DBNameC=$DBNameC,
DBName=$DBName, Condition=$Condition\n");

$calc=CalculateExpr($DB_name,$CondExpr,1);
$argc = @​_;

print(" HERE1 CalculateConditions(@​_)​::argc=$argc, DBNameC=$DBNameC,
DBName=$DBName, Condition=$Condition\n");
Please look into badguy.out​:
HERE0 CalculateConditions( Orders Goods.<RecordNumber>
== GooCode)​::argc=2, DBNameC=Orders, DBName=Goods, Condition=

ENTER CalculateExpr(Goods GooCode 1)​:: DBName_C=Goods, FExpr=GooCode,
Reg=1

MIDDLE CalculateExpr(Goods GooCode 1)​:: DBName_C=Goods, FExpr=GooCode,
Reg=1

DONE CalculateExpr(Goods GooCode 1)​:: DBName_C=Goods, FExpr=GooCode,
Reg=1

REPLY CalculateExpr​::RetValue=2

HERE1 CalculateConditions( Goods )​::argc=2, DBNameC=Orders,
DBName=Goods, Condition=
And the value of @​_ before and after the call to CalculateExpr is different.

Nobody had the intention to use references, so we expect that all variables
are just copies of the values, not the references to the other values or
variables...
Perl manpage says​:
@​_
Within a subroutine the array @​_ contains
the parameters passed to that subroutine. See the perlsub manpage.
In our testcase it looks that it may be changed implicitly by unknown
actor.

At least it shows effects that couldn't happen if @​_ is just an array
of the values, not references.

Debugging and the place that makes bad thing.
Using perl -d badguy.pl I found the point where all this mess happens.

Function calls stack BEFORE the mess looks like this (top-down)​:

GetFieldsNamesList( 'Goods' , 'd​:\project\data');

CalculateConditions('Orders', 'Goods.<RecordNumber>.....');

CalculateExpr( 'Orders' , 'Goods.SUnitPrice');

CheckAndCount(5);

AddToDB('Orders');
set breakpoint at line 1001.

This is the following code in the
sub GetFieldsNamesList {
local $RecordLen,$DBPack;
my $Mode=''; #Only read

my $Regim=0; #Not full in array for calculating
fields

my @​FieldNames,

$DBName,$DBDir;
# here OK

($DBName,$DBDir) = @​_;

# here CORRUPTED NOW
@​FieldNames=OpenDB($DBName,$DBDir,$Mode,$Regim);
Before the ($DBName, ...) = @​_;

stack looks as it was described above.

After this stack of calls looks like this​:

GetFieldsNamesList( 'Goods' , 'd​:\project\data');

CalculateConditions('Orders', 'Goods.<RecordNumber>.....');

CalculateExpr( 'Goods' , 'Goods.SUnitPrice');

CheckAndCount(5);

AddToDB('Orders');
and the DBName in CalculateExpr changes its value.

What is wrong​:

1. We assign the value to my variable in the topmost
frame.

This change should be local to this frame.

2. Instead, this assignment affects two other places​:

a) the variable that has been declared as my
in the underlying frame.

b) the arguments array for underlying CalculateExpr
subroutine.

In C language this may happen ONLY if the element of the vector is
a pointer to the

variable being changed and the my variables inside the stack
and at the top of stack

are placed into the same memory space.
Since the variables have different names and are declared as my,
we
can suppose that they are not the same variable occupying the same memory
location. And all the elements of @​_ were supposed to be local copies of
the values, not the reference to anything else. So I can call this a BUG
in variables handling subsystem.

Once again.
Assignment to the my variable in the topmost function calls frame
modifies both the my variable in the underlying frame (that variable
has different name by the way) and modifies the @​_ arguments vector of
that underlying subroutine. This is just the madness...

More failures.
The second sample dbadm.pl eliminates some unnecessary subroutines.

In this case the @​_ is NOT corrupted, however the value of $DBName_C
is still changed for the unknown reason.

Look again at the lines BEFORE and AFTER, at the value of $DBName_C.
Next bad news is that I was not able to reproduce this messy behavior
with the special simplified test case.

Take a look at the file 04.pl -- it is a model of the mainstream program.
However in this case everything works fine and the corruption doesn't happen.

Help needed.
Questions are​:

1. Will this behaviour appear in the latest version of Perl?
Answer is​: YES. Perl 5.005_02 under UNIX shows the same effect.

2. Will it happen on UNIX version? Answer is​: YES.

3. May be something in the PROGRAM is wrong?
The later is very unlikely since the author of the program is a beginner
in Perl and she used only very simple and obvious constructions, expecting
that they will work mainly like C-language variables. No variables linkage
one to another was expected, no modifications of local copies of
values were expected as well.

Thanks.
In advance for either

- fixing our program.(if this is our bug; don't suggest workarounds
please)

- fixing Perl

- telling us what's wrong in the World :-)
Best regards to all,

Andrew Bogatyrev.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant