Search Unity

How come this exception fires sometimes?

Discussion in 'Scripting' started by Unarmed1000, Sep 12, 2014.

  1. Unarmed1000

    Unarmed1000

    Joined:
    Sep 12, 2014
    Posts:
    22
    On some android phones the SomeException is thrown from SomeFunction (see below) once in a while.

    How is that possible since GetShadowTag() should never be able to return null?
    Can you spot something I missed?

    EDIT:
    BTW: The code is single threaded.

    Code (CSharp):
    1. void SomeFunction()
    2. {
    3.   if (obj != null)
    4.   {
    5.     ShadowTag tag = GetShadowTag(obj);
    6.     if (tag == null)
    7.       throw new SomeException();
    8.   }
    9. }
    10.  
    11. ShadowTag GetShadowTag(IShadowable obj)
    12. {
    13.   if (obj.SYS_Tag == null)
    14.   {
    15.     RegisterObject(obj);
    16.   }
    17.   return obj.SYS_Tag;
    18. }
    19.  
    20.  
    21. private void RegisterObject(IShadowable obj)
    22. {
    23.   int classId = m_shadowClassMgr.GetClassId(obj);
    24.   ShadowTag tag = RegisterObject(classId, obj);
    25.   m_shadowDict[tag.ObjectId] = tag;
    26. }
    27.  
    28. ShadowTag RegisterObject(int classId, IShadowable obj)
    29. {
    30.   ShadowTag tag = new ShadowTag(obj, classId, NULL_ID, 0);
    31.   int objectId = m_objectList.Add(tag);
    32.   tag.ObjectId = objectId;
    33.   obj.SYS_Tag = tag;
    34.   return tag;
    35. }
    36. void ShadowClassMgr::GetClassId(obj)
    37. {
    38.    return someId;
    39. }
    40.  
     
    Last edited: Sep 12, 2014
  2. Kensei

    Kensei

    Joined:
    Apr 26, 2013
    Posts:
    63
    I think its because in SomFunction you throw when tag==null, it can be null because this code is called before assigning tag with a value later one. I think if you put the function after the other methods you shouldn't get any problems. However I'm by no means an expert :)

    Edit: What I mean is that SomeFunction is executed before the other functions, and since it's them that assign the tag, it will stay null.
     
  3. Unarmed1000

    Unarmed1000

    Joined:
    Sep 12, 2014
    Posts:
    22
    Thanks for guessing but its incorrect.
     
  4. Kensei

    Kensei

    Joined:
    Apr 26, 2013
    Posts:
    63
    Well I'm out of ideas :D All your returns and calls seem legit to me. Hope someone more knowledgeable figures it out, I'd like to find the reason as well ^^
     
  5. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    Does IShadowable.SYS_Tag have any logic in a set accessor?
     
  6. Unarmed1000

    Unarmed1000

    Joined:
    Sep 12, 2014
    Posts:
    22
    That was a good bet, but no.
     
  7. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,447
    Does ShadowTag override the comparison operator like UnityEngine.Object does?
     
  8. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    Does this give you any hints?
    Code (csharp):
    1. ShadowTag GetShadowTag(IShadowable obj)
    2. {
    3.   if (obj == null)
    4.   {
    5.     Debug.LogWarning("obj is null");
    6.     return;
    7.   }
    8.   if (obj.SYS_Tag == null)
    9.   {
    10.     RegisterObject(obj);
    11.     if (obj.SYS_Tag == null)
    12.       Debug.LogWarning("Failed to register object obj. obj.SYS_Tag is still null.");
    13.   }
    14.  return obj.SYS_Tag;
    15. }
     
  9. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    Does ShadowTag inherit from MonoBehaviour?
     
  10. Unarmed1000

    Unarmed1000

    Joined:
    Sep 12, 2014
    Posts:
    22
    No

    No

    Unfortunately I do not own a device that cause this error but I have been able catch and log it in the wild.
    My latest build contain even more logging code in the same spirit of your code, but I only just deployed it earlier today.
    I unfortunately suspect its a Unity3D bug on android. Possible a code generation issue, but then again I hope thats not the case. I still just hope its something I overlooked in the above code.
     
  11. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    Good luck to you, my friend! Intermittent bug in the wild? That's the WORST kind of bug to fix. Here's to hoping you find some good repo steps.
     
  12. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,447
    Afted a couple of inlinings I came to this:
    Code (csharp):
    1. void SomeFunction()
    2. {
    3.     if (obj != null)
    4.     {
    5.         if (obj.SYS_Tag == null)
    6.         {
    7.             obj.SYS_Tag = new ShadowTag(...);
    8.         }
    9.         if (obj.SYS_Tag == null)
    10.             throw new SomeException();
    11.     }
    12. }
    Look's pretty safe...

    IShadowable looks like it's an interface and can't have any logic:
    Code (csharp):
    1. interface IShadowable
    2. {
    3.     ShadowTag SYS_Tag { get; set; }
    4. }
    How does the actual class implement SYS_Tag property? Like this?
    Code (csharp):
    1. class SomewhatShadowable : IShadowable
    2. {
    3.     public ShadowTag SYS_Tag { get; set; }
    4. }
     
  13. Unarmed1000

    Unarmed1000

    Joined:
    Sep 12, 2014
    Posts:
    22
    Code (CSharp):
    1.  
    2. private ShadowTag m_shadowTag;
    3.  
    4. public ShadowTag SYS_Tag
    5. {
    6.   get { return m_shadowTag; }
    7.   set { m_shadowTag = value; }
    8. }
    9.  
    Nothing in the class references m_shadowTag.
    It's very old code from before I knew about the syntactic sugar form :)

    All in all the code seems pretty simple and without side effects.
     
  14. Unarmed1000

    Unarmed1000

    Joined:
    Sep 12, 2014
    Posts:
    22
    Code (CSharp):
    1. ShadowTag RegisterObject(int classId, IShadowable obj)
    2. {
    3.   ShadowTag tag = new ShadowTag(obj, classId, NULL_ID, 0);
    4.   int objectId = m_objectList.Add(tag);
    5.   tag.ObjectId = objectId;
    6.   obj.SYS_Tag = tag;
    7.   if (tag == null)
    8.     throw new Exception1();
    9.   if (obj.SYS_Tag == null)
    10.     throw new Exception2();
    11.   return tag;
    12. }
    13.  
    I got some additional logging added and now it throws Exception2

    Meaning the "obj.SYS_Tag = tag" assignment a couple of lines above seem to be failing.. wtf.

    Any ideas, what could cause this to fail on some phones once in a while, except a Unity VM error?
     
  15. Unarmed1000

    Unarmed1000

    Joined:
    Sep 12, 2014
    Posts:
    22