Jump to content

Exception while debugging : CompareBaseObjectsInternal can only be called from the main thread ??


Recommended Posts

Hello guys. I'm new to debugging in unity so maybe I missed something obvious (that must be the case).

 

I tried to debug some functions in existing mods. I set up my debugging environment and it's working just fine. However, most of the mods I try to use are now completely broken and don't want to run correctly.

I did found the problem, which stands in that Exception :

Quote

CompareBaseObjectsInternal can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.

I understand that constructors should not use any compare functions since they are not executed in the main thread, but I don't really understand why they were running fine in "production" environment. Kerbal Engineer Redux and FAR are the source of theses exception. And they were working fine before I set up the debugging environment.

I am using unity 4.6.4f1 for KSP 1.0.5, trying to debug with Visual Studio 2015 under Windows 8 and I did installed Sean McDougal KspDevModePatcher, as well as the latest mono libraries to get a correct mdb file for my visual studio version.

Would anyone happen to know some fix I could use to avoid these errors (and avoid changing every constructor in FAR or KER, that would be a pain since I don't want to debug them, but rather a mod depending on FAR)

Link to comment
Share on other sites

I believe that both of those mods use a background thread to do various calculations.  This is definitely true of KER (the vessel simulation code that calculates the deltaV is run in a background thread) and is probably also true of FAR.  I don't know why they work fine in release and not in debug but I do remember something related to this in the thread about setting up the debug environment.

If you find that there is something in KER that could easily be changed to avoid this issue then please post about it in the KER thread.

Edited by Padishar
Link to comment
Share on other sites

Thank you for your help. That does not arrange me because I'm trying to debug a mod relying on FAR and if FAR isn't working properly, then the mod does not work as intended.

I kept on trying to find a way to solve this issue, and it seems that's something common in Unity. As far as I understood, there are a lot of functions and properties you can't access on a Component if you're not doing it on the main thread, and there's no easy way to invoke a function on the main thread. The problem with FAR is that it does its voxelization in background. I guess KER problem is somewhat related.

I guess that means I can't debug to solve the problem on the mod I'm working on. Thanks anyway

Link to comment
Share on other sites

As I understand it, the issue isn't because the mods call Unity code from other threads (KER doesn't access any Unity objects from the background thread) but that initialisers get run in a different thread in the development version of the Unity player and this causes the errors that happen.  There is a post in the debugging thread that mentions exactly the problem you are having in the same situation so the poster of that may have found a solution.  This may involve changing and recompiling FAR or it may involve a modified version of the KSPDevModePatcher configured to patch the necessary bits of the FAR dll.  I haven't looked into the patcher but that way may be easier than trawling through the FAR source.  Alternatively, it may be enough to compile a debug version of FAR as that may do something different with where the code gets put.

Link to comment
Share on other sites

9 hours ago, Baleine said:

I understand that constructors should not use any compare functions since they are not executed in the main thread, but I don't really understand why they were running fine in "production" environment. Kerbal Engineer Redux and FAR are the source of theses exception. And they were working fine before I set up the debugging environment.

I think the release version of the engine might suppress warnings like this

2 hours ago, Padishar said:

As I understand it, the issue isn't because the mods call Unity code from other threads (KER doesn't access any Unity objects from the background thread)

KER does appear to access a Unity object from the background thread (assuming the code on git is correct). It's easy to identify if you have the whole stack trace of the error to go by:

[LOG 18:37:17.542] KerbalEngineer -> SimManager.RunSimulation() // CompareBaseObjectsInternal can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
[LOG 18:37:17.544] KerbalEngineer ->   at (wrapper managed-to-native) UnityEngine.Object:CompareBaseObjectsInternal (UnityEngine.Object,UnityEngine.Object)
  at UnityEngine.Object.CompareBaseObjects (UnityEngine.Object lhs, UnityEngine.Object rhs) [0x00000] in <filename unknown>:0 
  at UnityEngine.Object.op_Equality (UnityEngine.Object x, UnityEngine.Object y) [0x00000] in <filename unknown>:0 
  at PhysicsGlobals.get_Instance () [0x00000] in <filename unknown>:0 
  at PhysicsGlobals.get_Stack_PriUsesSurf () [0x00000] in <filename unknown>:0 
  at KerbalEngineer.VesselSimulator.EngineSim.SetResourceDrains (System.Collections.Generic.List`1 allParts, System.Collections.Generic.List`1 allFuelLines, System.Collections.Generic.HashSet`1 drainingParts) [0x00000] in <filename unknown>:0 
  at KerbalEngineer.VesselSimulator.Simulation.UpdateResourceDrains () [0x00000] in <filename unknown>:0 
  at KerbalEngineer.VesselSimulator.Simulation.RunSimulation () [0x00000] in <filename unknown>:0 
  at KerbalEngineer.VesselSimulator.SimManager.RunSimulation (System.Object simObject) [0x00000] in <filename unknown>:0 

 

 

Link to comment
Share on other sites

I just want to add my experience with thread an Unity object. If you share a Unity object between the main thread and your threads you can get really strange results. For example a FloatCurve will reply to your thread vith values asked in the main thread, and vice-versa. You need a copy of the object for the thread.

Link to comment
Share on other sites

It sounds like FloatCurve must be storing intermediate values for the calculation in a member variable and this causes an issue for simultaneous calls, though I can't see why they would want or need to.  I could understand if it generated coefficients for each section of the curve lazily but it would be better to store them for all the sections separately if you're going to bother storing them at all.

Edit: Also, is FloatCurve a Unity thing?  It isn't mentioned anywhere in their documentation.  Are you sure it isn't a KSP thing...?

Edited by Padishar
Link to comment
Share on other sites

Yes, most likely. For MJ I found a way to clone them easily.

FloatCurve is a KSP thing but they use AnimationCurve internally, which are in Unity.They more or less just warp the config node loading and saving.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...