Microsoft has come a long way since the error messages that they put into Windows 95. I think most people can remember when the ‘This program has performed an illegal operation’ dialog appears.
The problem is that most people, even sometimes us programmers can not understand the error messages when they occur. So I want to shed some light on the quite common CLR20r3 error message.
In summary this is the ‘oh darn something has gone wrong’ style error message, or more technically an ‘unhandled exception’ in the .NET CLR but we can hopefully find out the reason why.
First off you will most likely see a error dialog like this:
The error comes packaged with an Event name and 9 P codes (usually P1 – P9).
Technically these correspond to:
P1: Application where the error occurred
P2: Application version
P3: UNIX timestamp of the Application build.
P4: Assembly / Module where the error occurred
P5: Assembly / Module version
P6: UNIX timestamp of the Module build
P7: Method identifier
P8: IL code offset
P9: Error message (hashed if there is not enough space)
Finding out the application that crashed is easy, that is stored in P1. You can use the version stored in P2 to check to see if you have the latest version, if not, it may be worth while upgrading!
Dissecting the error
P3 and P6 are both UNIX timestamps stored in hexadecimal. So in the example above P3 (4CFDAB9C) is hex for 1291692956. UNIX time is stored as an integer representing the number of seconds since 01/01/1970.
Therefore 1291692956 (4CFDAB9C) equals Tue, 07 Dec 2010 03:35:56 GMT
P4 is the module where the error occurred, this can either be an internal .NET framework module or part of the application itself. In this case it is ‘mscorlib’ which is the core of the .NET framework. P5, which is the version number shows that this was using version 18.104.22.168 of mscorlib, which itself means that the application was compiled against version 2 of the .NET framework.
Note: Just because the error may have occured in mscorlib, the core .NET assembly, does not mean that the .NET installation is corrupt, it can (and usually does mean) that it has thrown an error that the client application did not correctly handle.
P7 and p8 are the core bits of information needed to get to where the error was being thrown.
P7 represents part of the indexer metadata token of the method which threw the error. When a .NET assembly is compiled, the compiler assigns each type (including methods) additional metadata including an identifying token. In the case of methods these usually start with 06000. Therefore the method which the error was thrown has the metadata token of 06000 + P7
In the case of the example above where P7 is F50, the metadata token for the method is 0x6000F50
P8 represents the offset within the compiled IL code of the module, for more information about IL, check out my previous article on extracting IL code from assemblies.
To use the information in P7 and P8 you need to use the IL Disassembler that comes as part of the Visual Studio SDK tools.
To find the method where the error occurred:
- Go to File > Open and select the .DLL associated with P4 (with version P5)
- Go to View > Meta Info > Show!
- Go to Find, and type in 06000 and the P7 value.
This should give you the method name and containing class information of the error. You can use additional tools to decompile the code to see what exactly is going wrong.