views:

314

answers:

0

This is actually a solved problem, but it's so esoteric I thought I'd share it for other users.

Also perhaps others might suggest reasons?

Anyway, I'm working on a "mixed mode" .NET application written in managed C++, but with heavy links into existing native libraries.

The problem was, unhandled managed exceptions ended up as Win32 Access Violations. What I mean by this is that instead of showing the nice .NET dialog one gets with an unhandled managed exception, instead I would get the older style "Unhandled win32 exception occurred in..." message.

Here's the interesting thing: if I start the app in the debugger, then the thrown managed exception gets correctly picked up. i.e., the debugger shows me the line.

However, when executing normally, it would turn into this Access Violation. Attaching the debugger at that point would produce little useful information (it wouldn't even show a sensible stack trace).

So, to me it suggests that something is happening in native code just before the unhandled managed exception reaches the exception handler.

So anyway, I managed to solve the issue by comparing my project to a clean new C++ managed project generated by Visual Studio 2008.

The fix was to do the following:

  1. Change the /SUBSYSTEM flag (Project properties->Linker->System->SubSystem) from /SUBSYSTEM:WINDOWS to "Not Set"

  2. Switched from using old style WinMain() to using the new style main().

i.e. it used to be

  int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)

And it is now

int main(array<System::String ^> ^args)

[Why am I using this weird _tWinMain? This was what got generated by the Visual Studio .NET IDE many years ago when you create a sample mixed mode Windows app. It's always worked fine (until now) so I never bothered changing it. _tWinMain is just a macro to WinMain]

I made this change and the problem disappears. Unhandled .NET exceptions now get properly trapped so I can now actually debug them.

I also made the inverse change to the clean sample C++ app and proved that it was the cause.

So, really my questions is, what the heck is going on?

Was it just that I was using the old style WinMain instead of the new "main(array ^)"?

Should I maybe report this to Microsoft (will anyone care ;-) )?