[Vm-dev] Re: Bug with valueWithReceiver:arguments:

Andreas Raab andreas.raab at gmx.de
Sun Oct 26 12:39:04 UTC 2008


Hi Frederic -

Congrats! You found the first real VM bug in five years or so ;-) I'm 
not completely sure what the problem is but there is obviously something 
wrong here. It's easiest to recreate the problem by copying the #/ 
method and simply do something like:

SmallInteger>>foo: aNumber
	"(SmallInteger>>#foo:) valueWithReceiver: 11 arguments: {2}"
	<primitive: 10>
self halt.
	aNumber isZero ifTrue: [^(ZeroDivide dividend: self) signal].
	(aNumber isMemberOf: SmallInteger)
		ifTrue: [^(Fraction numerator: self denominator: aNumber) reduced]
		ifFalse: [^super / aNumber]

When you run this, you'll see that the debugger shows *two* frames with 
SmallInteger>>foo: on them. Inspecting the "parent" frame will 
eventually crash the system since it has a completely bogus stack 
pointer (-1).

It seems that in a failing primitive method we end up with a bogus 
activation record in primitiveExecMethodWithArgs (removing the primitive 
from the above makes it work fine). I'm somewhat at a loss here as to 
what the problem might be given that the implementations of 
primPerformWithArgs and primExecWithArgs are so similar but 
interestingly, the equivalent:

	11 perform: #foo: withArguments:{2}.

works fine with or without the primitive. Somewhere there must be a 
difference ...

Cheers,
   - Andreas

Frederic Pluquet wrote:
> Hello,
> 
> I found a fondamental bug in Squeak and Pharo. The next code
> 
> 11 / 2 
> 
> gives the fraction (11/2). It's correct. But the next code
> 
> (SmallInteger>>#/) valueWithReceiver: 11 arguments: {2}
> 
> gives 1 !
> 
> The problem is the method valueWithReceiver:arguements: is used hugely 
> with method wrappers...
> 
> After long time of debugging, I found a point to debug: this method 
> don't have the good behavior with compiled methods having a primitive 
> that fails and executes some code after (as in SmallInteger>>#/ method 
> when the division don't give a whole integer). In fact, when I send this 
> message, the vm executes normally the compiled method but, in place of 
> returns simply the good result, seems to rerun the the compiled method 
> with other arguments (completly wrong) and returns so a wrong result.
> 
> For example, 
> (SmallInteger>>#/) valueWithReceiver: 11 arguments: {2}
> 
> has the following execution trace :
> 
> 2 isZero
> |  2 = 0
> |  returns: false
> returns: false
> 2 isMemberOf: SmallInteger
> |  2 class
> |  returns: SmallInteger
> |  SmallInteger == SmallInteger
> |  returns: true
> returns: true
> Fraction numerator: 101 denominator: 2
> |  Fraction new
> |  |  Fraction basicNew
> |  |  returns: a Fraction instance
> |  |  (a Fraction instance) initialize
> |  |  returns: a Fraction instance
> |  returns: a Fraction instance
> |  a Fraction instance setNumerator: 101 denominator: 2
> |  |  2 = 0
> |  |  returns: false
> |  |  101 asInteger
> |  |  returns: 101
> |  |  2 asInteger
> |  |  returns: 2
> |  |  2 abs
> |  |  |  2 < 0
> |  |  |  returns: false
> |  |  returns: 2
> |  |  2 < 0
> |  |  returns: false
> |  returns: (101/2)
> returns: (101/2)
> (101/2) reduced
> |  101 = 0
> |  returns: false
> |  101 gcd: 2
> |  |  101 = 0
> |  |  returns: false
> |  |  2 \\ 101
> |  |  returns: 2
> |  |  2 = 0
> |  |  returns: false
> |  |  101 \\ 2
> |  |  returns: 1
> |  |  1 = 0
> |  |  returns: false
> |  |  2 \\ 1
> |  |  returns: 0
> |  |  0 = 0
> |  |  returns: true
> |  |  1 abs
> |  |  |  1 < 0
> |  |  |  returns: false
> |  |  returns: 1
> |  returns: 1
> |  101 // 1
> |  returns: 101
> |  2 // 1
> |  returns: 2
> |  2 = 1
> |  returns: false
> |  Fraction numerator: 101 denominator: 2
> |  |  Fraction new
> |  |  |  Fraction basicNew
> |  |  |  returns: a Fraction instance
> |  |  |  (a Fraction instance) initialize
> |  |  |  returns: a Fraction instance
> |  |  returns: a Fraction instance
> |  |  (a Fraction instance) setNumerator: 101 denominator: 2
> |  |  |  2 = 0
> |  |  |  returns: false
> |  |  |  101 asInteger
> |  |  |  returns: 101
> |  |  |  2 asInteger
> |  |  |  returns: 2
> |  |  |  2 abs
> |  |  |  |  2 < 0
> |  |  |  |  returns: false
> |  |  |  returns: 2
> |  |  |  2 < 0
> |  |  |  returns: false
> |  |  returns: (101/2)
> |  returns: (101/2)
> returns: (101/2)
> 2 isZero
> |  2 = 0
> |  returns: false
> returns: false
> false isMemberOf: SmallInteger
> |  false class
> |  returns: False
> |  False == SmallInteger
> |  returns: false
> returns: false
> 
> 
> Please help me to fix this bug. I really need it works fine !
> 
> Fréd
> -- 
> Frédéric Pluquet
> Université Libre de Bruxelles (ULB)
> Assistant
> http://www.ulb.ac.be/di/fpluquet
> 
> 
> ------------------------------------------------------------------------
> 
> 



More information about the Vm-dev mailing list