TerminateProcess vs Ctrl + C

I have a console program that uses SQLite3 to maintain a database file. It takes some time to execute, but it should be safe to cancel at any time, assuming that the database is being written. (All this under Windows)

How much safer, from the point of view of the running program, to press Ctrl C in the console than to another call to the TerminateProcess program on it?

I noticed that I can get database corruption if TerminateProcess is called - I assume that this is because the program does not have the ability to end the recording. I assume that Ctrl C is better because the program receives the signal and exits itself, not the OS, killing it.

Note that the program does not actually process the signal (if SQLite does not); I am talking about the default built-in mechanisms for Win32 executables to process the Ctrl C signal.

To clarify / simplify the question asked, the record just made:

fwrite(buf, 1024*1024, 1, stream); 

During this entry, TerminateProcess will be different from Ctrl C ?

+6
windows signals console
source share
4 answers

These are all compelling arguments, but the only way to know for sure is to try. So I wrote a simple program that allocates a 1 GB buffer, assigns some data to it, and then writes it to a file using a single fwrite () file. I tried several methods to make the record "corrupt" the data (I was expecting a truncated file, in particular):

  • Call TerminateProcess (via kill perl and Win32 :: Process :: Kill)
  • Press Ctrl C
  • Using the End Process Task Manager
  • Using Process Explorer Killing Process

Nothing would stop recording in each case, the file was the right size and had the correct data. And although “Kill” will happen instantly, the process will be delayed until the recording is completed.

It seems undeniable that there is no difference between TerminateProcess and Ctrl C from the I / O point - as soon as the recording starts, it seems to be completed (prohibition of power outages).

+5
source share

Your application has the ability to handle Ctrl C and Ctrl Break , like keystrokes or signals (depending on configuration), which means the application has the ability to make a clean exit, these would be a much softer way to terminate the process, allowing it a little longer execution time, if nothing else.

TerminateProcess is more like a blow in the teeth, the application cannot handle it, it comes from the kernel, and if the application can process it, it will create all kinds of problems with the "un killable" processes, which depend on the TerminateProcess handler and refused to exit.

As I understand it, as soon as the TerminateProcess is called in the process, it cannot execute more code that it has, doesn’t clear, does not exit, just finished, you cannot process it, it just doesn't make sense if you couldn’t safety point of view.

An excellent code draft article is here for handling Windows console signals:

http://www.codeproject.com/KB/winsdk/console_event_handling.aspx

By implementing some of the above actions with signals, you can make sure that the database record has a chance to complete before the program is released, and not, perhaps, leave it to its own devices.

You can block TerminateProcess, but its "not very" polite "programming, it is more like root set programming, I saw a good article about it on rootkit.com, so look for the" Invincibility Process "there, when you have an invincible process, it could turn off in due time after receiving such a “request” and perform any cleanup before hnad, but this will certainly be a hack.

It seems to me that the behavior of Ctrl C that you see now is due to the fact that it does not immediately end the current process.

+1
source share

SQLite claims to be atomic, even during power failures, see http://www.sqlite.org/atomiccommit.html .

The only exception is that some disk systems report that the recording was successful before the data will actually be written to the disk tablets, i.e. the data is in the disk cache or the operating system is on SQLite. See http://www.sqlite.org/lockingv3.html , section 6.0 "How to Corrupt Database Files".

Processes that are completed must stop all running threads and complete pending I / O operations before they exit . Data integrity should be guaranteed, provided that the process is not broken.

0
source share

I find it safer to use Ctrl C for your purposes. This will send a signal to the program for completion. If the program does not process the signal, it stops in place.

TerminateProcess forcibly terminates the process and any child threads.

From MSDN :

The TerminateProcess function terminates the specified process and all its threads .... Notes

The TerminateProcess function is used to unconditionally call the Exit process. The state of global data maintained by dynamic link libraries (DLLs) can be compromised if TerminateProcess is used instead of ExitProcess.

TerminateProcess initiates termination and returns immediately. This stops the execution of all threads within the process and requires cancellation of all pending I / O. Termination process cannot exit until all pending I / O is completed or canceled.

The process cannot prevent ends.

There are ways for the TerminateProcess locking process, but I doubt that SQLite3 will do this.

0
source share

All Articles