diff options
Diffstat (limited to 'src/rc')
-rw-r--r-- | src/rc/Makefile | 1 | ||||
-rw-r--r-- | src/rc/rc.c | 40 |
2 files changed, 41 insertions, 0 deletions
diff --git a/src/rc/Makefile b/src/rc/Makefile index e73cd713..2779a447 100644 --- a/src/rc/Makefile +++ b/src/rc/Makefile @@ -33,6 +33,7 @@ CLEANFILES+= ${ALL_LINKS} LDFLAGS+= -L../librc -L../libeinfo LDADD+= -lutil -lrc -leinfo #CFLAGS+= -ggdb +CPPFLAGS+= $(shell test "x$(DEBUG)" = x && echo -DRC_DEBUG=0 || echo -DRC_DEBUG=1) LDFLAGS+= $(shell test -d ../../.git && echo -Wl,--rpath=../librc -Wl,--rpath=../libeinfo) MK= ../../mk diff --git a/src/rc/rc.c b/src/rc/rc.c index 499e0dc6..65501c6a 100644 --- a/src/rc/rc.c +++ b/src/rc/rc.c @@ -898,6 +898,44 @@ interactive_option: } +static void catch_a_baddie(int sig) +{ + pid_t crashed_pid = getpid(); + + switch (fork()) { + case -1: _exit(sig); + case 0: { + char pid[10]; + sprintf(pid, "%i", crashed_pid); + printf("\nAuto launching gdb!\n\n"); + _exit(execlp("gdb", "gdb", "--quiet", "--pid", pid, "-ex", "bt full", NULL)); + } + default: { + int status; + wait(&status); + } + } + + _exit(1); +} +static void init_bad_signals(void) +{ + struct sigaction sa; + sigset_t full; + + if (!RC_DEBUG) + return; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = catch_a_baddie; + sigfillset(&full); + sa.sa_mask = full; + + sigaction(SIGBUS, &sa, NULL); + sigaction(SIGILL, &sa, NULL); + sigaction(SIGSEGV, &sa, NULL); +} + #include "_usage.h" #define getoptstring "o:" getoptstring_COMMON static const struct option longopts[] = { @@ -932,6 +970,8 @@ int main(int argc, char **argv) char *token; #endif + init_bad_signals(); + applet = basename_c(argv[0]); LIST_INIT(&service_pids); atexit(cleanup); |