Can aborting a process without resetting the clipboard chain cause trouble? - windows

I've got a program that calls SetClipboardViewer at startup to register for clipboard change notifications. At shutdown time, it will call ChangeClipboardChain to remove itself from the chain correctly.
This is all great as long as the program runs normally. But that's got me wondering, what happens if the program gets aborted, either by me killing it under the debugger, by a crash, or by the user killing the process because something went wrong? Then the cleanup never happens. Can that cause trouble for the system somehow?
Specifically, I know Windows can remove my viewer without trouble because it's a handle and Windows can clean up all handles when a process terminates, but will this cause the next value downstream in the chain, that I was holding a reference to, to get lost somehow?

Yes, failure to remove yourself from the chain will break the chain. Deadly sin #2. Please read the whole list to be sure that you're following all of the rules.
http://www.clipboardextender.com/developing-clipboard-aware-programs-for-windows/6
Lots of apps suffer from this, including the Delphi IDE. i.e. if Delphi crashes in certain ways, it'll kill the clipboard chain (D2005 anyway).
Consider using Vista style notification on Vista/Windows7.

Related

File operation functions return, but are not actually committed when Windows shuts down

I am working on an MFC application that can (among other things) be used to shut Windows down. When doing this, Windows of course sends the WM_QUERYENDSESSION and WM_ENDSESSION to all applications, mine included. However, the problem is that my application, as part of some destructors, delete certain files (with CFile::Remove) that have been used during the execution. I have reason to believe that the destructors are called (but that is hard to know for certain) when the application is closed by Windows.
However, when Windows starts back up again, I do occasionally notice that the files that were supposed to be deleted are still present. This does not happen consistently, even when the execution of the program is identical (I have a script for testing this). This leads me to think that one of two things are happening: Either a) the destructors are not consistently being called, or b) the Remove function returns, but the file is not actually deleted before Windows is shut down.
The only work-around I have found so far is that if I get the system to wait with the shutdown for approximately 10 seconds after my program has stopped, then the files will be properly deleted. This leads me to believe that b) may be the case.
I hope someone is able to help me with this problem.
Regards
Mort
Once your program returns from WM_ENDSESSION, Windows can terminate it at any time:
If the session is being ended, this parameter is TRUE; the session can end any time after all applications have returned from processing this message.
If the session ends quickly, then it may end before your destructors run. You must do all your cleanup before returning from WM_ENDSESSION, because there is no guarantee that you will get a chance to do it afterwards.
The problem here is that some versions of Windows report back that file handling operations have been completed before they actually have. This isn't a problem unless shutdown is triggered as some operations, including file delete will be abandoned.
I would suggest that you cope with this by forcing your code to wait for a confirmed deletion of the files (have a process look for the files and raise an event when they've gone) before calling for system shutdown.
If the system is properly shut down (nut went sudden power loss or etc.) then all the cached data is flushed. In particular this includes flushing the global file descriptor table (or whatever it's called in your file system) which should commit the file deletion.
So the problem seems to be that the user-mode code doesn't call DeleteFile, or it failes (for whatever reason).
Note that there are several ways the application (process) may exit, whereas not always d'tors are called. There are automatic objects which are destroyed in the context of their callstack, plus there are global/static objects, which are initialized and destroyed by the CRT init/cleanup code.
Below is a short summary of ways to terminate the process, with the consequences:
All process threads exit conventionally (return from their procedure). The OS terminates the process that has no threads. All the d'tors are executed.
Some threads either exit via ExitThread or killed by TerminateThread. The automatic objects of those threads are not d'tructed.
Process exited by ExitProcess. Automatic objects are not destructed, global may be destructed (this happens in the CRT is used in a DLL)
Process is terminated by TerminateProcess. All d'tors are not called.
I suggest you check if the DeleteFile (or CFile::Remove that wraos it) is called indeed, and check also if it succeeds. For instance you may open the same file twice for whatever reason

Alternatives to NtQueryInformationProcess for detecting undead processes?

I'd like to detect when someone terminates a suspended debugged process without informing the debugger. (For example, get to a breakpoint in a console app, and close the app's console window.) The process goes into a zombie-like state and cannot be interacted with further until the debugger releases its hold.
This state appears to set the PROCESS_EXTENDED_BASIC_INFORMATION::IsProcessDeleting flag when gathering information on the process via NtQueryInformationProcess, but both the flag, structure, and function are effectively undocumented and marked "do not use" on MSDN.
Is testing this flag reliable? Is there a better, "official" API I can use?
(Yes, I know IsProcessDeleting is also set when the process is (surprise, surprise) shutting down normally. This is not a problem from my perspective.)
Nope, not that I can see. NtQueryInformationProcess isn't going away anytime soon though, if that function was removed hundreds of apps would be broken by it.

How to know if my program crashed the last time it ran?

If my program doesn't tear down correctly, the system becomes unstable. There is no workaround really. So, should my program crash and not tear down correctly, then I need to tell the user when he tries to run it again that the system was left in an unstable state. Is the right way to do this is to create a lock file when I start and delete it when I exit correctly. If I start and that file exists, then I know I crashes previously. Is this the right approach?
Two things that may be useful:
The Application Recovery and Restart API can be used on Vista and Win7. You can specify a recovery function that the OS will call for you so the user will be notified
Create an unhandled exception filter where you can try to perform some of the really critical recovery should you experience a crash elsewhere. This will work on XP too. I've used this technique before to close drivers that otherwise would hang if not closed properly.
If your program crashed and the machine was rebooted, would things still be in an unstable state? If not, then a lock file is not the approach you wish to take since the file will still exist after rebooting. Try a solution using the global atom table.
// Test if the application has crashed since the last reboot
ATOM myAtom = GlobalFindAtom ("MySecretName");
if (myAtom != 0)
{
// We crashed on last run, inform user and exit
// ...
exit (0);
}
// Create a global atom which will be destroyed only on clean termination
myAtom = GlobalAddAtom ("MySecretName");
// Run your main program here
// ...
// Clean termination, delete the atom
GlobalDeleteAtom (myAtom);
Just so you take it into account, but the lock file might not be deleted for circumstances independent of your app, .e.g. network error, file system error, o.s error.
So depending on your requirements, if it's absolutely critical to know if the current state is valid, you would probably need to determine the validity by examining all the dependant variables and states, instead of just relying on the lock file. Otherwise, it can be an easy way to monitor the exit status. Just don't rely on it to determine whether or not you should relaunch the missiles.
Microsoft Word (PPT/Excel also) follow a similar approach. A hidden file is created when a document is opened in write mode and as soon as the application exits normally it is deleted. The file may have lot more info like auto-saving document every 'x' mins etc. but the point is that your point is valid :-)

