c/linux infinite loop application: deallocate memory if kill -9 command is called
Asked Answered
A

6

6

I developed a C application in linux that contains an infinite loop while(1). There are some pointers that are dynamically allocated and are useful under the infinite loop, so the only time to deallocate memory is after interrupting the while(1) by ctrl-z, ctrl-c, kill -9 apppid, killall appname. So the idea is that I associate new handler that deallocates memory to the interruption events signals.

void deallocatehandler(int signal){ printf("Memory Deallocation\n"); exit(0);}

int main(){
    signal(SIGINT, &deallocatehandler);
    signal(SIGTSTP, &deallocatehandler);
    signal(SIGKILL, &deallocatehandler);

    while(1){
        /**
        Some code here
        **/
    }
}

If I press ctrl-c or ctrl-z the handler is called but the problem is with SIGKILL. The commands kill -9 and killall doesn't launch the handler.

Has someone an idea why? and is there suggestions to correct it?

Anselmi answered 24/10, 2017 at 10:30 Comment(7)
SIGKILL can't be handle, read the manuel.Approbate
@Approbate so what's the idea to deallocate memory if we call kill command?Anselmi
You can refer to question in this link #7376728Liard
Well, you can't with SIGKILL, this signal is used to stop a process whatever. We use SIGTERM to end a process properly.Approbate
Possible duplicate of C++ : how to close a tcp socket (server) when receiving SIGKILLBreakable
Even for other signals than SIGKILL and SIGSTOP (which both cannot be caught) malloc() and free() are not safe to use in any signal handler.Incomplete
Also, you can only safely call async-signal-safe functions from a signal handler. Functions like malloc(), free(), and even printf() are not async-signal-safe and shouldn't be called from a signal handler.Mhd
N
5

The whole point of SIGKILL is to kill the process no matter what. That's why you're not allowed to handle it.

In most cases, you start with a SIGTERM to give the process a chance to exit nicely. SIGKILL is usually used as a last resort when SIGTERM does not work. After all, the expected behavior from SIGTERM is that the process exits. If it doesn't you know that something is wrong.

From the manual

The SIGTERM signal is a generic signal used to cause program termination. Unlike SIGKILL, this signal can be blocked, handled, and ignored. It is the normal way to politely ask a program to terminate.

...

The SIGKILL signal is used to cause immediate program termination. It cannot be handled or ignored, and is therefore always fatal. It is also not possible to block this signal.

In the same document, you can also read this interesting thing

In fact, if SIGKILL fails to terminate a process, that by itself constitutes an operating system bug which you should report.

Nunnery answered 24/10, 2017 at 10:41 Comment(0)
D
3

You can't catch SIGKILL and SIGSTOP signals. So your signal handler wouldn't do anything. There's nothing you can do when your process receives SIGKILL, let alone any memory cleanup. On Linux, memory will be cleaned up on program exit, so this is probably not an issue. Usually such cleanup-on-exit is done for SIGTERM.

The correct answer is don't send SIGKILL (kill -9 should only be used if kill itself doesn't work). That's not the way to request to a process to terminate itself. Send SIGTERM first and if it doesn't work, then send SIGKILL.

Dean answered 24/10, 2017 at 10:43 Comment(0)
B
2

man 7 signal

When you SIGKILL a process, you don't ask it to terminate nicely. You ask the kernel to stop any further execution for that process. Thus, the process can't be aware it has received a SIGKILL.

But it shouldn't matter for you, since a SIGKILL shall only be issued when SIGTERM has shown no success.

Biped answered 24/10, 2017 at 10:43 Comment(0)
W
2

So the idea is that I associate new handler that deallocates memory to the interruption events signals.

Not needed! After the process terminates, whatever the reason was, all memory is deallocated from the kernel. So you have no need to do that manually.

With IPC resources and semaphores you will have this problem which can't be handled properly at all.

Whirligig answered 24/10, 2017 at 10:46 Comment(5)
I mean memory dynamically allocated with malloc or calloc. It must be deallocated with by free. If we don't deallocate it in the app so we will have a garbage.Anselmi
@KallelOmar: No, dynamic allocated memory will be freed after process terminates. Simply allocate a huge amount of data and terminate your process and repeat that 1000 times. You will not run out of memory at all, because the kernel do the job!Whirligig
that's why I thought to add handle to the corresponding signal, to free dynamic allocated memory before quitingAnselmi
Again: You can't! kill -9 terminates the process, no handler is called! And there is no need for the handler as the kernel frees your memory resources. But also again: Of you use IPC resources or others, your system keeps that resources and you have to deal with that problem OUTSIDE your application.Whirligig
@KallelOmar: Why do you will not read my answer? I say: The kernel will free your resources. It doesn't matter how it works. So simply forget about! There simply will be no memory leak AFTER the process terminates.Whirligig
R
2

Your question is ill-posed for several reasons.

First, malloced memory is freed when your process terminates. Most machines would be completely unusable if modern architectures wouldn't do this automatically.

Second, some signals and some ways of process termination aren't catchable. So for these there is no hope of doing repairwork anyhow. Among the methods that terminate an execution without much cleanup are some signals, abort, quick_exit, _Exit.

Third, using signalhandlers for cleanup jobs is complete overkill. The C library has atexit and at_quick_exit (since C11) handlers that are designed for that purpose. So if you have to do something special when an execution terminates (such as writing some final message to a socket, cleaning up files or shared memory) use the tools that were invented for this.

Raymund answered 26/10, 2017 at 19:6 Comment(1)
atexit and at_quick_exit functions is something new for me that I learned from your answer thank you :)Anselmi
L
0

You can't catch SIGKILL (kill -9) by definition. It is meant as a "last resort" way to kill a process, so for this reason the process must not be able to catch it. For a friendly termination request, check for SIGTERM (kill -15 or kill without specific value).

But you should in general not want to catch such events, unless you need to do very specific clean-up actions. The memory will be deallocated but the Operating System; no need for your program to catch the signals only to free the memory.

Louiselouisette answered 24/10, 2017 at 10:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.