Really kill current process when time elapses - c

I have a Win32 console program written in C, that needs to terminate when a certain length of time has elapsed, even if it's still busy. At the moment I'm doing this:
static VOID CALLBACK timeout(PVOID a, BOOLEAN b) { ExitProcess(0); }
...
HANDLE timer = 0;
CreateTimerQueueTimer(&timer, 0, timeout, 0, (DWORD)(time_limit * 1000),
0, 0);
This works fine in the case where the program is computationally busy when the time limit is reached, e.g. it easily passes a test case where I put an infinite loop in main. However, there is a situation where it doesn't work, and the program just stays hung indefinitely. The situation has to do with being called by a parent process, I don't know exactly what's going on, have asked a separate question about that. My question here is:
Is there a way to tell Windows to really kill the current process after a certain number of seconds, no matter what?
Update: experimented just now, WT_EXECUTEINTIMERTHREAD seems to solve the problem. That leaves a few questions:
Why does that flag matter?
If I'm not using any other time operations in the program, is it safe to ignore the warning "This flag should be used only for short tasks or it could affect other timer operations."?
If more than one choice of flag will solve the problem, which flag is it best to use?

You can use SleepEx
Suspends the current thread until the specified condition is met. Execution resumes when one of the following occurs:
AN I/O completion callback function is called,
AN asynchronous procedure call (APC) is queued to the thread OR
The time-out interval elapses.
The 3rd, or 1st option is your best bet. The condition for the first function should be your desired situation, whatever the case is in your program. Or a pre-configured amount of time.
After SleepEx follow-up by a call to ZwTerminateProcess from NTDLL.DLL. This will ensure that the process is terminated as calling ExitProcess performs prior checks before calling ZwTerminateProcess/Thread. Here you can call it yourself and ensure termination! You can fill the HANDLE parameter for ZwTerminateProcess by passing GetCurrentProcess() to the argument. Alternatively, you obtain a HANDLE to a remote process by scanning the process list via ZwQuerySystemInformation->ZwOpenProcess, or Creating a snapshot (CreateToolhelp32Snapshot ... off the top of my head) followed by Process32First->Next->OpenProcess - You can then use ZwTerminateProcess to terminate the remote process given you have the SE_DEBUG_PRIVILEGE, and the current process is executing from the same integrity level as the other process!

Related

Cancelling calculation early using pthreads

