Random things about .NET, CLR, C++, and work
I've seen enough people asking about this so I thought I should talk about this in my blog. They see strange first-chance TypeLoadException happening in their application but it doesn't seem never cause any problem (app doesn't crash) and everything still seem to work 'fine'. This seem to happen mostly if you have a C++ Windows Store project with a managed Windows Runtime Component project working together. For example, they might have a C++/CX class that looks like this:
ref class Foo sealed : public CSharpWinRTComponent::IFoo
virtual void Bar()
Note that this is a private ref class (ref=WinRT in this case) that implements a managed WinRT interface IFoo defined in a managed WinRT component.
Then they pass an object instance of this type to a managed WinRT component:
WindowsRuntimeComponent1::StaticClass::Func(ref new Foo());
And guess what happens?
If you look at the object inside StaticClass::Func in managed debugger, you'll see the type is actually __ComObject, not the Foo class as you've expected.
Even though WinRT does provide you with the strong type support (unlike COM, where everything is interface based) that are very familiar to C# developers, the strong type support doesn't come magically. What actually is happening is when CLR sees a WinRT interface getting passed to managed code, it has no idea about what the interface is, and it needs to ask interface a simple question "Who are you" through IInspectable::GetRuntimeClassName. The answer from the interface is typically a class name (but could also be an interface name, which CLR would actually use for other purposes), and CLR will call Windows API RoResolveNamespace to figure out where that type lives, and loads up the WinMD containing the type.
By default, a C++ application project generates a WinMD for you and the WinMD would contain contain all the public types in that app. This means the private type Foo is actually not in any WinMDs and CLR would fail to create the Foo type instance for you. Fortunately, we have a plan B - CLR would create a __ComObject instance that would happily take any interface calls as long as the object actually supports them (through QI, of course). So the underlying type of the object may not be what you expect, but hey, as long as you can cast this object to the IFoo interface, and call the methods on IFoo, who cares.
The fix would be simply making the type public - and for return, you get the real type in managed code.
If you don't want to make it public (and for good reasons), you can also use RuntimeClassName attribute on IFoo interface:
ref class Foo sealed :
[Platform::Metadata::RuntimeClassName] public CSharpWinRTComponent::IFoo
virtual void Bar()
This tells C++/CX to use WindowsRuntimeComponent1.IFoo as the runtime class name returning to the CLR. CLR would recongizes this interface (well, it's a managed interface, after all), and happily accept it as the best answer. This interface is still not a class type, but at least this is something CLR regconizes and follows the WinRT rules. You would still get a __ComObject, but at least you are not getting TypeLoadException.
I mentioned earlier that making this type public would also fix the problem. The truth is, it's not that simple. When WinRT resolves a type name (to find the WinMD that contains the type), it finds the WinMD by namespace. For example, if the type's namespace (returned from IInspectable::GetRuntimeClassName()) begins with "MyApp", then it would look for a WinMD named MyApp.WinMD. C++/CX generates a WinMD usually with the same name of your project, and if your type has a different namespace, it would never get found, even though it is actually in the WinMD (you can confirm by using ildasm to open the WinMD up - it's .NET assembly, after all). So, you need to make sure the public types actually has the same namespace.
Even though I work on .NET interop and WinRT these days, async/await is still the one topic that gets me confused from time to time. It's a great concept logically but difficult to grasp once you start thinking about how the actual code flow goes (and all hell breaks loose once you start debugging the async code under WinDbg, without the help of Visual Studio). Found this great series talk by Lucian called 'Six Essential Tips for Async' on channel 9 and it clarified many of my confusions. Here is the link :
It's easier to explain this in an example. Let’s say you have a export function in your native DLL:
void WINAPI MyFunction(_com_ptr_t<IMyInterface> ptr)
// ... do something with ptr
void MyFunction(IMyInterface ptr);
Everything seems to be perfectly valid, except that there is a extra release, and you'll end up crashing later when the RCW finalizes.
The problem here is the _com_ptr<IMyInterface> argument. This is a C++ smart COM pointer, and it AddRef the pointer when it is created, and Release the pointer when it goes out of scope. Normally, when you are calling it in C++, C++ will take care of everything, making sure the contruction of _com_ptr is done correctly, making sure the AddRef is done. For example, when you are calling MyFunction with a IMyInterface* in C++, the actual code generated will look like this:
_com_ptr_t<IMyInterface> ptr(p); // -------> C++ inserts this code for you
However, when you are calling this as a P/invoke, the construction of ptr is not done at all - CLR is not C++, and has absolutely no knowledge about your _com_ptr_t. Whatever CLR passes as the interface pointer, becomes the _com_ptr_t. This happens to work (except for the extra release part), because _com_ptr_t only has one pointer field. As a result, AddRef is not done, and _com_ptr_t does an extra Release on the interface pointer. Then when CLR is trying to release the COM object, CLR will crash because the COM object will be gone/deleted before the last release from CLR. And people typically blame CLR for that because CLR dll shows up on the stack...
The underlying problem here, is that C++ types come with additional semantics that is not part of the P/invoke signature and is not understood by CLR, and there is no way CLR could follow C++ semantics and make sure they are done correctly. Some common mistakes that people make are:
We've already discussed #1. #2 is fairly obvious if you think about it. #3 is a bit interesting - potentially CLR could support a MarshalAs(CPPString), but std::string not standardized in terms of binary memory layout, CLR can't marshal them reliably if CLR don't know for sure what they look like in memory. So it is always a good idea to avoid C++ types in your native functions that you need P/invoke to.
BTW, this actually isn't really specific to .NET interop. Any time you are 'interop'ing with other languages, you better make sure you only pass data that other languages understand.
I'm seeing many people reporting that they are seeing strange P/invoke issues when they moved their code to VS 2012. Typically, they have P/invokes like this:
[DllImport("Win32Project2.dll", PreserveSig = true, CharSet = CharSet.Unicode)]
static extern int MyPInvoke(out string ret);
If you attach a native debugger (or enable native debugging), with the right symbols (public symbol would be just fine), you would see that it is actually crashing inside combase.dll!CoTaskMemFree:
> ntdll.dll!_RtlReportCriticalFailure@8() + 0x33 bytes ntdll.dll!_RtlpReportHeapFailure@4() + 0x21 bytes ntdll.dll!_RtlpLogHeapFailure@24() + 0xa2 bytes ntdll.dll!_RtlFreeHeap@12() + 0x2677b bytes combase.dll!CoTaskMemFree(void * pv) Line 475 C++
Problem like this are usually caused by a mismatch between the managed declaration and the native implementation. The usual suspect here is the 'out string' signature. In .NET world, having a out string in P/invoke means:
So, if MyPInvoke pass a LPWSTR that is not allocated from CoTaskMemAlloc, say from HeapAlloc, new, or a string literal, you are potentially asking CLR to do CoTaskMemFree on your pointer, which would result in undefined behavior.
Basically, this means the P/invoke was already broken before.
But why it didn't crash before and suddenly starts to crash now after upgrading?
This is exactly the kind of thing you could expect with undefined behavior, because that could change anytime. It turns out in Vista, Windows guys decided to make CoTaskMemFree a tiny bit better: by actually reporting errors. Before that, since it returns void, it would silently fail if a random pointer is passed to CoTaskMemFree (because CoTaskMemAlloc has some book keeping, so in 99.99% of the case it would know it is not theirs). In Vista, if the app is indeed compiled for Vista, which means its subsystem version would be 6.0 in the PE file, you would get the better behavior: you would crash!
How's VS 2012 involved in this puzzle? It actually pass /subsystemversion:6.0 to C# compiler (this is a new switch), which would enable this new crash-if-error behavior.
Fixing this issue is actually pretty straight-forward:
For more information, you can refer to an MSDN article that I wrote about 4 years ago here: http://msdn.microsoft.com/en-us/magazine/cc164193.aspx
Let's first start by looking at a small code snippet:
if (Marshal.GetHRForException(myException) == E_SOME_COM_ERROR)
This looks perfectly fine, right? Not really. It turns out this API is actually poorly named, and it actually does more than just retrieving the HR from the exception object. Using this API incorrectly could give you some weird problems, such as throwing out an incorrect, old exception.
So what does the API actually do?
Besides returning you the HRESULT, this function also sets the current thread IErrorInfo object to be the exception object. Every thread has a assoicated IErrorInfo COM object, defaulting to NULL. This IErrorInfo object represents the failure from the last COM API call, which is sort of like the GetLastError() Win32 API, or errno C api. From the IErrorInfo object, you can get more information such as the error description, help file context, etc, that gives you more information about the error. By setting IErrorInfo object to the exception object (actually setting to the IErrorInfo implementation of the exception object, which is shared by all managed objects), you are essentially telling your COM callers, "hey, there is a failure, it's this exception object, and you should do something about it", which is obviously a bad idea if you only want to retrieve the HR.
In many cases, this could go unnoticed, if your COM caller/callee handles IErrorInfo correctly. By "correctly", I mean they follow the COM IErrorInfo protocol, which are basically:
1. The caller use IErrorInfo from the current thread when calling a COM interface that explicily says "I support IErrorInfo"
2. The callee (which implements the COM interface) that says "I support IErrorInfo", must clear/set IErrorInfo before returning. This is very similar to GetLastError()/errno, right?
If this is the case, the incorrectly set IErrorInfo in the thread, would typically either be overwritten/cleared by some interface implementation that supports IErrorInfo, or ignored.
However, because the protocol I described is actually not very well understood by every COM developer, I've often seen cases where the COM component just say "sure, I support IErrorInfo on every COM interface", and they don't set/clear IErrorInfo at all. And then, the caller of this poorly implmented COM interface, would end up using the IErrorInfo set by GetHRForException call earlier, and is lead to believe that there is an error. For example, let's consider the following scenario:
Now, you might be wondering: What is this API really intended for in the first place? It is actually used in places in COM interop, where you want to return the HRESULT and set IErrorInfo by yourself. This doesn't happen very often - most people would be happy enough to let COM interop takes care of that part by converting Exception to HR and IErrorInfo (which, happens to call Marshal.GetHRForException). So unless you really know what you are doing, my advice is to stay away from Marshal.GetHRForException.
What if you really, really want to just get the HRESULT for a specific Exception? You should use Exception.HResult property.
I learned this debugging trick from a colleague a few days ago when we are debugging a bug together and I can’t wait to share it. Conceptually it is really a simple idea but it is very helpful.
Let’s say you are debugging a crash. You know the bug is probably in function A but you have no idea how to stop at the last time A is called before the crash (or whatever debugging events that is interesting). WinDbg actually provides a way to stop at a function when it is called N times, and then the problem becomes how do you know what N is. Here is how:
1. Start your app under debugger
2. Set a breakpoint with a big hit count: for example, bp SomeDll!A 1000
3. Run your scenario until the crash (or whatever debugging events that are interesting to you)
4. See the breakpoint hit count using ‘bl’ command. It should show you the hit count left (say 900).
5. Restart debugging. This time, set a breakpoint with hit count = 1000 – 900 (note that the numbers are typically in hex – time to bring out calc.exe)
6. Run – Now you’ve stopped at the last time function A is called.
Note that in 3 you could hit the breakpoint set in step #2 before the debugging event and in this case you just reset the breakpoint with a larger hit count and keep going. Just keep in mind that you’ve already hit that function for X number of times (X being the hit count you set in step #2) and you need to count that in the final calculation. You could repeat this multiple times but you get the idea. Of course, you can just set a very large number in the beginning to avoid all this trouble.
Like all the other debugging tips/tricks, this method has its own limitations – it doesn’t work if the repro doesn’t always execute code in the exact same way every time it runs. But in most cases, this is a simple but effective trick.
I recently got Samsung Focus but it doesn’t get recognized by the Zune Software – it says “No device connected”, even though my phone did ring a sound when it connects to my computer and zune software did pop up. Spend half hour searching for solutions and I run into this article:
One of the advices is to try a different USB port, like the one on the back of the computer. In fact I was connecting my phone to the front USB port, and switch to the USB port on the back actually worked for me. Not sure why this phone is so picky about the USB port… Anyway, thought I should share this just in case there are other people run into the same problem.
What is 0x8013XXXX
Occasionally you might run into mysterious HRESULTs returned from .NET that begins with 0x8013, for example, 0x80131522. Unfortunately the error lookup shipped with Visual Studio doesn’t really work on those strange HRESULTs. What are they?
It turns out they are in fact, defined by .NET/CLR in the header files. All these failure/success HRESULTs are defined in corerror.h in your platform SDK include directory (typically C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include). All these HRESULTs have their facility defined as FACILITY_URT=0x13 (in which URT stands for Universal Runtimeis an old 3-letter acronym for CLR, there are other funny old names for CLR - COM+ is one of them). If you don’t recall what facility is, you can think it as a category for the error – a HRESULT have facility = FACILITY_URT is returned from CLR.
If you look at the binary layout of a HRESULT below, you’ll see any CLR failure code will begin with 0x8013, and all the success code will begin with 0x0013.
Interpreting the HRESULT
Let’s say you are seeing a HRESULT 0x80131522, how do you know what error it is? Actually it is quite straight-forward - all the HRESULTs are defined in corerror.h in the following fashion:
#define COR_E_APPDOMAINUNLOADED EMAKEHR(0x1014)
EMAKEHR is defined as follows:
#define EMAKEHR(val) MAKE_HRESULT(SEVERITY_ERROR, FACILITY_URT, val)
MAKE_HRESULT is a windows macro which does some simple bit math and use SEVERITY_ERROR, FACILITY_URT, and val (as the lower 16-bits) to compose a HRESULT. So if you open corerror.h in your favorite editor, and search for the lower 16-bits which is 1522, you’ll easily locate the line:
#define COR_E_TYPELOAD EMAKEHR(0x1522)
Now you’ve probably already figured out it is a type load failure. But what if the name doesn’t give us any meaningful information? If that’s the case, now it is time to look it up in the resource DLL.
Look it up in mscorrc.dll
All the resources used by the native implementation of CLR (mscorwks/mscorsvr in v1/v2, clr.dll in v4) are saved in mscorrc.dll. Every resource string in resource DLLs have a resource ID. If you add 0x6000 to HRESULT code (the lower 16-bits part), you’ll get the error message ID in the resource. For example, the error message ID for 0x80131522 will be 0x6000+0x1522=29986. Now, open mscorrc.dll in Visual Studio (or whatever resource editor you got), and find the string ID with 29986:
Now you know the error message is: Could not find or load type.
A full list of HRESULTs
To save everyone from looking things up from corerror.h and mscorrc.dll, I made a table consists of every error HRESULT in .NET 4.0 and their corresponding error message (extracted by a little tool I wrote). Note that there are some HRESULTs don’t have corresponding resource strings as they don’t follow the rules I talked about above and those are listed as <N/A> in the table below.
HRESULT #define name
Invalid entrypoint information.
cvtres.exe not found.
Failed to delayload a library.
Failed to get dll entrypoint.
Multiple copies of mscoree.dll have been loaded into the same process.
Type has been unloaded.
Attempted to access an unloaded appdomain.
Error while unloading appdomain.
Assembly is still being loaded.
Attempt to create appdomain failed.
The module was expected to contain an assembly manifest.
Attempt to load an unverifiable executable with fixups (IAT with more than 2 sections or a TLS section.)
The private assembly was located outside the appbase directory.
A module specified in the manifest was not found.
Modules which are not in the manifest were streamed in.
A strongly-named assembly is required.
Strong name signature could not be verified. The assembly may have been tampered with, or it was delay signed but not fully signed with the correct private key.
Host detected a deadlock on a blocking operation.
Host interrupted a wait.
CLR has been disabled due to unrecoverable error.
A wait has timed out.
The leave operation has been attempted on a synchronization primitive that is not owned by the current thread.
An event has been abandoned.
Process exited due to ThreadAbort escalation.
Process exited due to AD Unload escalation.
Process exited due to Timeout escalation.
LoadFrom(), LoadFile(), Load(byte) and LoadModule() have been disabled by the host.
Failed to add file to AppDomain cache.
The check of the module's hash failed.
The located assembly's manifest definition does not match the assembly reference.
An unexpected error was encountered in the Assembly Cache database.
The given assembly name or codebase was invalid.
HTTP download of assemblies has been disabled for this appdomain.
Uninstall of given assembly is not allowed.
Assembly in host store has a different signature than assembly in GAC.
The requested assembly version conflicts with what is already bound in the app domain or specified in the manifest.
The requested assembly name was neither found in the GAC nor in the manifest or the manifest's specified location is wrong.
Unexpected error while parsing the specified manifest.
The given assembly name is invalid because a processor architecture is specified.
The module was expected to not contain an assembly manifest.
Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context.
Error occurred during a read.
Error occurred during a write.
File is read only.
Data value was truncated.
Old version error.
A shared memory open failed to open at the originally assigned memory address.
Too many records were returned for criteria.
Record is a duplicate.
Primary key value is required.
Record is valid but deleted.
Record is emitted out of order.
Cannot open a incrementally build scope for full update.
Null value not allowed in unique index or primary key.
Index has been duplicated.
The columns data type is not allowed in an index.
Index not found.
Record not found on lookup.
Data too large.
Column cannot be changed.
Too many RID or primary key columns, 1 is max.
Primary key column may not allow the null value.
Attempted auto-drop of table while open.
Object not found in the database.
Column not found.
A blob or string was too big.
TypeLib export: Detected array of SafeHandles.
Typelib import: Invalid type, not converted.
Typelib import: Invalid type, not converted - name unknown.
Typelib export: TLBX_E_CTX_NESTED
Typelib export: General error. See IError info for more information.
Typelib export: SaveAllChanges() failed.
Typelib export: Type library is not registered.
Typelib export: Type library could not be loaded.
Typelib import: Invalid vartype, not converted.
Typelib export: Could not load mscoree.tlb.
Typelib export: Could not get a required typeinfo from mscoree.tlb.
Merge: Method is duplicated but no matching property info.
Bad binary signature.
Merge: duplicated methods have inconsistent ImplFlags.
Merge: Inconsistency in meta data.
Typelib export: Cannot convert non-sequential structs.
Typelib import: The resolve ref call failed.
Typelib export: Encountered AsAny - ignored.
Typelib export: Encountered an [lcid] attribute set to an invalid parameter.
Typelib export: Encountered an [lcid] attribute on a pure dispatch interface.
Typelib export: Non-public field in public struct.
TypeLib export: the hModule of a loaded class is 0; cannot export it.
TypeLib export: attempted to export an Assembly imported from a TLB.
TypeLib import: attempted to import a TLB exported from an Assembly.
Attempted to define an object that already exists.
A guid was not provided where one was required.
Merge: an import typedef matched ns.name, but not version and guid.
Merge: conflict between import and emit.
Merge: Class already in emit scope, but member not found.
Merge: Parameter information mismatched.
Typelib export: Types which contain the native type NATIVE_TYPE_LPTSTR are not allowed to be exported to COM.
Typelib export: Types with a charset of auto are not allowed to be exported to COM.
Typelib export: The enum value is not legal for a typelib.
Typelib export: Duplicate IID.
Merge: Method is duplicated but no matching event info.
Bad input parameters.
Cannot resolve typeref.
No logical space left to create more user strings.
Known custom attribute had invalid value.
Known custom attribute blob has bad format.
Known custom attribute blob has repeated named argument.
Known custom attribute named argument not recognized.
Known attribute named argument does not support variant.
Known attribute named argument does not support array.
Failure decoding permission set.
Failure encoding permission set.
Unrecognized encoding format.
StrongName APIs not supported on system.
StrongName APIs could not locate a matching CSP.
Invalid security custom attribute.
Failed to grant minimum permission requests.
Failed to grant permission to execute.
XML Syntax error.
Bad custom attribute serialized blob version.
Invalid security action code.
CA reference to CA definition in same assembly.
Use of non-CAS permission with invalid action.
Failed to load assembly containing CA (or required CA type).
Signature size mismatch.
Public key of assembly did not match signing public key.
Failure during Cryptographic operation.
Unexpected Cryptographic operation.
Unable to create store file mapping.
Unable to map the store file.
Unable to determine store file size.
Unable to create mutex.
Unable to lock the store.
File Write failed.
Bad custom attribute serialized blob.
Failed to load CA type (or required CA type).
Rid is out of range.
Coded token type is out of range.
Coded rid is out of range.
String offset is invalid.
GUID offset is invalid.
Blob offset if invalid.
Multiple module records found.
FieldLayout2 has a duplicate.
ModuleRef name is NULL.
ModuleRef has a duplicate.
TypeRef has a bad resolution scope.
TypeDef marked nested has no encloser.
TypeDef extends a TypeRef which resolves to a TypeDef in the same module.
TypeDef that is not an Interface and not System.Object extends nil parent.
System.Object extends a non-nil parent.
TypeDef extends sealed class.
TypeDef is Deleted but not marked with RTSpecialName.
TypeDef is marked RTSpecialName, but is not a Deleted record.
MethodImpl's Decl is private.
Assembly [Ref] name has path and/or extension.
File has a system name (con, com, aux, etc.).
MethodImpl's body is static.
TypeDef is marked Interface but not Abstract.
Signature has function pointer missing argument count.
Signature is missing rank specification.
Signature is missing count of sized dimensions.
Signature is missing size of dimension.
Signature is missing count of lower bounds.
Signature is missing a lower bound.
MemberRef name is NULL.
MemberRef has an invalid name, _VtblGap*.
MemberRef has an invalid name, _Deleted*.
MemberRef parent Nil in a PE file.
MemberRef has invalid calling convention.
MemberRef has Method parent but calling convention is not VARARG.
MemberRef name different from parent MethodDef.
MemberRef signature different from parent MethodDef.
MemberRef has a duplicate.
ClassLayout parent TypeDef is marked AutoLayout.
Assembly name is NULL.
E_T_VALUETYPE<class token> or E_T_CLASS<vtype token>.
Class layout on an Interface.
AssemblyOS platform ID invalid.
AssemblyRef name is NULL.
TypeDef not nested has encloser.
FieldLayout2 has field marked Static.
Signature specified is zero-sized.
Signature does not have enough data at specified byte.
Method signature has invalid calling convention.
Enum has no value__ field.
Enum's value__ field is static.
Enum's value__ field is not SpecialName.
Enum's field is not static.
Enum's field is not literal.
Enum has no literal fields.
Signature is missing function pointer.
Signature has bad element type.
Signature has value array missing size.
Field signature has invalid calling convention.
Field is marked marshaled but has no marshaling record.
Field has marshaling record but is not marked marshaled.
Field is marked HasDefault but has no const value.
Field has const value record but is not marked HasDefault.
Field or method is marked HasSecurity but has no security record.
Field or method has security record but is not marked HasSecurity.
Multiple Assembly records found.
AssemblyRefOS has invalid platform ID.
File name is NULL.
ExportedType name is NULL.
Field is Literal but not Static.
Field or method is RTSpec.Name but not Spec.Name.
Method is abstract, parent is not.
Method not static or abstract in interface.
Method not public in interface.
.ctor in interface.
ManifestResource is neither Public nor Private.
Enum's field signature does not match value__ signature.
Enum's value__ field is not first.
Field is RTSpecialName but name is not value__.
Method is abstract and implemented.
Method is abstract and pinvoke.
Method is abstract and not virtual.
Method is not abstract and not implemented.
Method is not abstract and not (non-zero RVA or PInvoke or runtime).
Method is PrivateScope and has RVA set to zero.
.ctor or .cctor has zero RVA.
Field or method is PInvoke but is not marked Static.
Field or method is marked PInvoke but has no ImplMap.
Field or method has ImplMap but is not marked PInvoke.
Unrecognized Hash Alg ID (warning).
Unrecognized Processor ID in Assembly(warning).
Unrecognized Processor ID in AssemblyRef(warning).
Constant: parent token out of range.
Invalid flags in Assembly.
There is TypeDef with same name as TypeRef (warning).
Field is InitOnly and Literal.
global .ctor or .cctor.
.ctor or .cctor not marked SpecialName or RTSpecialName.
MethodImpl has invalid MethodDeclaration token.
MethodImpl has invalid MethodBody token.
MethodImpl has duplicate.
Bad field parent.
Parameter out of sequence (warning).
Parameter's sequence number exceeds number of arguments.
Method is abstract and final.
Global method is abstract or virtual.
Signature uses long form.
Method has multiple semantics (warning).
Property marked HasDefault, has no const value.
Property has const value, not marked HasDefault.
Property has method that is neither a Setter nor a Getter.
Property has method with invalid token.
Property has method from another class.
Const has non-null blob when it should not.
Access to this method is denied.
Field does not exist.
Member does not exist.
Method does not exist.
Attempt to combine delegates that are not multicast.
Operation is not supported.
Arithmetic, casting or conversion operation overflowed or underflowed.
An array has the wrong number of dimensions for a particular operation.
This operation must be called from a synchronized block.
Thread was interrupted from a waiting state.
A datatype misalignment was detected in a load or store instruction.
A managed code contract (ie, precondition, postcondition, invariant, or assert) failed.
Access to this type is denied.
Thread is in an invalid state for this operation.
Thread is stopping.
Could not find or load a type.
Could not find the specified DllImport entrypoint.
Could not find the specified DllImport Dll.
An invalid __ComObject has been used.
Not a Number.
Thread has aborted.
OLE Variant has an invalid type.
An expected resource in the assembly manifest was missing.
A mismatch has occurred between the runtime type of the array and the sub type recorded in the metadata.
Uncaught exception during type initialization.
Invalid marshaling directives.
An expected satellite assembly containing the ultimate fallback resources for a given culture was not found or could not be loaded.
The format of one argument does not meet the contract of the method.
A mismatch has occurred between the runtime rank of the array and the rank recorded in the metadata.
Devices not supported.
Unrecoverable API error.
Process was terminated.
Process not synchronized.
A class is not loaded.
An IL variable is not available at the current native IP.
A reference value was found to be bad during dereferencing.
A field in a class is not available, because the runtime optimized it away.
'Native-frame-only' operation on non-native frame.
Cannot Continue on non-continuable exception.
The code is currently unavailable.
When doing Edit and Continue, some JITs do not allow increasing the maximum level to which exception handling can be nested.
Process has been detached.
Not allowed to change the signature of an existing method.
SetIP is not possible, because SetIP would move EIP from outside of an exception handling catch clause to a point inside of one.
SetIP cannot be done on any frame except the leaf frame.
SetIP is not allowed.
Func eval cannot work. Bad starting point.
This object value is no longer valid.
CordbEval::GetResult called before func eval has finished.
The in-process version of the debugging API does not support this function.
Internal Runtime Error while doing Edit-and-Continue.
The field was added via Edit and Continue after the class was loaded.
Module not loaded.
Not allowed to change base class.
Cannot set a breakpoint here.
Debugging is not possible due to an incompatibility within the CLR implementation.
The remote device closed the connection.
The connection was closed due to a keep-alive failure.
Generic error that the device connection has been broken with no chance for recovery.
Cannot use JMC on this code (likely wrong JIT settings).
Internal frame markers have no associated context.
The current frame is not a child frame.
The provided CONTEXT does not match the specified thread.
The stackwalker is now past the end of stack. No information is available.
Func eval cannot update a variable stored in a register on a non-leaf frame. The most likely cause is that such a variable is passed as a ref/out argument.
The Method has no associated IL.
The thread has never run managed code before.
The function may only be called during profiler initialization.
Cannot perfrom SetValue on non-leaf frames.
Tried to do Edit and Continue on a module that was not started in Edit and Continue mode.
SetIP cannot be done on any exception.
The 'variable' does not exist because it is a literal optimized away by the compiler.
Cannot get the local signature for the method.
Adding a field to a value or layout class is prohibited.
Cannot change field after adding.
An internal structure about the class is missing.
A kernel debugger is enabled on the system. User-mode debugging will trap to the kernel debugger.
A kernel debugger is present on the system. User-mode debugging will trap to the kernel debugger.
The debugger's internal helper thread is dead.
Function not yet compiled.
The ID is not fully loaded/defined yet.
The Module is not configured for updateable methods.
The Method could not be updated for re-JIT.
In-process debugging must be enabled during initialization.
Cannot get a JIT map becuase they are not enabled.
BeginInprocDebugging already called.
Failed to convert XML to ASN.
Loading this assembly would produce a different grant set from other instances.
Unverifiable code failed policy check.
Assembly already loaded without additional security evidence.
CA type is abstract.
IsolatedStorage operation failed.
Unable to open the store.
Cannot set file pointer.
Unable to create the store directory.
Store must be open for this operation.
Store file is corrupt.
Store version is not supported.
Store file is not mapped.
Block size is too small.
Allocation size is too large.
Allowed quota is fully used.
Row not found.
An argument was out of its legal range.
Attempted to store an object of the wrong type in an array.
Attempted to marshal an object across a context boundary.
Operation timed out.
Internal CLR error.
Access to this field is denied.
Array subscript out of range.
An operation is not legal in the current state.
An object appears more than once in the wait objects array.
Operation is not supported on this platform.
The given key was not present in the dictionary.
Insufficient stack to continue executing the program safely. This can happen from having too many functions on the call stack or function on the stack using too much stack space.
The given filter criteria does not match the filter content.
Could not find or load a specific class that was requested through Reflection.
Attempt to invoke non-static method with a null Object.
Uncaught exception thrown by method called through Reflection.
Custom attribute has invalid format.
Error during managed I/O.
Could not find or load a specific file.
The object has already been disposed.
Runtime operation halted by call to System.Environment.FailFast().
The host has forbidden this operation.
Attempted to call into managed code when executing inside a low level extensibility point.
Failed to load the runtime.
Failed to find a required export in the runtime.
Install root is not defined.
Expected component of the runtime is not available.
A runtime has already been bound for legacy activation policy use.
The operation is invalid because the process may be shutting down.
Filter contains handler.
filter >= code size
Unknown calling convention.
Stack is too large.
Branch out of exception handler block.
fall through end of the method without returning
try start >= try end
try end > code size
handler start >= handler end
handler end > code size
Try starts in the middle of an instruction.
Handler starts in the middle of an instruction.
Try block overlap with another block.
Branch back when this is uninitialized.
ldftn and ldvirtftn not allowed on .ctor.
Non-compatible types on the stack.
Unexpected type on the stack.
Missing stack slot for exception.
Filter contains try.
Filter starts in the middle of an instruction.
fallthru the end of an exception block
fallthru into an exception handler
fallthru into an exception filter
Leave from outside a try or catch block.
Rethrow from outside a catch handler.
Expected pointer to function on the stack.
Expected single dimension array on the stack.
Expected value type instance on the stack.
Expected address of value type on the stack.
Unexpected value type instance on the stack.
Local variable is unusable at this point.
Branch out of try block.
Branch out of exception filter block.
Branch out of finally block.
Return out of try block.
Return out of exception handler block.
Return out of exception filter block.
jmp / exception into the middle of an instruction.
Non-compatible types depending on path.
Init state for this differs depending on path.
Stack must be empty on return from a void function.
Return value missing on the stack.
Stack must contain only the return value.
Return uninitialized data.
Illegal array access.
Store non Object type into Object array.
Return from .ctor before all fields are initialized.
Uninitialized item on stack.
Address of not allowed for this item.
Address of not allowed for ByRef.
Address of not allowed for literal field.
Cannot change initonly field outside its .ctor.
Cannot throw this object.
Callvirt on a value type method.
Expected ByRef on the stack.
Unrecognized local variable number.
Unrecognized argument number.
Unable to resolve token.
ELEMENT_TYPE_PTR cannot be verified.
ByRef of ByRef
Code size is zero.
Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
Expected single dimension array.
Expected single dimension array of pointer types.
Array field access is denied.
Missing ldsfld, stsfld, ldind, stind, ldfld, stfld, ldobj, stobj, initblk or cpblk.
Missing ldind, stind, ldfld, stfld, ldobj, stobj, initblk or cpblk.
Innermost exception blocks should be declared first.
Calli not allowed on virtual methods.
Call not allowed on abstract methods.
Expected non-static field.
Call signature mismatch.
Static function expected.
Box operation on TypedReference, ArgHandle, or ArgIterator.
ByRef of TypedReference, ArgHandle, or ArgIterator.
Array of TypedReference, ArgHandle, or ArgIterator.
Stack not empty when leaving an exception filter.
Unrecognized delegate .ctor signature; expected I.
Unrecognized delegate .ctor signature; expected Object.
Array of ELEMENT_TYPE_BYREF or ELEMENT_TYPE_TYPEDBYREF.
Unrecognized use of vararg.
Missing call, callvirt or calli.
Cannot pass ByRef to a tail call.
Expected address of value type, ObjRef type or variable type on the stack.
Unrecognized type parameter of enclosing class.
Unrecognized type parameter of enclosing method.
Unrecognized type argument of referenced class instantiation.
Unrecognized type argument of referenced method instantiation.
Cannot resolve generic type.
Invalid field token in FieldRVA record.
Duplicate RVA in FieldRVA record.
Duplicate field in FieldRVA record.
Bad token as entry point in CLR header.
Entry point in CLR header is a token of instance method.
Enum has non-integral underlying type.
Method has bogus RVA.
Literal field has no const value.
Class implementing an interface does not implement one of methods.
CA has invalid owner.
Method signature is generic but is missing its arity.
Method signature is generic but its arity is zero.
Signature has generic type instantiated at arity 0.
MethodSpec signature has arity 0.
MethodDef signature has arity n but owns m GenericParams.
Entry point in CLR header is the token for a method in a generic type.
Method has invalid header.
Entry point has more than one argument.
Entry point has bad return type.
Entry point has bad argument.
Illegal 'void' in signature.
Multiple implementation of method.
GenericParam name is NULL.
GenericParam has nil owner.
GenericParam has duplicate by owner and name.
GenericParam has duplicate by owner and number.
Warning: Class does not implement interface method in this module.
GenericParamConstraint has nil owner.
GenericParamConstraint has duplicate by owner and constraint.
GenericParamConstraint is non-contiguous with preceeding constraints for same owner.
MethodSpec has nil method.
MethodSpec has duplicate based on method and instantiation.
MethodSpec signature has invalid calling convention.
MethodSpec signature is missing arity specification.
MethodSpec signature is missing type argument.
MethodSpec arity of generic method and instantiation do not match.
MethodSpec method is not generic.
Entry point in CLR header is the token for a generic method.
MethodImpl overrides non-generic method with generic method.
MethodImpl overrides generic method of arity n with generic method of arity m.
Signature has token following ELEMENT_TYPE_CLASS (_VALUETYPE) that is not a TypeDef or TypeRef.
This post has some implementation details of CLR. Please do not use this information in your application as these implementation details are subject to change in the future.