Search Unity

Weird error and bad stack: Assertion failed on expression: 'Thread::CurrentThreadIsMainThread()'

Discussion in 'Windows' started by bluemike, May 4, 2017.

  1. bluemike

    bluemike

    Joined:
    Oct 26, 2015
    Posts:
    18
    Hi

    I am facing a strange error when running my code in the editor. It won't crash the editor but will crash the standalone Windows or Android app.

    This code indeed runs in a separate thread. I haven't see in the OpenCVForUnity documentation any special requirement regarding multi-threading. That seems to be a bug in the OpenCVForUnity package, but there is still something weird: the file and line numbers pointing to OpenCVForUnity code actually don't exist. Here is a partial excerpt of the C# file MatOfByte.cs containing the code mentioned in the call stack, with the correct line offset:

    Code (CSharp):
    1.        
    2. 40      public MatOfByte (params byte[] a) : base()
    3.         {
    4.  
    5.             fromArray (a);
    6.         }
    7. 45    
    8.         public void alloc (int elemNumber)
    9.         {
    10.             if (elemNumber > 0)
    11.                 base.create (elemNumber, 1, CvType.makeType (_depth, _channels));
    12. 50
    13.         }
    14.    
    15.         public void fromArray (params byte[] a)
    16.         {
    17. 55          if (a == null || a.Length == 0)
    18.                 return;
    19.             int num = a.Length / _channels;
    20.             alloc (num);
    21.             put (0, 0, a); //TODO: check ret val!
    22. 60      }
    23.  

    It is clear that those lines 40 and 44 are meaningless.
    Did I compile something not as required ? What would explain this discrepancy between the call stack and the actual code ?

    Worth mentioning that this error has been popping up forever, and I didn't care until it started to crash since I upgraded to Unity 5.6. The crash happens on Windows standalone and Android, but not on WebGL. Haven't tested yet on other platforms. If I comment this code no crash happens...

    Thanks for your help!

    Michael
     

    Attached Files:

  2. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    What type does MatOfByte derive from?
     
  3. bluemike

    bluemike

    Joined:
    Oct 26, 2015
    Posts:
    18
    Hmm OK, forgot to look at that.
    'Mat' is the base type.

    Code (CSharp):
    1.     public class Mat: DisposableOpenCVObject
    2.     abstract public class DisposableOpenCVObject : DisposableObject
    3.     abstract public class DisposableObject : IDisposable
    4.  
    The 'Mat' constructor calls a native function:

    Code (CSharp):
    1.         /**
    2. * <p>Various Mat constructors</p>
    3. *
    4. * <p>These are various constructors that form a matrix. As noted in the
    5. * "AutomaticAllocation", often the default constructor is enough, and the
    6. * proper matrix will be allocated by an OpenCV function. The constructed matrix
    7. * can further be assigned to another matrix or matrix expression or can be
    8. * allocated with "Mat.create". In the former case, the old content is
    9. * de-referenced.</p>
    10. *
    11. * @see <a href="http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-mat">org.opencv.core.Mat.Mat</a>
    12. */
    13.         public Mat ()
    14.         {
    15.             #if UNITY_PRO_LICENSE || ((UNITY_ANDROID || UNITY_IOS || UNITY_WEBGL) && !UNITY_EDITOR) || UNITY_5
    16.      
    17.             nativeObj = core_Mat_n_1Mat__ ();
    18.      
    19.             return;
    20. #else
    21.  
    22. #endif
    23.         }
    24.  
    Other base classes don't have any such Assert code.
    The doc doesn't mention an issue with multithreading, but indeed, regardless of other base constructors, it may point to an issue in the native code... I don't know.

    http://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#Mat::Mat()

    Thanks.
     
  4. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    It almost looks like the stacktrace is lying. In the editor, the console has an option to use "full stack logging":

    upload_2017-5-4_22-16-29.png

    Try using that - and paste the callstack that it prints. Note this may affect the editor performance (full logging is way slower).
     
    bluemike likes this.
  5. bluemike

    bluemike

    Joined:
    Oct 26, 2015
    Posts:
    18
    To make a long story short, I fixed the crash :)

    The full log is indeed different, but maybe a little too bug to make the link up to the C# code:

    Anyway, the crash is indeed in the native function.

    I had a suspicion with this line in the full stack log:
    "0x0000000140D9EBC5 (Unity) FindAndLoadUnityPlugin"

    Looks like it complains about loading the Unity plugin being initialized in the non-main thread.
    I havent found an init class for the OpenCVForUnity namespace, so what I did is to just build a dummy 'Mat' instance in the main thread.. et voilà!
    So yes, all it wanted was to initialize the plugin in the main thread. Worth a mention in the OpenCVForUnity forum (a very messy one, in the shape of one single Unity forum thread with multi-years history...)
     
  6. Tautvydas-Zilys

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,680
    Whoa, that's unexpected. It seems that Unity hijacks the P/Invoke, and tries to initialize the plugin as if it was a graphics plugin. And it dies because it's not on main thread.

    Could you report a bug on this? That doesn't look like correct behaviour on Unity's part - we should at least give you a reasonable error message.
     
    bluemike likes this.
  7. KiwiBleu

    KiwiBleu

    Joined:
    Jul 5, 2017
    Posts:
    1
    Hey @blue-mile,
    I am struggling as well with this ~~ I am trying to invoke the Mat() in the mainThread however... I got poor knowledge on how to do that. I just bumep onto your post it sound obvious~ Would you mind sharing with a beginner like me ~
    Thank you or anyone with that knowledge ah :)
     
  8. FreakForFreedom

    FreakForFreedom

    Joined:
    Jan 22, 2013
    Posts:
    156
    For anyone still having this error with 5.6 or 2017.1/2017.2: OP's solution with a manual initialization of the plugin also worked for me.
    I tried to access methods from a native plugin which operates on a different DX context besides Unity and when called the first time inside a threaded coroutine, I got the same error as OP. So I simply made sure that a method from the plugin would definitely be called at Start()-time and it works smoothly now for me.
     
  9. Tangruolin

    Tangruolin

    Joined:
    Nov 23, 2017
    Posts:
    1
    How do you solve this problem?Can you tell more about it?
     
  10. FreakForFreedom

    FreakForFreedom

    Joined:
    Jan 22, 2013
    Posts:
    156
    As I said, it's quite easy: Just make sure you're calling a native method from the dll inside Start() or Awake() so the native plugin is being correctly loaded on the unity main thread.