Stop execution in the simulator during an infinite loop

I’m optimizing an infinite loop at the moment but so far it still takes a bit too long ;)  and while it runs the Corona simulator just hangs and the only thing I can do is to kill it.

Is there any other way to stop the execution in the simulator in such situations?

I would set up an enterFrame listener or coroutine, that breaks every x iterations. Then you could build a ‘stop’ button that cancels the processing and this method will give you a chance to click it before the processing resumes on the next frame.

[lua]

local currentIteration = 1

local iterationsPerFrame = 1000

local totalIterations = 1000000

local continueProcessing = true

local processLoop = function ()

  if continueProcessing then

    for i = currentIteration, currentIteration + iteractionsPerFrame, 1 do

        – do your stuff using i as index if accessing a large table or something

        currentIteration = currentIteration + 1

        if currentIteration > totalIterations then

              continueProcessing = false

              break

        end

    end

  end

end

Runtime:addEventListener(“enterFrame”, processLoop)

[/lua]

Hi nick,

thanks for your reply. Actually I just meant, if there’s a way to stop execution without killing the simulator process in case of a bug causing an infinite loop every now and then - tried to make it sound funny, but I’m probably not good at this :slight_smile:

I.e. is there a way to stop execution without preparing the code upfront to interrupt on potentially bad loops?

With regards to your suggestion - good idea - for now I’ve chosen an even simpler way - I added a max iterations counter and if it reaches it’s limit, I simply crash on purpose by indexing a nil value or similar invalid code.

Best regards,

Michael

That’s the best way, whenever I use while loops I always have a maximum number of iterations that will cause the loop to end, just by setting the ‘ok’ condition to true. I can then print a nice message telling me it went on longer than expected and the state of all the variables involved.

There is no way to stop the engine once you’re stuck in an infinite loop.

However, you might be able to set up a runtime ‘key’ event listener that would purposely cause an unhandled error, thus crashing the engine.  Still this wouldn’t respond right away if ever.

You might be able to use a hook (see also here), possibly together with some of the ideas mentioned above. This would be expensive if you need this sort of behavior in non-debugging situations, though.

There is no magic bullet, alas. You could be trying to measure the effects of running an infinite loop, after all.  :slight_smile:

I wouldn’t expect a key listener to be called in this situation but the debug hook sounds like a quite nice option as it’s only relevant during development and given there’s a line hook it would work even when a tiny inner loop gone wild.

Had an infinite loop again and gave this a try - works great.

Simple code snipped that can be added to main.lua

[lua]

local INFINITE_LOOP_COUNTER = 0

local function infiniteLoopKiller()

    INFINITE_LOOP_COUNTER = INFINITE_LOOP_COUNTER + 1

    if INFINITE_LOOP_COUNTER > 50*1000 then

        INFINITE_LOOP_BREAKER_TRIGGERED()

    end

end

local function infiniteLoopResetter()

    INFINITE_LOOP_COUNTER = 0

end

Runtime:addEventListener( “enterFrame”, infiniteLoopResetter )

debug.sethook( infiniteLoopKiller, “c” )

[/lua]

I would set up an enterFrame listener or coroutine, that breaks every x iterations. Then you could build a ‘stop’ button that cancels the processing and this method will give you a chance to click it before the processing resumes on the next frame.

[lua]

local currentIteration = 1

local iterationsPerFrame = 1000

local totalIterations = 1000000

local continueProcessing = true

local processLoop = function ()

  if continueProcessing then

    for i = currentIteration, currentIteration + iteractionsPerFrame, 1 do

        – do your stuff using i as index if accessing a large table or something

        currentIteration = currentIteration + 1

        if currentIteration > totalIterations then

              continueProcessing = false

              break

        end

    end

  end

end

Runtime:addEventListener(“enterFrame”, processLoop)

[/lua]

Hi nick,

thanks for your reply. Actually I just meant, if there’s a way to stop execution without killing the simulator process in case of a bug causing an infinite loop every now and then - tried to make it sound funny, but I’m probably not good at this :slight_smile:

I.e. is there a way to stop execution without preparing the code upfront to interrupt on potentially bad loops?

With regards to your suggestion - good idea - for now I’ve chosen an even simpler way - I added a max iterations counter and if it reaches it’s limit, I simply crash on purpose by indexing a nil value or similar invalid code.

Best regards,

Michael

That’s the best way, whenever I use while loops I always have a maximum number of iterations that will cause the loop to end, just by setting the ‘ok’ condition to true. I can then print a nice message telling me it went on longer than expected and the state of all the variables involved.

There is no way to stop the engine once you’re stuck in an infinite loop.

However, you might be able to set up a runtime ‘key’ event listener that would purposely cause an unhandled error, thus crashing the engine.  Still this wouldn’t respond right away if ever.

You might be able to use a hook (see also here), possibly together with some of the ideas mentioned above. This would be expensive if you need this sort of behavior in non-debugging situations, though.

There is no magic bullet, alas. You could be trying to measure the effects of running an infinite loop, after all.  :slight_smile:

I wouldn’t expect a key listener to be called in this situation but the debug hook sounds like a quite nice option as it’s only relevant during development and given there’s a line hook it would work even when a tiny inner loop gone wild.

Had an infinite loop again and gave this a try - works great.

Simple code snipped that can be added to main.lua

[lua]

local INFINITE_LOOP_COUNTER = 0

local function infiniteLoopKiller()

    INFINITE_LOOP_COUNTER = INFINITE_LOOP_COUNTER + 1

    if INFINITE_LOOP_COUNTER > 50*1000 then

        INFINITE_LOOP_BREAKER_TRIGGERED()

    end

end

local function infiniteLoopResetter()

    INFINITE_LOOP_COUNTER = 0

end

Runtime:addEventListener( “enterFrame”, infiniteLoopResetter )

debug.sethook( infiniteLoopKiller, “c” )

[/lua]