Disabling Windows error reporting (Dr. Watson) for my process

I have an application that is hosting some unstable third-party code which I can't control in an external process to protect my main application from nasty errors it exhibits. My parent process is monitoring the other process and doing "the right thing (tm)" when it fails.
The problem that I have is that Dr. Watson is still detecting crashes in the isolated process and attaching to the processes on the way down to take a crash dump. This has the two problems of:
1. Dramatically slowing down the time that it takes for me to detect a failure because the process stays alive while the crash dump is being taken.
2. Showing annoying popups to the user asking if they want to submit the error reports to Microsoft.
Clearly I would prefer to fix the bugs in the child process, but given that it isn't an option, I would like to be able to selectively disable Dr. Watson (and Windows Error Reporting in Vista+) for that process.
I am running some of my own code in the process before handing off to the untrusted bit, so if there is an API that I can call that affects the current process that would be fine.
I am aware of: http://support.microsoft.com/default.aspx/kb/188296 which would disable Dr. Watson for the entire machine. I don't want to do that because it would make me a bad citizen to trash a machine-wide setting.
I am also aware of the WerSetFlags option in Vista+ that would seem to disable windows error reporting for the current process, but I need something that will disable Dr.Watson on earlier OS versions.
The good doctor is invoked when a process does not handle a certain exception. Therefore, the common way to go would be to handle all exceptions yourself. In your case, it is much harder since you don't own the crashing process code. What you can do then, is to inject your code into the other process at runtime, and install an exception handler that will swallow the exception causing the crash. When caught, gracefully shut down the process.
There are quite a few questions here talking about injecting code into another process. As for the crash handler, you can either set an unhandled exception filter, or add a vectored exception handler. Note that for the latter, you'll have to be careful not to swallow legit exceptions that are in fact handled inside the other process, namely find a way to recognize the crashing exception and make sure it is the only one you handle.
You want to disable the GPF popup: http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx

How to reload a crashed process on Windows

How to reload a crashed process on Windows? Of course, I can run a custom monitoring Win service process. But, for example, Firefox: it doesn't seem to install such a thing, but still it can restart itself when it crashes.
On Vista and above, you can use the RegisterApplicationRestart API to automatically restart when it crashes or hangs.
Before Vista, you need to have a top level exception filter which will do the restart, but be aware that running code inside of a compromised process isn't entirely secure or reliable.
Firefox constantly saves its state to the hard disk, every time you open a tab or click a link, or perform some other action. It also saves a flag saying it shut down safely.
On startup, it reads this all back, and is able to "restore" based on that info.
Structured exception handling (SEH) allows you to catch program crashes and to do something when it happens.
See: __try and __except
SEH can be very dangerous though and could lead to your program hanging instead. Please see this article for more information.
If you write your program as an NT service then you can set the first, second and subsequent failure actions to "Restart the service".
For Windows 2008 server and Windows Vista and Windows 7 you can use the Win32 API RegisterApplicationRestart
Please see my answer here for more information about dealing with different types of program crashes.
If I recall correctly Windows implements at least some subset of POSIX and so "must" have the signal interface (things like SIGKILL, SIGSEGV, SIGQUIT etc.).
I've never done this but on linux, but you could try setting the unexpected termination trap with signal() (signal.h).
From quick scan of docs it seems that very few things can be done while handling signal, it may be possible that even starting a new process is on forbidden list.
Now that I've thought about it, I'd probably go with master/worker pattern, very simple parent thread that does nothing but spawns the worker (that does all the UI / other things). If it does not set a specific "I'm gonna die now" bit but still dies (parent process always gets message / notification that spawned process died) then master respawns the worker. The main theme is keep master very simple and hard to die due to own bugs.

Resources