Page 1 of 1

Found an anomaly

Posted: Fri Jul 11, 2014 12:15 am
by dunbarx
There is another thread about timers:

http://forums.livecode.com/viewtopic.php?f=8&t=13090

While playing around with this, I finally found a case where stepping through a handler works fine but running it causes, not an error, but rather a recursion alert. Reliably.

Make two buttons and two fields. Place this into button 1:

Code: Select all

on mouseUp
   set the status of this card to "timing"
   put random (10) into fld 1
end mouseUp
And this into button 2:

Code: Select all

local startingTime

on mouseUp
   put the milliseconds into startingTime
   timeEvent startingTime
end mouseUp

on timeEvent startingTime
   if the status of this card = "timing"  then put the milliseconds - startingTime into fld 2
   if the mouse is down then
      set the status of this card to ""
      divide fld 2 by 1000
      wait 1 with messages --tried this to see if it did anything. It does not. 
      exit to top
   end if
   send "timeEvent" && startingTime to me
end timeEvent
Clicking on btn 1 sets up the process, loading a small integer into fld 1. The idea is to estimate the time in seconds of that value, with two successive clicks on btn 2. If I do this, I always get a valid result in fld 2, and always a recursion alert. If I step through the handler, though, I always get nothing at all. Place a breakpoint at the "wait' line to see this behavior.

I would love to know if anyone else sees this, and further, that this is a replicable example of this issue.

Craig Newman

Re: Found an anomaly

Posted: Fri Jul 11, 2014 12:37 am
by FourthWorld
Or more simply:

Code: Select all

on foo
  foo
end foo
Why would you not expect a recursion error when something keeps calling itself in a tight loop?

Re: Found an anomaly

Posted: Fri Jul 11, 2014 4:40 am
by dunbarx
Richard.

Hmmm. I am exiting quickly, with a millisecond difference of only a few thousand in that result field. I thought that meant that I am not going over the 40,000 call limit. Writing to the field is sort of like waiting for a small interval, and I can see the counter running in the thousands place. Am I wrong about this "loop" interpretation of the value of that field? I will think about it.

Craig

Re: Found an anomaly

Posted: Fri Jul 11, 2014 5:27 am
by FourthWorld
dunbarx wrote:Richard.

Hmmm. I am exiting quickly, with a millisecond difference of only a few thousand in that result field. I thought that meant that I am not going over the 40,000 call limit.
If I'm reading the code correcly, the field is storing a difference between millisecs, not iterations.

Re: Found an anomaly

Posted: Sat Jul 12, 2014 2:42 am
by dunbarx
Richard.

I was not counting the millisecond difference as a counter. I was informally watching that counter and considering it as an indicator of the number of calls. In this sense the number of calls should be less than the value of the field. In other words, since each update of the field reflects one call of the handler, the number of calls should be less, and certainly no more than, the field value. That difference might be whatever it feels like, but should not be more than the "index" of the number of calls, which increment by single digits:

Call 1 -- some millisec difference value
Call 2 -- some larger millisec difference value
Call 3 -- some even larger millisec difference value
etc.

I think.

But my question was more this: why does the recursion alert come after the handler ends? I certainly see how it can come in the middle of a runaway process. The one I run has a clean exit, and it is as if there is a queued number of calls that are banked after that ending. I am concerned that this question is related, and therefore reflects the same brain issues, as the recent thread I started about nested handler calls. What am I misunderstanding?

Craig

Re: Found an anomaly

Posted: Sat Jul 12, 2014 3:04 am
by dunbarx
Not sure anyone is interested in this sort of minutiae, but I think the anomaly I mentioned involves interface elements. The original idea was that the user be able to press the same button to start and then stop a timing process. I made a change to the code to watch the number of calls. It made things odd:

Code: Select all

local startingTime

on mouseUp
      put the milliseconds into startingTime
   put 0 into line 2 of fld 2
   timeEvent startingTime
end mouseUp

