PDA

View Full Version : Evil crash bites my butt again



speeder
08-30-2010, 03:59 AM
But this time I found a script that actually trigger it rather easily...

function OnInit() //run upon initialization
end

function OnPostInit() //run during the entity's first logic update
thisMap = this:GetMap();
--if --thisMap == GetMapManager:GetActiveMap() and
--not thisMap:GetName() == "Gui_Stuff" then
SpawnDefaultGui(); -- I am using a function in case I decide to support multiple GUIs
--end
end

function OnKill() //run when removed
DeleteDefaultGui();
end

function SpawnDefaultGui()
BigBar = GetEntityByName("power_up_bar_big_template");
YellowBar = GetEntityByName("power_up_bar_yellow_template");
PinkBar = GetEntityByName("power_up_bar_pink_template");
WhiteBar = GetEntityByName("power_up_bar_white_template");
GreenBar = GetEntityByName("power_up_bar_green_template");

GuiCover = GetEntityByName("gui_cover_template");

big_bar = BigBar:Clone(thisMap, Vector2(0, 0));
yellow_bar = YellowBar:Clone(thisMap, Vector2(0, 0));
pink_bar = PinkBar:Clone(thisMap, Vector2(0, 0));
white_bar = WhiteBar:Clone(thisMap, Vector2(0, 0));
green_bar = GreenBar:Clone(thisMap, Vector2(0, 0));
gui_cover = GuiCover:Clone(thisMap, Vector2(58, -6));
end

function DeleteDefaultGui()
safe_delete(big_bar);
safe_delete(yellow_bar);
safe_delete(pink_bar);
safe_delete(white_bar);
safe_delete(green_bar);
safe_delete(gui_cover);
end

function safe_delete(entity)
if entity then entity:SetDeleteFlag(true); end
end


First, the "safe_delete" is totally non-safe, because it generate a error when entity is nil "big_bar does not exist"

Anyway, it sorta worked, but as soon as I delete some object and re-loaded the script, the engine crashed...

The same crash as the mentioned "random" crash in other topic.

I realized that the engine hates when you call SetDeleteFlag(true) twice, it plainly crashes sometimes when you do that... So, there are a way to fix any of the issues I mentioned here? Including a way to allow me to "delete" stuff that is not even created yet?

Pleng
12-10-2010, 03:09 PM
Cant you check if the Entity exists before trying to remove it?

If !(GetEntityByName('big_bar-)=nil
{
safe_delete(big_bar);
}

speeder
12-10-2010, 03:30 PM
I guess I will have to edit the C++ later, doing that in Lua totally don't work.

But for now I am managing to avoid it with careful (VERY) lua coding.

Seth
12-11-2010, 12:04 AM
Calling entity:SetDeleteFlag(true) twice in a row shouldn't crash the engine as "entity" still exists until the end of the logic cycle. (if it does, that is a bug)

However, refering an entity pointer after an entity has been deleted would - as it's just a pointer to random memory at that point.

You should probably be doing:

safe_delete(big_bar); big_bar = nil;

to make sure you don't do that, otherwise the "safe_delete" function really has no meaning.

speeder
12-11-2010, 12:10 AM
I noticed the crashes are triggered when I delete something, and the engine was going to delete it for another reason, like deleting a entity and then unloading the map.

This trigger two deletes (and thus a deletion of a random pointer).

speeder
12-25-2010, 06:58 PM
The game is not frequently crashing, it crashes when closing, it crashes when unloading a map, it crashes when manipulating Watch Manager, and so on...

But in all crashes, no matter how the stack trace looks (sometimes it look wildly different) one line is ALWAYS present:


sig_delete(m_ID); (BaseGameEntity.cpp line 52)



This is greatly bothering me, obviously the deleteflag thing is deleting invalid stuff, but I am not figuring how to figure if something is valid or not (specially because m_ID is a int, not a pointer, thus I cannot just verify if m_ID is valid or not).

Seth
12-26-2010, 12:18 AM
Hey Speeder, I'm back at the computer in IRC if you want to try again there btw..

I think you are using Novashell in a way that I didn't plan, because the examples don't seem to have this problem.

Is it possible for you to make a tiny test project that shows the error and attach it? If so I'd be glad to take a look at it. This test should cause the crash on my version of Novashell. (if it doesn't, it might point to a chance you made as the culprit)

speeder
12-26-2010, 12:45 AM
Hello

No need to make a test case, I found out how exactly how it happen (usually... that is...)


Create two entities (entity A and entity B).

Put on the OnKill of EntityB: referenceToEntityA:SetDeleteFlag(true)

Then unload the map or reload the engine or quit the engine.

If you are unlucky (or lucky :P), EntityA will get deleted when Screen is deleted on C++ before EntityB.

Then during EntityB deletion, it calls OnKill, that calls SetDeleteFlag on the non-existing EntityA.

C++ actually allows you to call a method of a non-existing object, and the function runs fine until it actually need data on EntityA, then it crashes.


The workaround solution is: Don't delete stuff on "OnKill" (what I did).

But this does not guarantee you won't trigger this bug by accident in other manner.

The other solution is somehow prevent any call to SetDeleteFlag on a non-existing object, on C++ calls this is done (you check if the pointer is null), but on Lua it blindly calls the method...

I thought of many possibilities, but I could not figure a way to prevent a dangling pointer on Lua to call a method of a non-existing thing, at least not without causing a error message.


EDIT: I am not hanging on IRC because someone on Ludumdare dislike me, and keep complaining to ops (even of other channels), once even I said something on Ludumdare that a op in Gamedev disagreed, and I got banned from there... Since Afternet banned msot of IPs of my country, I won't go to the hassle of getting on Afternet to get banned on Ludumdare or Gamedev because of some guy that never cared to show himself.

Seth
12-26-2010, 01:09 AM
No need to make a test case, I found out how exactly how it happen (usually... that is...)

Good, but that is the test case, and if you make the project (dead simple, crashes when you hit the unload map button or whatever) I'll take a look. :sweatdrop: