msvsmon.exe exceptions when debugging CE applications in VS explained
If you have ever done any application development for Windows Embedded Compact (aka "CE" or "WEC") devices then you no doubt have seen this ugly exception coming out of the serial port of the device:
It has been a long standing issue that so far nobody has really taken the time to investigate or explain, so let's change that!
Today I loaded up a WEC2013 debug kernel, started conmanclient and created a default "ConsoleApplication" targeting my device. I pressed F10 and waited for PB to break because of the exception. The callstack at the time of the exception is:
VSDEBUGENG.IMPL!43e2da82()
KERNEL!APICall + 142 bytes
COREDLL!TlsSetValue(unsigned long 0x00000001, void * 0x00000001) line 260 + 6 bytes
COREDLL!ThreadBaseFunc(unsigned long (void *) 0x00000000, void * 0x00000000) line 1269 + 6 bytes
So, msvsmon.exe (VSDEBUGENG.IMPL) is actually raising the exception! But why?
Setting a breakpoint on the call to RaiseException allowed me to step in and see the arguments passed to RaiseException:
dwExceptionFlags 0x00000000
nNumberOfArguments 0x00000004
- lpArguments,4 0x009ffd48
[0] 0x00001000
[1] 0x43e8794c
[2] 0x0526001a
[3] 0x00000000
A quick google search on "Exception 0x406d1388" turned up this little gem of information: "How to: Set a Thread Name in Native Code".
So, what this RaiseException call actually does is simply setting the thread name by sending the VS debugger the event name through this exception. The reason it does this is so it is easier for you (the developer) to identify which thread you are debugging. This could be very useful when debugging multi-threaded applications; open the Threads window (CTRL-ALT-H) to see the thread names.
Knowing what we know now, we can see that the above 4 arguments are indeed matching what is listed on the MSDN page:
[0] 0x00001000 dwType: Must be 0x1000.
[1] 0x43e8794c szName: Pointer to name (in user addr space).
[2] 0x0526001a dwThreadID: Thread ID (-1=caller thread).
[3] 0x00000000 dwFlags: Reserved for future use, must be zero.
Long story short; I don't think there is any way to avoid this exception (even if MS would be interested in 'fixing' this). It's an annoyance, but not more than that. The exception can be safely ignored. It should not have any (or at least not have a big) impact on your debugging experience.
Comments
Nice explanation
Michel
Thanks for the explanation. This is yet another example of why you are a true leader in the industry.
Bruce