I have a program in c where I want to do some calculations which may or may not take a very long time. It is hard to know beforehand how much time the calculations will take. The program has a cli so right now I usually do something like this
./program
do calculation 243
and it starts calculating. If I want to cancel it because it takes to much time I do ctrl+c and restart the program with another calculation. Now I would like for the program to cancel the calculation itself after either q has been pressed or for example 10 seconds has passed.
I have found a way which seems to do what I expect using pthreads. I'm however wondering if this is recommended or if there are for example any memory leaks or other things that can happen.
The following is my code
void *pthread_getc(void *ptr) {
char c = '\0';
while (c != 'q')
c = getc(stdin);
pthread_cancel((pthread_t)ptr);
}
void *pthread_sleep(void *ptr) {
sleep(10);
pthread_cancel((pthread_t)ptr);
}
void pthread_cancellable(void *(*ptr)(void *), struct arg *arg) {
pthread_t thread_main, thread_getc, thread_sleep;
pthread_create(&thread_main, NULL, ptr, (void *)arg);
pthread_create(&thread_getc, NULL, pthread_getc, (void *)thread_main);
pthread_create(&thread_sleep, NULL, pthread_sleep, (void *)thread_main);
pthread_join(thread_main, NULL);
pthread_cancel(thread_getc);
pthread_cancel(thread_sleep);
pthread_join(thread_getc, NULL);
pthread_join(thread_sleep, NULL);
}
the idea being that both pthread_getc and pthread_sleep can cancel main, and once main is cancelled so are these two. Then I simply call pthread_cancellable where the first argument is a function doing the calculation and the second argument is the arguments to the calculating function.
Can something go wrong with memory leaks here or something else? Is there an easier/better way to this in c?
What happens if main is cancelled two times and if a thread gets cancelled when its already done?
Can something go wrong with memory leaks here or something else?
If the program is going to terminate after aborting the computation then there is no issue with memory leaks. The system does not rely on processes to clean up after themselves -- it will reclaim all memory allotted to the process no matter how the process used it.
But your code violates the #1 rule of pthread_cancel(): never call pthread_cancel(). And although monitoring stdin for a q keystroke could work, that's a bit odd, and it potentially gets in the way of using stdin for something else you want to add to your program later.
Is there an easier/better way to this in c?
Yes. In the first place, if the objective is simply to terminate the program at timeout / user interrupt, then do that. That is is, have any thread call exit() when you want to terminate. You do not need to cancel any threads for that.
In the second place, I don't see what is gained by implementing a custom keyboard action (type 'q' to abort) when the standard interrupt signal sent by Ctrl-C works fine, and you even get the latter for free. If you want or need to perform some kind of extra behavior in response to an interrupt signal (before or instead of terminating), then register a handler for it.
There are multiple ways you could implement the early termination behavior, but here are outlines of two I like:
No-frills abortion upon timeout (or Ctrl-C):
Only the program's initial thread is needed.
Before it launches the computation, it creates and starts an interval timer (timer_create()) to count down the timeout. Configure the timer to raise SIGINT when it expires.
That's it. You get termination via the keyboard (albeit with Ctrl-C as you already do, not 'q') and the same termination behavior as far as an external observer can see in the event of a timeout.
optional addition 1:
If desired, you can install a handler for SIGINT to get extra or different behavior upon cancellation than you otherwise would. Note, however, that there are significant limits on what a signal handler may do. For example, maybe you want to emit a message to stderr (use write(), not fprintf() for such things), or you want to exit() with non-zero status instead of terminating (directly) because of the signal.
optional addition 2:
If the program reaches a point where it is not finished but it no longer wants to be terminated when the timeout is reached then it may at that point use timer_delete() to disable the timer.
With-frills abortion upon timeout (or Ctrl-C):
If you want to perform work in response to abort of the computation that is unsuited for a signal handler (too much, needs to call functions that are not async-signal-safe, ...) then you need a thread to do that in, and additional control structures and mechanisms. This is one way to do it:
Create and initialize a mutex, a condition variable, and a flag of type sig_atomic_t, all at file scope. The contract for these is that the flag may be accessed (read or write) only by a thread that currently holds the mutex locked, and that the mutex is the same that will be associated with all waits on the CV.
Install a signal handler for SIGINT that
locks the mutex
Provided that the flag does not indicate completion, updates it to indicate cancellation
unlocks the mutex
broadcasts to the CV
The last thing the computational thread will do after completing its work is (with the mutex locked) set the flag to a value indicating completion, and then broadcast to the CV.
The initial thread will then do this:
Setup as described in the previous points
lock the mutex
Create / start an interval timer (timer_create()) that raises SIGINT when it expires, after the chosen timeout period.
Start the computational thread
loop while the flag indicates ongoing computation. In the loop body
perform a wait on the CV
The computation having either completed successfully or been canceled at this point, perform whatever final actions are appropriate and then terminate, either by returning from main() or by calling exit().
That's still pretty clean, gets you both timeout-based and keyboard-based cancellation (albeit the latter with Ctrl-C instead of 'q'), puts all the cancellation handling in one place, and requires only one thread in addition to the computational one.
optional addition: abort in response to 'q'
Although I do not recommend it, if you really must have that termination by typing 'q', then you can set up another thread that monitors for that keypress / character, and performs a raise(SIGINT) if it sees it.

Is there a difference between spawning multiple threads that runs to completion vs having a single thread wait for work?

