I am trying to use sigwait() for SIGSEGV and other signals and then do something (says writing the timestamp to a file). Then, I would like the program to behave as if the signal were never caught (e.g. a coredump is generated when SIGSEGV happens -- assuming the system is configured for coredump).
I read through couple manpages, and I don't see an obvious way to do so.
Any suggestion?
Thanks in advance!
You can register a signal handler that won't cause the program to crash. Once you receive the signal, you'll enter the signal handler, and after executing the signal handler (write to file you said), you'll reenter the program where you left off.
If you want a core dump, you can use the linux core(5) command and it will create a core dump in your signal handler without ending your process.
http://www.alexonlinux.com/signal-handling-in-linux#signal_masks
I believe you can not handle few signals the way you want to for example
SIGKILL
SIGSEGV
as manual itself states The signals SIGKILL and SIGSTOP cannot be caught or ignored
check below links
SIGNAL(7) and SIGNAL(2) These links should provide good enough details on signal handling in linux
You can however register a signal handler to handle few other signals
to list signals in operating system like linux you can use below command
kill -l
and as far as generating core dump is conserned its generated by operating system click here for more info
check the example code here
Related
I know that a SIGINT signal can be raised by the user with Crtl + C or a kill command, but what needs to happen for the system to raise a SIGINT by itself? This question comes to my mind because my system just caught a SIGINT signal while using the read() function in C to read incoming messages in a Unix-like real-time operating system, and it was not user-triggered.
I've been looking on the Internet and I could not find anything related to a system-triggered SIGINT signal, so your help would be more than welcome.
I'm writing a multi-threaded program that shall run on a Linux system. I want to be sure that, if the program was in a reliable running condition (i.e. no segmentation faults, no abort, etc...), on exit it finalises a file writing some trailing information. To do so I want to handle the termination signals in order to trigger a graceful shut down.
Since it is a multi-threaded program all the signals are masked for all the threads but the main, which call sigwait on a signal set filled only with the termination signals. So all other signals are handled by their default action.
Is this a good practice, or I should provide a custom action for every signal?
Is this a good practice,
Yes absolutely. Handling termination signals in a multi-threaded environment any other way(by not having a single thread responsible for them) is virtually impossible.
or I should provide a custom action for every signal?
No. You'd normally want to handle SIGINT, SIGTERM and SIGHUP. SIGKILL can't be handled, and I'd leave SIGQUIT alone so it could be used to core-dump the application.
Use signalfd()!
This lets you handle signals along with file descriptor readiness in a single select() call.
When I was googling my gdb and sigwait issue, I found this kernel bug thread
GDB is not trapping SIGINT. Ctrl+C terminates program when should break gdb.
Quote:
gdb puts the debugged process in its own pgrp and sets the terminal to that pgrp.
When you hit C-c, the signal goes to the current pgrp, i.e. to the debugged process and not to gdb. When a signal is delivered, ptrace will intercept it and let gdb decide what to do before it actually reaches the debugged process.
However, your program uses sigwait and so the signal is never actually delivered. Instead, you dequeue it via sigwait without going through actual signal delivery. ptrace only reports a signal that is about to be delivered. When you use sigwait, technically the signal is blocked the whole time and never delivered as such.
This comment got me more curious about how signal and GDB actually works,
1) What is the difference between "signal delivered" and "signal queued"?
2) How does GDB trap signals while the signal is sent to the debugged process?
Thanks,
First of all, I do know that there was a similar question here in the past.
But that question wasn't answered properly. Instead, it diverted into suggestion what to do to catch signals.
So just to clarify: I've done whatever needs to be done to handle signals.
I have an application that forks a daemon that monitors the main process through pipe.
If a main process crashes (e.g. segmentation fault), it has a signal handler that writes all the required info to pipe and aborts.
The goal is to have as much info as possible when something bad happens to the application, w/o messing with "normal" operation, such as SIGHUP, SIGUSR1, etc.
So my question is: which signals should I catch?
I mean signals that w/o me catching them would cause application to abort anyway.
So far I've come up with the following list:
SIGINT (^C, user-initiated, but still good to know)
SIGTERM (kill <pid> from shell or, AFAIK, can be result of OutOfMemory)
SIGSEGV
SIGILL
SIGFPE
SIGBUS
SIGQUIT
Does anybody know if I miss something? kill -l has lots of them... :)
I'm looking at my copy of advanced programming the unix environment (Stevens). According to the table in the section on signals, the following POSIX signals will by default terminate the process, if you don't catch them. It wouldn't be unreasonable to monitor all of these that you don't use:
SIGABRT
SIGALRM
SIGFPE
SIGHUP
SIGILL
SIGINT
SIGKILL
SIGPIPE
SIGQUIT
SIGSEGV
SIGTERM
SIGUSR1
SIGUSR2
You can catch all of these except SIGKILL, but hopefully SIGKILL won't come up very often for you.
Note that your signal man page (man 7 signal) should give you the proper list for your system - this is the POSIX list, and may differ depending on your architecture.
You should not catch the signal and write the code to a pipe. This is both unnecessary and not failsafe.
Let me quote an answer from the question you linked to, to point out why it's not failsafe: "What makes you think that a SEGV hasn't already corrupted your program memory"
Now you may be wondering how to do it better, and why I've said it is "unnecessary".
The return code of the waitpid syscall can be checked using WIFSIGNALED() to determine whether the process was terminated normally or via a signal, and WTERMSIG() will return the signal number.
This is failsafe and it does not require a handler or a pipe. Plus, you don't need to worry what to catch, because it will report every signal that terminates your process.
It depends: whatever signal you like if that's useful to inform the user something bad just happened. However SIGKILL and SIGSTOP cannot be caught.
Trying to build a debugger in C for fuzzing.
Basically in linux, I just want to start a process via fork and then execve(), then monitor this process to see if it crashes after 1 second.
On linux, is this done via creating the process then monitoring the SIGNALs it generates for anything that looks like a crash? Or is it about monitoring the application and? I'm not sure.
Use the ptrace(2) system call:
While being traced, the child will stop each time a signal is
delivered, even if the signal is being ignored. (The exception is
SIGKILL, which has its usual effect.) The parent will be notified at
its next wait(2) and may inspect and modify the child process while it
is stopped. The parent then causes the child to continue, optionally
ignoring the delivered signal (or even delivering a different signal
instead).
The signals you should be interested in, regarding to the process having crashed are SIGSEGV (restricted memory access), SIGBUS (unaligned data access), SIGILL (illegal instruction), SIGFPE (illegal floating-point operation), etc.