orxObject_Delete during update

Please see attached screenshot. I'm currently having this problem in iPhone Simulator only (not on the device or on Windows).

So far it only happens when I'm moving an object when a spawner attached (the spawner makes particles). It is intermittent, sometimes happens, sometimes does not.

I know it has happened at least the last few SVN versions.

Do you need any other info? Just let me know and I'll send it. Untitled-e7815e0481dbeb5b489f7e91d232f13f.png

Comments

  • edited April 2012
    I forgot to mention the only time I call orxObject_Delete in my code is when transitioning in between "scenes". I double-checked to make sure I don't have orxObject_Delete calls anywhere near the Update functions where this is happening.
  • edited April 2012
    Yep, I don't think it's an issue with any orxObject_Delete() call but with what orxEvent_IsSending() is returning.

    In orxObject_UpdateAll() we actually delete all the object that have expired (LifeTime = 0), but we're not in an event anymore, which means the internal send event counter has a wrong value.

    When it happens, can you look at the value of sstEvent.s32EventSendCounter? It's a static value so you should be able to inspect it when breaking anywhere in the code, even in this assert.
    It should be 0 but it's not, knowing its value will help me track the issue, thanks!
  • edited April 2012
    I actually don't understand how this can happen without a memory corruption of some sort:

    s32EventSendCounter gets initialized to 0 with a memset in orxEvent_Init(), then we only modify it in orxEvent_Send, the code looks like that:
      {
        orxEVENT_HANDLER_INFO *pstInfo;
    
        /* Updates event send counter */
        sstEvent.s32EventSendCounter++;
    
        /* For all handlers */
        for(pstInfo = (orxEVENT_HANDLER_INFO *)orxLinkList_GetFirst(&(pstStorage->stList));
            pstInfo != orxNULL;
            pstInfo = (orxEVENT_HANDLER_INFO *)orxLinkList_GetNext(&(pstInfo->stNode)))
        {
          /* Calls it */
          if((pstInfo->pfnHandler)(_pstEvent) == orxSTATUS_FAILURE)
          {
            /* Updates result */
            eResult = orxSTATUS_FAILURE;
    
            break;
          }
        }
    
        /* Updates event send counter */
        sstEvent.s32EventSendCounter--;
      }
    

    EDIT: This would potentially be an issue with multi-threaded code but orx is single-threaded...
  • edited April 2012
    I reproduced it and when the debugger hit the assert, I went to orxEvent_IsSending and see sstEvent.s32EventSendCounter == 1.
  • edited April 2012
    Ok thanks.

    Well, then I really have no idea how this is happening! I'm afraid I could only find out if I were able to run your code.

    The fact that it only happens on the simulator is a bit worrying though. What if you change the declaration of s32EventSendCounter by adding a "volatile" in front of it. Does it still happen?
  • edited April 2012
    Because this is intermittent and I don't debug on the device unless I need to, it's possible I just haven't seen it yet. Seems unlikely I wouldn't have seen it at least once, though.

    I can confidently say it has never happened on Windows, however. And it never happens when we're testing the Release version.

    It does still happen with volatile keyword in front of the s32EventSendCounter declaration.

    I mentioned earlier I'll let you look at my code before we go into beta testing.. in the meantime, anything I should be on the lookout for in my own code that could possibly affect it?

    Another thing, though--if you remember, I was having all that trouble in Xcode 4 a few months ago. This Xcode project I'm using has been through a lot. I may start fresh with the one provided in SVN and set the Equilibria project up again.
  • edited April 2012
    The assert will only happen with debug builds (__orxDEBUG__ needs to be defined), but that doesn't mean that s32EventSendCounter will be correct in release though.

    Another option to track it down (as I don't have XCode 4 anyway, so it might not be as easy for me to repro) is to modify the orxEvent_Send() function and adding a few orxLOG lines.

    Like backuping the value of s32EventSendCounter as the beginning of the function and asserting at the end of it if the value is different (that should never happen!). You can also try to add an orxASSERT(s32EventSendCounter != 0) at the end of the function, but in the case where events are sent from listeners that will not be true, I don't know if you have such cases in your game though, but it's worth a try I guess.
    At least by doing that, we'll have the callstack at the exact moment the value isn't set correctly. If you never hit that assert but still have the initial bug, that means something is corrupting the memory, and that's bad juju.
  • edited May 2012
    Ok, I found the issue and it's iOS specific for now.

    The problem comes from the fact event are sent from more than one single thread in iOS and that can screw the counter (and probably a few other things as well ^^).

    I'll change either the event sends to be thread-safe or make sure that I stack all the inputs events in iOS and send them from the main thread like any others. Not sure when I'll be able to do that change though...
  • edited May 2012
    Glad you were able to find it. I thought there was something wrong with my Xcode project!
Sign In or Register to comment.