I'm writing a piece of software that does a single very long task. To allow interruption, we have added a check-pointing function that periodically (on the order of minutes) dumps an image of the program state to disk. This takes some time, however, so I would like to switch to a model where the checkpoints are written on a separate thread rather than blocking the primary worker. (Yes, I know I need to keep it thread-safe.)
As I see it, there are two primary methods of accomplishing this task:
For each checkpoint, I pthread_create() a thread which will execute the checkpointing function once and then terminate.
For each checkpoint, I pthread_cond_signal() a single waiting thread that executes the checkpointing function and then returns to waiting.
Both methods require making an atomic copy of my working state and passing it to the checkpoint thread, as well as ensuring that the checkpoint complete successfully before I try another.
My question is if there is a compelling reason to use one method over the other.
I would argue that pthreads are a bad fit for your requirements:Regardless of whether you spawn a new thread for each backup or use a threadpool, you need to make a deep copy of your working-set, which is expensive. Also, you may need extensive synchronization if you go with the thread-pool. Instead, there's a much easier way to do it:fork().The child process inherits the entire memory-space of the parent, but on modern OSs, the copy is lazy (copy on write). Also, you don't need to worry about cleaning up the thread you started, because the fork()ed child releases its resources when it terminates. If your original program is already multithreaded, you may wish to make sure to only use async-safe functions in the child, but thankfully write() is async-safe (as is open() and unlink()). To avoid your child turning into a zombie, you need to call waitid(P_ALL, 0, siginfo_t *infop, WEXITED | WNOHANG) in a loop until it returns nonzero or the siginfo_t * indicates that the child has not yet exited. This avoids stalling the parent in case the child is not done with the backup before the next backup-point is reached.
Don't go with continually creating/terminating/destroying/joining threads if you can possibly avoid it. It's expensive in terms of latency and cycles, has the risk of unwanted multiple threads doing overlapping work and is difficult to debug.
Just create one thread once, at app startup, and don't terminate it. Loop it round some synchro object and sSignal it when you need to, or run a timer or sleep loop to perform your image dumps.

Function timeouts in C and thread

Hello everyone i have a question about timeouts in c so i ask you guys.
So i'm making a server application in C that uses POSIX threads to accept multiple simpultenious connections but implementing timeouts was harder than i expected as i read the message (HTTP requests) in parts first the start line than the headers etc, etc, and i initialy used select() to detect if the socket was ready for reading but that way if the client sends the start line only than the server will continue waiting for the headers and body without ever timing out so what i did is i put all the code that reads the message in one function and i wan't to implement a timeout for the entire function, say if the function doesnt return in x seconds than a timeout function is called and the thread is exited...
[Things that i have tried]
putting multiple select calls (one for every socket read) but that ended up in a mess of having to calculate remaining time for each operation.
i didn't actually try to use an alarm signal as i've heard that signals effect the entire process and not a specific thread that would cause one time out to timeout every parallel connection..
thanx in advance.. B)
There is no proper way to terminate a thread function other than letting it finish.
Every attempt to finish a thread from the outside could lead to resource (mostly but not only memory) leaks, state variables in nondeterministic state, and so. Please don't do it. Never. The normal way of terminating a thread function from the outside is to make it listen to some means of inter thread communication (which can be a sync object, a volatile variable or even a message loop), and exit the function core when it is necessary. Normally you would realize it by having a single test in the cycle condition of the thread if it is looping or testing before every long-running operation inside your thread.
Now if you store the timestamp of the function start and test at every cycle condition/long-running test if currenttimestamp > timestamp + timeout, you can exit from inside your thread and voilá; your problem is solved.

How do I exit a long-running function in C?

I have a situation as follows:
int funcA()
{
/*There will call funcB*/
funcB();
}
funcB() maybe last for a long time. And if I find it has been running for over 5 minutes, I want to abort funcB() and continue to do other thing.
How can I do this?
One way to do this is to measure the time elapsed within funcB() since entering, e.g. if you have a loop in funcB(). Ideally, your function returns a value that indicates success or early termination, so funcA() has a way to know if funcB() completed.
Another way is to run funcB() in its own thread. If your main thread determines that 5 min have passed, it can terminate the thread that is executing funcB().
If you are a beginner, why not create a new process by using fork(). Then start timing within the new process and then terminate the process if it exceeds 5 minutes. Even though in most cases threads are better to use, it's easier for beginners to create a new process.
You should code a feature in funcB so it will know to return.. Anything else is somewhat unsafe, if funcB for example writes to files. There are many ways to do this. I'm assuming you have a loop in funcB, which you want to abort. If you have something else, like blocking IO operation, you have to do this a bit differently.
If you have single thread, you could code the abort logic directly into funcB. You could also give function pointer argument for funcB, which then calls the function every loop round to see if it could abort. That way you can more easily have different abort conditions.
If you have multiple threads, you should use an atomic flag variable, which you set from other thread when you want funcB to abort, and in funcB loop you then test it. This is the most common way to twll orher thread running a loop to quit.
Addition: If you are going to abort file operations, it's possible to do it safely if you do a few things:
The function must do writes to temporary file (at same disk partition), and then close it and use rename operation (which is atomic at OS level when files are in same partition) to create/replace the final file. That way, if operation is aborted, the final file will not be left in corrupted state.
The caller must have the file handle or file descriptor of the temporary file, so it can close the file if file operation was aborted while file was open. If file operation happens in another process, which is killed, then that will close all file handles and this is not needed.
Caller should also always try to remove the temp file, in case the aborted function/thread/process did not have a chance to rename it to final name or remove it.
Addition 2: In Unix/Linux you can use alarm() function. See this: Simple Signals - C programming and alarm function

Forcing a function to end using SIGALRM in C

Right now I have a function connected to SIGARLM that goes off after 1 second and will re-alarm itself to go off in another second everytime. There's a test in the logic of the SIGALRM function I wrote to see if a certain timeout has been reached and when it does I need it to kill a function that's running. Does anybody know how I can do this?
I forgot to mention: in the function that needs to be killed it waits on scanf() and the function needs to die even if scanf() hasn't returned yet.
One approach that might be worth looking into is using select to poll stdin and see if any data is ready. select lets you wait for some period of time on a file descriptor, controlling when you can be interrupted and by what, and seems like it's perfect here. You could just sit in a loop waiting for up to a second, then failing gracefully if no data is available. That way, SIGALRM wouldn't need to kill the function; it would take care of that all by itself.
Not sure exactly what you're asking or what the structure of the program is. If I understand correctly: some function is running and you want to terminate it if it's been running for X time. You have a SIGALARM wake up every second and that will check the running time of the other function and do the terminate.
How do you plan to kill the function? Is it a function in the same process, or is it a separate process. Is your question how to terminate it or how to tell when it needs to be terminated?
I've done something which I believe is similar. I had a multi-threaded application with a structure which contained information about the threads I wished to monitor. The structure contained a member variable "startTime". My monitoring (SIGALARM) function had access to a list of threads. When the monitor woke up it would traverse the list, compare current time to each thread startTime and send a message to the function if it had exceeded it's allowed runtime.
Does this help at all?
You could use a (global) variable to communicate between the signal handler and the function that should be stopped. The function then would check that variable to see if it should still continue running or if it should exit.
Something line this:
volatile int worker_expired = 0;
void worker() {
while (!worker_expired) {
// ...
}
}
void sig_alrm() {
worker_expired = 1;
}
If you want the signal to terminate IO operations, you need to make sure it's an interrupting signal handler. On modern systems, system calls interrupted by signals automatically restart unless you specify otherwise. Use the sigaction function rather than the signal function to setup your signal handlers if you want control over things like this. With sigaction, unless you specify SA_RESTART, signal handlers can interrupt.
If you're using file-descriptor IO functions like read, you should now get the effects you want.
If you're using stdio functions like fscanf, getting interrupted by a signal will put the FILE into an error state that can only be cleared by clearerr, and will lose any partial input in the buffer. Interrupting signals do not mix very well with stdio unless you just want to abort all operations on the file and close it when a signal is received.
So ... to restate slightly: it isn't so much that you want to kill the function as that you want any pending i/o to terminate and the function to exit.
I would either:
use select() to periodically wake up and check a flag set by the signal handler. if the flag isn't set and there's no input pending then loop and call select() again.
i suspect that your SIGALARM handler is doing more than just checking this one timer, and so using pselect() to check for i/o OR SIGALARM is probably not an option for you. i wonder if you could grab a user defined signal, and pass that in pselect. then your alarm handler would send that user defined signal.
Regarding choice 1, if SIGALARM is waking every second then you can adjust the time that select() sleeps to be within your maximum error latency. In other words assume that the timeout occurs immediately after the call to select(), then it will take until select() wakes up to detect the flag set by the SIGALARM handler. So if select() wakes up 10 times per second then it could take up to 1/10 second to detect the setting of the "give up" flag (set by the SIGALARM handler).

Resources