BUG: Greater than 0 if statement crash.

I think I’ve found a bug in Corona, either that or I’m doing something thats not supported… I have the following if statement, that’s currently nested in 2 other if statements.

if scene.lives \> 0 then  
 scene.hudLives.objects[scene.lives]:removeSelf()  
 scene.lives = scene.lives - 1  
end  

This seems to crash Corona every time. If I change scene.lives \> 0 to scene.lives \>= 0 then it won’t crash the simulator… Just wondering what’s going on…

Thanks!

-Jake [import]uid: 144504 topic_id: 33332 reply_id: 333332[/import]

Oh, and this is the crash report.

http://pastebin.com/SN2bKZQU [import]uid: 144504 topic_id: 33332 reply_id: 132351[/import]

Hard to say what’s happening without more code to see. At first glance, this appears to be a fairly odd way to “nest” all of these tables and indexes. My guess is this is a Lua, perhaps a parent-child removal error.

Brent [import]uid: 9747 topic_id: 33332 reply_id: 132355[/import]

@jake72,

Hi. Is this code, part of a lives HUD that display images for each life?

I’m talking about something like the HUD in the upper-left of this video:

http://www.youtube.com/watch?v=6RXeaAWfwSU

If the answer is, “Yes”, and if you are stuck I can suggest an alternative means to solving your HUD needs.

Just post back if you need/want this kind of help. [import]uid: 110228 topic_id: 33332 reply_id: 132375[/import]

Yes it is, and I have the tables/groups nested like that because then it is easy to remove and orginize that way… Unless it is a performance issue… Anyways why would this make the simulator crash? And how could I fix this?

Thanks!

-Jake [import]uid: 144504 topic_id: 33332 reply_id: 132420[/import]

@jake72,
I assume you’re saying Yes to me and not Brent. Its hard to tell.

As far as how your organize you code, I think you should go with what makes sense for you. I (an and I think Brent) am a little confused by the level of indirection going on. That said, again use what works for you.

What about performance? Sure maybe there is a more efficient way to go, but until you measure you won’t know. I suggest not worrying about it for now. As long as your game performs well on your target devices you’re OK. Again, work the way that works best for you and change/learn as you go along. (Some folks will probably want to smack me for saying that, but I think right now you’re more worried about getting the darn thing working.)

Finally, let’s talk about the crash. I am not convinced the crash is occurring in that piece of code. I looked at the dump and from what I could see, your code died while executing the collision listener. Beyond that I can’t tell. I really need to see more code. In fact, if it isn’t too long the entire collision handler would be helpful.

Short of seeing all your code, please consider instrumenting the code with print statements like this:

[lua]if(scene) then
print(“A”, scene, scene.lives )
else
print(“A - SCENE MISSING”)
end

if scene.lives > 0 then

if(scene.hudLives) then
print(“B - scene.hudLives found” )
else
print(“B - scene.hudLives NOT FOUND” )
end

if(scene.hudLives,objects) then
print(“C - scene.hudLives.objects found” )
else
print(“C - scene.hudLives.objects NOT FOUND” )
end
if(scene.hudLives.objects[scene.lives]) then
print(“D - scene.hudLives.objects[scene.lives] found”, type(scene.hudLives.objects[scene.lives]) )
else
print(“D - scene.hudLives.objects[scene.lives] NOT FOUND” )
end

local theObj = scene.hudLives.objects[scene.lives]

if(theObj.removeSelf and type(theObj.removeSelf) == “function” ) then
print(“E - theObj is a valid display object” )
else
print(“E - theObj is NOT a valid display object” )
end
scene.hudLives.objects[scene.lives]:removeSelf()

if(scene.hudLives) then
print(“F - scene.hudLives found” )
else
print(“F - scene.hudLives NOT FOUND” )
end

scene.lives = scene.lives - 1
end
if(scene.lives) then
print(“G”, scene, scene.lives )
else
print(“G - SCENE MISSING”)
end[/lua]

Yes, this is horrible and unsophisticated, but I’d love to see the output nonetheless. Without access to your code, consider this my ‘remote debugger’. :slight_smile:

Just use the code, run till failure and grab the output of the console. Note: If the console crashes too, you may have to redirect the output to a file and get the file contents.

If you get stuck on this write back and we’ll figure out a way to get some debug output. Oh, and anyone still reading at this point who has a better suggestion for getting a sense of what this code is doing without actually having it, please shoot your suggestions this way.

-Ed

[import]uid: 110228 topic_id: 33332 reply_id: 132443[/import]

That callstack is coming from Box2D, leading me to be suspicious of the removeSelf call, since I’m assuming it’s an object with physics. It could also make sense that >= removes the crash since lives is probably not often -1.

Is that if statement in a collision detection callback possibly? It’s not a good idea to remove an object while a collision is being resolved, so maybe you could use timer.performWithDelay(1, function() …:removeSelf() end) to remove it after the collision is handled. [import]uid: 134101 topic_id: 33332 reply_id: 132454[/import]

Sorry, I realize that was confusing. I’ll add that and run it today, for the moment here is the listener function…

function gameObjects.sensor.listener( event )  
 -- If object is object1 (not power-up) and if lives are sufficient then remove object1, and subtract from lives.  
 if event.other.name == "object1" and scene.lives \>= 0 then  
 event.other:removeSelf()  
 print( event.other.name..": destroyed" )  
 if scene.debug == false then  
 if scene.lives \> 0 then  
 scene.hudLives.objects[scene.lives]:removeSelf()  
 scene.lives = scene.lives - 1  
 end  
 print( scene.lives )  
 end  
 if scene.lives == 0 then  
 -- If lives are no more, then do game over sequence.  
 storyboard.showOverlay( "gameOver", { isModal = true } )  
 timer.cancel( scene.timers.spawn )  
 print( "\n\n GAME OVER \n\n" )  
  
 end  
 end  
end  

Maybe it’s a problem with removing the object during a collision? Anyways I’ll add that to my function and post that soon…

-Jake [import]uid: 144504 topic_id: 33332 reply_id: 132457[/import]

Ntero: Yeah, maybe, I’ll test with an event.phase == “ended” and see if that fixes it… [import]uid: 144504 topic_id: 33332 reply_id: 132458[/import]

And here is the debug code:

A table: 0x109d839f0 3 B - scene.hudLives found C - scene.hudLives.objects found D - scene.hudLives.objects[scene.lives] found table E - theObj is a valid display object F - scene.hudLives found G table: 0x109d839f0 2 A table: 0x109d839f0 2 B - scene.hudLives found C - scene.hudLives.objects found D - scene.hudLives.objects[scene.lives] found table E - theObj is a valid display object F - scene.hudLives found G table: 0x109d839f0 1 A table: 0x109d839f0 1 B - scene.hudLives found C - scene.hudLives.objects found D - scene.hudLives.objects[scene.lives] found table E - theObj is a valid display object F - scene.hudLives found G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 [import]uid: 144504 topic_id: 33332 reply_id: 132459[/import]

From the Corona Docs (Gotchas on the collision event):
http://docs.coronalabs.com/api/event/collision/index.html
[text]
Restrictions on Modifying Objects
The objects involved in the collision should not be removed or any of it’s properties altered during a collision event. You should use timer.performWithDelay() if they want to modify object position values or other properties within the collision events.

Removing the object or modifying the properties in the collision event could cause the simulator to crash.
[/text]

Even if it’s not a collision object, you should be reluctant about removing anything inside of collision events. using performWithDelay, with a timer of 1, allows you to designate a ‘next frame’ operation.

Also, that event.other:removeSelf is definitely going to cause you major issues. [import]uid: 134101 topic_id: 33332 reply_id: 132460[/import]

(Edit: Looks like Ntero and I were posting at the same time there. Rather I was typing while Ntero was pressing submit.)

@jake72,

  1. Is the scene variable a reference to a table {} or is it a reference to a display group? It looks like a plain table.

  2. Is line 39 of the dump the end and then the game crashed? i.e. Did it just keep printing A, G messages over and over or did it completely crash.

  3. Ntero is likely on to something. If you’re deleting a physics object in the middle of processing you could get into trouble. (Sorry I misread that dump. I don’t look at them all that often and didn’t even notice the fact that the functions were signed org.Box2D.Box2D …)

You might try a deferred removal to see if that helps:
[lua]timer.performWithDelay( 10, function() scene.hudLives.objects[scene.lives]:removeSelf() end )[/lua]

This should keep the removal from occurring till after you get out of the box2D processing code as well as your current handler.

-Ed

[import]uid: 110228 topic_id: 33332 reply_id: 132461[/import]

Oh, and this is the crash report.

http://pastebin.com/SN2bKZQU [import]uid: 144504 topic_id: 33332 reply_id: 132351[/import]

Hard to say what’s happening without more code to see. At first glance, this appears to be a fairly odd way to “nest” all of these tables and indexes. My guess is this is a Lua, perhaps a parent-child removal error.

Brent [import]uid: 9747 topic_id: 33332 reply_id: 132355[/import]

@jake72,

Hi. Is this code, part of a lives HUD that display images for each life?

I’m talking about something like the HUD in the upper-left of this video:

http://www.youtube.com/watch?v=6RXeaAWfwSU

If the answer is, “Yes”, and if you are stuck I can suggest an alternative means to solving your HUD needs.

Just post back if you need/want this kind of help. [import]uid: 110228 topic_id: 33332 reply_id: 132375[/import]

  1. It is created with the storyboard.newScene() functions…

  2. A timer spawns multipule object1s, until lives = 0 and it is canceled, and then after thet go off screen, and the “sensor” object thats a isSensor physics object detects a collision and runs the lister function. It is fine with everything until it hits 0, and another object hits the sensor, where it crashes…

  3. Yes, I think it may have something to do with that but it has no problem until the lives hit 0 and another object comes over the sensor…

