While broken into my code using MonoDevelop, if I attempt to inspect some - not all - variables, MonoDevelop says the value is “The requested item has been unloaded”.
I have no idea what that means, or why MonoDevelop / Unity decided to ‘unload’ that particular value.
It is getting increasingly annoying as I have to resort to Debug.Log and then sifting through other people’s Logs to find the ones I’m interested in.
I have tried Googling to no avail, please tell me someone else has had this problem?
Such an annoying problem… Re-attaching the debugger while the game is running seems to fix the issue for me, it’s still lame I have to do all that clicking to see an enum… Hopefully this helps someone else out!
You can patch Unity Monodevelop source to fix this bug and rebuild some dlls.
I did that and uploaded dlls, you can just download and replace:
There are Dlls for Monodevelop version 2.8.2 and 4.0.1
These dlls work for me, if you get problems, you can download Unity Monodevelop source and build them manually (I will point what needs to be added below).
In this dlls there are two fixes:
First for not showing enum, and second for not showing generic collections saying
“unknown type 'System.Collections.Generic.CollectionDebuggerView’1 mscorlib”.
Fix for inspecting collections is just ignoring custom Debugger Proxy class and using plain inspector, so you will see all inner members of List and Dictionary.
Fix for Enum:
in SoftDebuggerAdaptor.cs TryCast function you can “eat” AppDomainUnloadedException and continue
if (valueType is TypeMirror) {
fromType = (TypeMirror) valueType;
try {
if (toType != null && toType.IsAssignableFrom (fromType))
return obj;
}
catch (AppDomainUnloadedException excep) {
}
// Try casting the primitive type of the enum
EnumMirror em = obj as EnumMirror;
Fix for generic collections:
In ObjectValueAdaptor.cs GetProxyObject function instead of throwing if Proxy Object could not be loaded, return plain object it ignores proxy attribute for List, Dictionary, etc:
try
{
if (ttype == null)
return obj;
object val = CreateValue (ctx, ttype, obj);
return val ?? obj;
} catch (Exception ex) {
ctx.WriteDebuggerError (ex);
return obj;
}
This is a bug in MonoDevelop, been there for ages, probably won’t be fixed for the next few years.
I’ve found the following work around. For every enum in your code, you can add:
public int debugView_enumName {get {return (int) enumName; }}
This will let you then view the enum casted to an int in the watch window. Certainly a dirty solution, but we have to do what we can in these dark times.
This is not a MonoDevelop problem, it’s actually a Unity problem - but there is a workaround (see below).
The issue is that Unity constantly re-creates the .csproj files for MonoDevelop, which is not the standard way that MonoDevelop (or any IDE for that matter) actually works. This causes MonoDevelop’s caching system (which is based on some sort of hash of the project file) for it’s completion data to become invalid, causing lots of issues related to code completion and debugging (not just enums). The completion data for the project is actually pointing to a previous completion cache file and will not pick up any new definitions of enums, which causes the debugger to throw an exception when trying to show the enum value.
The solution is this: every now and then clear the caches. These are located on Mac in /Users/yourusername/Library/Caches/MonoDevelop-Unity-4.0/DerivedData (there is a corresponding folder on Windows but I don’ t know where it is exactly). Deleting all of the files in this folder will clear the completion data cache, and force MonoDevelop to re-create the caches. This of course will only work once as Unity will then blow away your project files the next time you run Unity - so you’ll have to do it every now and then to have the IDE re-sync it’s caches.
The ultimate solution is for Unity to stop trashing project files they way they are doing it and allow MonoDevelop to work the way it supposed to work. If they need to update the project files, they need to do so in such a way that MD can correctly associate the new project file with the cached completion data in its completion cache.
the easiest work around I use is to add an accessor like so:
public string OpponentMove {
get {
return opponentMove.ToString();
}
}
ironically tho this work around appears to force the debugger to load the symbol infomation so you don’t see the “The requested item has been unloaded” error
Debugger have the problem that they have to work with what is available at a certain point. For example a local variable might be reused for something else when it’s not accessed from the rest of the code. Therefore you can’t read a value because it has no relevance to the code.
It’s hard to tell what’s your specific problem without seeing a concrete example.
A common case are local for-loop variables
// C#
void SomeFunction()
{
for(int i = 0; i < 5; i++)
{
}
for(int n = 0; n < 5; n++)
{
}
}
In this example the variable i and n will most likely use the same memory on the local stack. “i” is only defined inside the first for loop. When it’s done “i” runs out of scope.
“n” is only defined inside the second loop, so since at this point the memory of i isn’t used anymore it can be used for “n”.
This is just a simple basic example. What really happens depends on the compiler / platform.