Question

I started asking this question here, and got very informative answers, but still can't get round the problem. That question has been closed as it's a known issue. I know it's a known issue: my question is what can I possibly do about it?

To summarise:

  1. VS debugger swallows unhandled exceptions occurring in a Form_Load event (or any calls therefrom) when debugging on Windows 64-bit systems (in my case, Win 7 64-bit). As it stands, this makes VS useless as a dev environment
  2. One suggestion was to move code into the constructor rather than the FOrm_Load event. I don't want to do that as it moves code out of sight into "designer-created" modules; those modules are full of code I'm not competent to change yet; and I don't trust the Designers not to wipe out or change code I put there.
  3. Another suggestion was to point unhandled exceptions to dummy empty exception handlers by inserting some code into an initial procedure (e.g. Sub Main). This works. The problem here is that Sub Main can only execute on startup if I switch off the Application Framework. Then I can't run the application with a lifetime of "until the main form or last form closes".
  4. I thought I'd got a Sub Main in a startup form running, and running at the right time (i.e. before Form_Load). Thus I can still use the Application Framework, and have this special code run before anything else. I may be wrong here. In any case, I've changed the code of that form a bit, and Main no longer runs in time - if it ever did (Form_Load runs first, and we have the same problem). Tried moving the code into Form_Load - but it itself causes an error.
  5. There's a supposed hotfix (KB976038). I applied that (restart needed): but now instead of the exception being swallowed, I get a vshost.exe application error, and still can't debug my code. Frustatingly, once I OK the application error, I get a glimpse of the VS debugger showing the usual Unhandled Exception box - but it disappears in about 1/10th of a second.

So what are my options?

The common thread here is that though I'm an experienced programmer, used to getting things done in VB.NET and VB6, and competent to understand the thorough explanations of what's causing this problem;

all the possible measures are really beyond my competence, and introduce too many gotchas that I may not even be aware of. I can't help thinking - why can I not just get down to coding, and deal with the inevitable coding mistakes I'll make, using a debugger that I can trust to break on an exception?

At the moment, I feel that if (with advice from those more expert than me) I somehow get VS to properly catch unhandled exceptions and break on them, this will only be for today. Who knows whether something I do in my code tomorrow, or next week, might not break the carefully-constructed safety-net that is making VS behave itself properly for the moment?

I freely admit that I shouldn't be allowed near the constructor/Designer-created code at this stage in my .NET expertise. I just want to get stuff done! So my options look like:

  • Learn all the hardcore stuff so that I never break the solution to this problem. This will take months if not years; or
  • Give up and go back to VS2008 Express on XP; or
  • Persuade the company to bin Windows 7 64 and gives us Windows 7 32 as a development OS.

Any ideas or suggestions welcome!

EDIT: As suggested by @roadwarrior below, here's the suggested workarounds in the answer to the original question, and what I've found with them:

1 Project + Properties, Build tab, change Platform target to AnyCPU

Already is set that way, and I can't change it. Tried changing TargetCPU away from "AnyCPU" to x86 or 64-bit - no effect.

2 Debug + Exceptions, tick the Thrown box for CLR exceptions

Makes running/testing a nightmare as soon as I start deliberately handling exceptions (which I do a lot). Every exception will result in a "stop", whether handled or not.

3 Write try/catch in the Load event handler

This is not going to be much fun either. At this stage of development, I want to see the line that's causing the problem. Always loathed debugging code back in VB6 that was in the scope of an On Error Goto someone had put into a procedure 6 steps up the call stack; I don't want to start out that way in my own projects!

4 Use Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException) in the Main() method so that the exception trap in the message loop isn't disabled in debug mode. This setting however makes all unhandled exceptions hard to debug, the ThreadException event is pretty useless.

I don't understand the comment in the final sentence. But something like this worked. What I did, as suggested by Neolisk in answer to my previous question, was this, in a Sub Main:

Public Sub Main()
    AddHandler Application.ThreadException, AddressOf ThreadExceptionHandler
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException)
    AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf UnhandledExceptionHandler

    Form1.Show()
End Sub

Friend Sub ThreadExceptionHandler(sender As Object, e As System.Threading.ThreadExceptionEventArgs)

End Sub

Friend Sub UnhandledExceptionhandler(sender As Object, E As System.UnhandledExceptionEventArgs)
End Sub

This was my version of neolisk's code - had to change it as in my version of VS/.NET (2012, 4.5) the two handlers needed to have different signatures. Two problems with this:

a) I can't get a Sub Main to execute on startup without unticking "Enable application framework". Once I do that, Form1.Show shows the form, we get to the end of Sub Main, and the form immediately disappears again, as the application is closing. I've subverted the application Settings' window's "Shutdown mode" setting, and don't understand how to get it back again.

b) This code works but I have very little idea why, how, whether it covers all exceptions, how it relates to what I may decide to tick/untick in the Debug/Exceptions dialog, or what other gotcha side-effects it might have at debug-time or run-time.

5 Consider if your code really belongs in the Load event handler. It is very rare to need it, it is however popular with VB6 programmers where Load was a big deal. You only ever need Load when you are interested in the actual window size after user preferences and autoscaling is applied. Everything else belongs in the constructor.

Fair enough. As an ex-VB6 programmer I'm used to using Form_Load, but let's progress and learn new things and move the code into the form's New() constructor (Let's hope I never have some code that really has to be in the _Load event). Now at least an exception dialog is shown when execution hits the problem line: but it's on top of a new window "No source available (crlf) The call stack contains only external code". In this particular case, the mistake in the code is debuggable from what I see here (it's a stupid typo) - but debugging like this when things get more complicated is going to be a nightmare: no chance to see what the state of anything is.

General comments:

1. Ran this project on the one Win7 32-bit machine we have (not my machine), and had no problems whatsoever. That's my preferred solution - to simply stop using Win7 64-bit for development.

2. Comments along the lines of "you're lucky you've got a debugger at all" are amusing, but not helpful. This is VS2012, which is supposedly a development environment with a debugger that works, and which we're going to have to pay £££ for. I've programmed for long enough to know when I know what I'm doing, and when I'm messing around with stuff I shouldn't be because I don't understand it. What I specifically don't understand is not the underlying structures (I cut my teeth on ZX81 machine code, don't want to go back there...), but VS itself. I'm happy to learn more about e.g. changing exception handlers in VS, as I need to, but definitely don't want to dive right in there, ignorantly, as a basis for my development environment.

Was it helpful?

Solution 2

Regarding your concern #3: try using ShowDialog() instead of Show(), it makes the application run until this (main) form is closed. We have a production application running like this. If you don't have a main form, you might want to reconsider your design.

Before stepping away from x64, please consider that starting with 2008 R2, there is no 32-bit version of the OS. Meaning if you are to run your software on the application server, that would be x64, so you'd have to adapt for that.

OTHER TIPS

Your question was closed as a duplicate rather than because this is a known problem. The original question has a good answer by Hans Passant that discusses the possible workarounds.

Please let us know which bits of the various workarounds are "hardcore", and I will try to provide simple explanations. I actually think it would be good for you to explore this further as it will improve your understanding of what happens under the hood.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top