2

I am interested in executing a certain command every time any program I run outputs "segmentation fault". Basically I have a bash script that writes the timestamp in a log file and do some other stuff as well.

For my coursework, one module requests that we do this for each exercise. Sure I can make a script and run each program from within the script, but I was wondering if there is any way of generalizing this.

What I want is really for any program that is run by an user, if output contains "segmentation fault" execute command

  • smells like homework – Eduardo Cola Feb 16 '16 at 20:02
  • 2
    "create a signal handler for SIGSEGV" is a coding question and not an Ubuntu question – Rinzwind Feb 16 '16 at 20:03
  • @EduardoCola Well, it's not. It's just that I have a module with a bunch of exercises and I'm too lazy to change the script to fit each one. Plus I'm quite interested in this in case I'll ever need to log stuff easily based on output, without modifying the program – Mihai Bujanca Feb 16 '16 at 20:05
  • @Rinzwind "segmentation fault" was just to give context. What I'd like to do is set some string (for example segfault - maybe I'm doing java and I'm interested in a particular error occurring). I know exception handling is usually done from within programs - but I'm looking for something that is more system-wide and targets similar behaviour from multiple programs. Indeed (thanks), for SIGSEGV in particular, a handler will work - but how about other outputs (that are not necessarily a well-defined signal)? – Mihai Bujanca Feb 16 '16 at 20:08
  • You should know that "Segmentation fault" is not printed by the command, but by the shell. So no utility that captures the program's output will get that. Correspondingly, often the return code of a program that dies of SIGSEGV maybe 139. – muru Feb 16 '16 at 20:22
2

A program segfaulting's exit status is set to 139 by Bash (so this applies at least to programs which didn't define a handler for SIGSEV receiving a SIGSEV while running in Bash: it should fit your usage case):

$ cat foo.c 
#include <stdio.h>

int main() {
    char *ptr = NULL;
    *ptr = 'a';
    return 0;
}
$ gcc foo.c -o foo
$ ./foo
Segmentation fault (core dumped)
$ echo $?
139

You could set PROMPT_COMMAND to something like this in ~/.bashrc:

PROMPT_COMMAND='[ $? -eq 139 ] && printf "SIGSEV received\n"'

Changing printf "SIGSEV received\n" to the command you wish to run.

$ PROMPT_COMMAND='[ $? -eq 139 ] && printf "SIGSEV received\n"'
$ printf '\n'

$ ./foo
Segmentation fault (core dumped)
SIGSEV received
  • 1
    Technically, none of that is due it being in C, or using glibc. The shell sets the exit status of a process killed by a signal to be 128+(numeric value of signal), and SIGSEGV is 11. (See unix.stackexchange.com/a/252006/70524) – muru Feb 16 '16 at 20:35
  • @muru That sounds right. Misconceptions. But then I guess it's safe to assume Bash + SIGSEV = exit status 139 (unless handled)? – kos Feb 16 '16 at 20:57
  • Yes, I'd say so. – muru Feb 16 '16 at 21:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.