Thanks!

-Jake [import]uid: 144504 topic_id: 33332 reply_id: 132518[/import]

Yes it is, and I have the tables/groups nested like that because then it is easy to remove and orginize that way… Unless it is a performance issue… Anyways why would this make the simulator crash? And how could I fix this?

Thanks!

-Jake [import]uid: 144504 topic_id: 33332 reply_id: 132420[/import]

@jake72,
I assume you’re saying Yes to me and not Brent. Its hard to tell.

As far as how your organize you code, I think you should go with what makes sense for you. I (an and I think Brent) am a little confused by the level of indirection going on. That said, again use what works for you.

What about performance? Sure maybe there is a more efficient way to go, but until you measure you won’t know. I suggest not worrying about it for now. As long as your game performs well on your target devices you’re OK. Again, work the way that works best for you and change/learn as you go along. (Some folks will probably want to smack me for saying that, but I think right now you’re more worried about getting the darn thing working.)

Finally, let’s talk about the crash. I am not convinced the crash is occurring in that piece of code. I looked at the dump and from what I could see, your code died while executing the collision listener. Beyond that I can’t tell. I really need to see more code. In fact, if it isn’t too long the entire collision handler would be helpful.

Short of seeing all your code, please consider instrumenting the code with print statements like this:

[lua]if(scene) then
print(“A”, scene, scene.lives )
else
print(“A - SCENE MISSING”)
end

if scene.lives > 0 then

if(scene.hudLives) then
print(“B - scene.hudLives found” )
else
print(“B - scene.hudLives NOT FOUND” )
end

if(scene.hudLives,objects) then
print(“C - scene.hudLives.objects found” )
else
print(“C - scene.hudLives.objects NOT FOUND” )
end
if(scene.hudLives.objects[scene.lives]) then
print(“D - scene.hudLives.objects[scene.lives] found”, type(scene.hudLives.objects[scene.lives]) )
else
print(“D - scene.hudLives.objects[scene.lives] NOT FOUND” )
end

local theObj = scene.hudLives.objects[scene.lives]

if(theObj.removeSelf and type(theObj.removeSelf) == “function” ) then
print(“E - theObj is a valid display object” )
else
print(“E - theObj is NOT a valid display object” )
end
scene.hudLives.objects[scene.lives]:removeSelf()

if(scene.hudLives) then
print(“F - scene.hudLives found” )
else
print(“F - scene.hudLives NOT FOUND” )
end

scene.lives = scene.lives - 1
end
if(scene.lives) then
print(“G”, scene, scene.lives )
else
print(“G - SCENE MISSING”)
end[/lua]

Yes, this is horrible and unsophisticated, but I’d love to see the output nonetheless. Without access to your code, consider this my ‘remote debugger’. :slight_smile:

Just use the code, run till failure and grab the output of the console. Note: If the console crashes too, you may have to redirect the output to a file and get the file contents.

If you get stuck on this write back and we’ll figure out a way to get some debug output. Oh, and anyone still reading at this point who has a better suggestion for getting a sense of what this code is doing without actually having it, please shoot your suggestions this way.

-Ed

[import]uid: 110228 topic_id: 33332 reply_id: 132443[/import]

That callstack is coming from Box2D, leading me to be suspicious of the removeSelf call, since I’m assuming it’s an object with physics. It could also make sense that >= removes the crash since lives is probably not often -1.

Is that if statement in a collision detection callback possibly? It’s not a good idea to remove an object while a collision is being resolved, so maybe you could use timer.performWithDelay(1, function() …:removeSelf() end) to remove it after the collision is handled. [import]uid: 134101 topic_id: 33332 reply_id: 132454[/import]

Sorry, I realize that was confusing. I’ll add that and run it today, for the moment here is the listener function…

function gameObjects.sensor.listener( event )  
 -- If object is object1 (not power-up) and if lives are sufficient then remove object1, and subtract from lives.  
 if event.other.name == "object1" and scene.lives \>= 0 then  
 event.other:removeSelf()  
 print( event.other.name..": destroyed" )  
 if scene.debug == false then  
 if scene.lives \> 0 then  
 scene.hudLives.objects[scene.lives]:removeSelf()  
 scene.lives = scene.lives - 1  
 end  
 print( scene.lives )  
 end  
 if scene.lives == 0 then  
 -- If lives are no more, then do game over sequence.  
 storyboard.showOverlay( "gameOver", { isModal = true } )  
 timer.cancel( scene.timers.spawn )  
 print( "\n\n GAME OVER \n\n" )  
  
 end  
 end  
end  

Maybe it’s a problem with removing the object during a collision? Anyways I’ll add that to my function and post that soon…

-Jake [import]uid: 144504 topic_id: 33332 reply_id: 132457[/import]