-
Notifications
You must be signed in to change notification settings - Fork 150
Description
When using dollar variables with ModuleOption maximum or ModuleOption minimum it is possible to crash TFORM. In AssignDollar the general structure for a multi-term RHS is:
new sort, generator, endsort
lock the dollar
free its data
put the data allocated by endsort
unlock the dollar
The problem comes when the RHS depends on the dollar itself, as in:
#-
Symbol x,i;
Local test = sum_(i,0,100,x^i);
.sort
#$pow = 1;
$pow = $pow + 1;
ModuleOption, maximum $pow;
.sort
#message $pow = `$pow'
.end
Here, one thread may try to access the dollar variable data after another thread has freed the pointer.
The fix is easy: move the lock before we start working out the RHS. This might have a performance impact, but presumably people do not generally use very hard-to-work-out RHS in combination with ModuleOption maximum etc.
Actually, ModuleOption maximum and ModuleOption minimum do not work like I thought. My impression has always been that they are similar to ModuleOption local, but with a final step of taking the proper value from per-thread copies at the end of execution.
But actually, the maximum (or minimum) value is continually updated, with locks, during execution. This means one can write scripts which work properly in TFORM but not in FORM. Instead of the usual construction like
If (Count(x,1) > $pow) $pow = count_(x,1);
ModuleOption maximum $pow;
.sort
#message $pow = `$pow'
one can use
$pow = count_(x,1);
ModuleOption maximum $pow;
.sort
#message $pow = `$pow'
which produces the wrong value in FORM.
Also in TFORM the following code is a bit counter-intuitive:
$pow = count_(x,1);
If (Count(x,1) == $pow);
Print "t: %t";
EndIf;
ModuleOption maximum $pow;