0

I have a WPF application written in C# that I'm using TerminateProcess() when certain events happen and the app needs to shutdown

I'm not sure why, but I'm seeing an occasional Watson dialog box appear when this is called? it's not 100%

is this to be excepted? I am passing a non-0 result code?

why is Watson popping, I would think this would be a silent exit?

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool TerminateProcess(IntPtr hProcess, uint uExitCode);

[DllImport("kernel32.dll")]
private static extern IntPtr GetCurrentProcess();

TerminateProcess(GetCurrentProcess(), 2);   <-- this is whats triggering Watson (sometimes)
stuck
  • 2,264
  • 2
  • 28
  • 62
  • How ocasional is "occasional"? – User 12345678 Aug 10 '13 at 13:26
  • 1
    This kind of harikiri is already built into .NET, use Environment.Exit or FailFast instead. Whether that makes a difference is very hard to guess. Might be related [to this](http://stackoverflow.com/questions/18036863/why-does-environment-exit-not-terminate-the-program-anymore) – Hans Passant Aug 10 '13 at 13:53

1 Answers1

2

You do know that calling TerminateProcess to close an application is like jerking the power plug out of the wall to shut down your computer, right? It doesn't ask nicely, and it doesn't do the right thing. It just forcibly rips your process out of memory.

It therefore makes a good deal of sense that the Dr. Watson debugger is going to pop up—no correctly functioning application is going to request that it be terminated in such an unusual way. One of the threads that you're terminating was probably busy and didn't expect to have the rug ripped out from underneath it. It is, of course, not notified when you call TerminateProcess. So there are all kinds of things that can go wrong here. Dr. Watson concludes that this has to be a symptom of a bug or some other problem, so it steps in to capture a crash dump.

The exit code you pass is irrelevant here. You can inspect it yourself after a process has exited, but it is not evaluated by Windows.

My suggestion is not to try and figure out what is keeping Dr. Watson from appearing sometimes, but rather to find a better way to close your application. If you had provided more details about your design and why you think you need to close the app in the first place, I could have made better suggestions. Right now, all I can suggest is to call Application.Current.Shutdown(). That ensures that your application is shut down the right way, which will keep the debugger from being invoked. It is, however, still an irreversible action, so it should still do what you want.

In Win32 terms, since perhaps that's your native language, the correct way to shut down an application is to cleanly shut down all of the worker threads associated with your process first, and then call the ExitProcess function. Notice the significance of the naming—exit is a normal action, terminate is not.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • In the case being discussed, the code is attempting to fail fast, the data in memory is not in a consistent state and any further progress may corrupt. My exact needs are to have each thread stop in their tracks – stuck Aug 10 '13 at 23:51
  • @stuck So then it makes perfect sense that the debugger is going to be invoked. That happens when apps crash. Turn it off using a global system setting. Not something you should be doing on machines you don't own personally, like those belonging to clients. – Cody Gray - on strike Aug 11 '13 at 09:54
  • Even if you what Hans suggested and call `Environment.FailFast`, a crash dump is going to be written. That is expected behavior. The only real solution is figuring out *why* your app needs to be terminated in such an unusual way. – Cody Gray - on strike Aug 11 '13 at 09:55
  • Cody, thanks for your input - I understand what yore saying but the situation is more involved than can be easily described here - TerminateProcess() is the proper technique. Terminate process should not be invoking the debugger, it shouldn't allow event pumps to exit, and it shouldn't invoke the second chance exception handler. – stuck Aug 12 '13 at 03:13
  • @stuck I'm still not convinced, you haven't given me any actual evidence that this is the right approach other than restating your belief. We'll never come to an agreement that way. But that's fine, you don't have to convince me. Unfortunately, there is not enough information provided in your question for me to give any more detailed of an answer. There is obviously something going wrong in code that you haven't shown us. You can verify that assumption by creating a simple app and calling `TerminateProcess`; you and I both know it'll work fine. – Cody Gray - on strike Aug 12 '13 at 09:03
  • The only advice I can offer is to take the opportunity provided to attach a debugger and/or examine the crash dump to see where the process termination is going wrong. – Cody Gray - on strike Aug 12 '13 at 09:03
  • The API was written for a reason, to be used as a component in a particular technique. You've felt your guidance is important, maybe it is to someone... thank you for your time. However, my question centers around API behavior and not technique. – stuck Aug 12 '13 at 14:52