on timeEvent startingTime
   if the status of this card = "timing"  then put the milliseconds - startingTime into line 1 of fld 2
   if the mouse is down then --This is very wierd
   -- if the optionKey is down then --This is reliable
      set the status of this card to ""
      divide line 1 of fld 2 by 1000
      wait 1 with messages --tried this to see if it did anything. It does not. 
      exit to top
   end if
add 1 to line 2 of fld 2
   send "timeEvent" && startingTime to me
end timeEvent
Not sure I can understand this at all. The "mouse is down" option does really odd things. The "optionKey is down" works like I would have thought it had to. And why does the value in field 1 change???

Craig

Re: Found an anomaly

Posted: Sat Jul 12, 2014 5:52 am
by FourthWorld
Thanks for the patient clarification. Intrigued, I copied the code into a stack there and I'm definitely seeing an anomalry: it consistently bails with a recursion error at iteration 621.

However, this is on Ubuntu 14.04, rather than Mac OS X, and I'm getting the handler interrupted rather than seeing the error after the mouse has been clicked. This difference may be due to the many oddities in the Mac event manager (the sort of thing that requires us to use the ol' "wait 0 with messages" trick just to get visible updates, something never needed on other platforms), but it doesn't explain why the recursion is being reported at all after just 621 iterations.

Re: Found an anomaly

Posted: Sat Jul 12, 2014 6:48 am
by Simon
I'm getting on Win 7 the recursion error at iteration 769.

Simon

Re: Found an anomaly

Posted: Sat Jul 12, 2014 2:03 pm
by dunbarx
I get what I originally wrote about, a sort of odd runaway action that bypasses what I wanted, and thought I scripted. If I place a soft breakpoint at, say, the "wait" line, and click the button a second time, the handler ends normally if I then step through. If I do not place that breakpoint, all hell breaks loose, the second line of the field starts to "count", and the only way out is cmd-period.

Oh, and did I mention that a spurious integer is placed into field 1?

Craig

Re: Found an anomaly

Posted: Sat Jul 12, 2014 5:14 pm
by jacque
A handler isn't removed from the queue until after its "end" line runs. Since neither of the "send" commands use an "in time" structure, every command that uses it goes on the queue. Basically that means the initial mouseUp never completes, nor any of the timeEvent iterations. Eventually a recursion error happens. Adding any amount of time to the send command, even zero, will fix it because each handler will complete before it runs again.

I'm not sure, but I wonder if the mouse check acts strangely because the initial mouseUp never completed. Essentially the mouse check is happening repeatedly inside a very deeply nested mouseUp handler.

Edit: The mouseUp handler doesn't use send, it just calls the handler directly. But it should use send-in-time, since the direct call also doesn't allow the mouseUp to complete.

Re: Found an anomaly

Posted: Sat Jul 12, 2014 8:11 pm
by jacque
dunbarx wrote:If I place a soft breakpoint at, say, the "wait" line, and click the button a second time, the handler ends normally if I then step through. If I do not place that breakpoint, all hell breaks loose, the second line of the field starts to "count", and the only way out is cmd-period.
By necessity, the script editor must interrupt the message flow and intervene, so it will introduce enough idle periods for handlers to complete and exit.

Re: Found an anomaly

Posted: Sat Jul 12, 2014 8:11 pm
by dunbarx
Jacque.

I understand that the execution of handlers is not "perfect", in the sense that mental constructs do not sync perfectly with machine constructs. Hence the inclusion of "wait (even 0) with messages", as a technique, often allows the engine to catch its breath.

I have such a line, though. It makes no difference. But surely the issue lies somehow in what you mention; it just is not apparent to me where.

Craig

Re: Found an anomaly

Posted: Sat Jul 12, 2014 11:17 pm
by jacque
Waiting with messages allows other background processes to happen but does not clear the call stack (the message queue.) I wouldn't expect it to; if it did, it would be a bug. Handlers must always complete. I probably shouldn't have used the term "idle" because I'm not sure that's correct here.

I don't know exactly how the debugger works, but it's doing something that prevents the call stack from accumulating too much cruft. For us normal peons, the backup has to be avoided by sending messages in time. I've been bitten by this enough that I pay attention now, and make sure that any handler that calls itself is sent in time rather than called directly.