Add more sofisticated fatal signal handlers
This commit is contained in:
parent
3b14fecf40
commit
1b12716e0e
5 changed files with 189 additions and 73 deletions
2
Makefile
2
Makefile
|
@ -64,7 +64,7 @@ SRCS = src/main.c \
|
|||
src/htsmsg_xml.c \
|
||||
src/settings.c \
|
||||
src/htsbuf.c \
|
||||
src/parachute.c \
|
||||
src/trap.c \
|
||||
src/avg.c \
|
||||
src/htsstr.c \
|
||||
src/rawtsinput.c \
|
||||
|
|
20
src/main.c
20
src/main.c
|
@ -56,7 +56,7 @@
|
|||
#include "iptv_input.h"
|
||||
#include "transports.h"
|
||||
#include "v4l.h"
|
||||
#include "parachute.h"
|
||||
#include "trap.h"
|
||||
#include "settings.h"
|
||||
#include "ffdecsa/FFdecsa.h"
|
||||
|
||||
|
@ -87,18 +87,6 @@ doexit(int x)
|
|||
running = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pull_chute (int sig)
|
||||
{
|
||||
char pwd[PATH_MAX];
|
||||
|
||||
if(getcwd(pwd, sizeof(pwd)) == NULL)
|
||||
strncpy(pwd, strerror(errno), sizeof(pwd));
|
||||
|
||||
tvhlog_spawn(LOG_ERR, "CRASH",
|
||||
"HTS Tvheadend crashed on signal %i (pwd \"%s\")",
|
||||
sig, pwd);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -349,7 +337,7 @@ main(int argc, char **argv)
|
|||
|
||||
pthread_mutex_lock(&global_lock);
|
||||
|
||||
htsparachute_init(pull_chute);
|
||||
trap_init(argv[0]);
|
||||
|
||||
/**
|
||||
* Initialize subsystems
|
||||
|
@ -452,8 +440,8 @@ static void
|
|||
tvhlogv(int notify, int severity, const char *subsys, const char *fmt,
|
||||
va_list ap)
|
||||
{
|
||||
char buf[512];
|
||||
char buf2[512];
|
||||
char buf[2048];
|
||||
char buf2[2048];
|
||||
char t[50];
|
||||
int l;
|
||||
struct tm tm;
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Crash Parachute
|
||||
* Copyright (C) 2007-2008 Andreas Öman
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "parachute.h"
|
||||
#include <assert.h>
|
||||
|
||||
static void (*htsparachute_userhandler)(int);
|
||||
|
||||
static void
|
||||
htsparachute_sighandler (int sig)
|
||||
{
|
||||
signal(SIGSEGV, SIG_DFL);
|
||||
signal(SIGBUS, SIG_DFL);
|
||||
signal(SIGILL, SIG_DFL);
|
||||
signal(SIGABRT, SIG_DFL);
|
||||
signal(SIGFPE, SIG_DFL);
|
||||
|
||||
if (htsparachute_userhandler)
|
||||
htsparachute_userhandler(sig);
|
||||
|
||||
assert(!*"parachute");
|
||||
}
|
||||
|
||||
void
|
||||
htsparachute_init (void (*handler) (int))
|
||||
{
|
||||
signal(SIGSEGV, htsparachute_sighandler);
|
||||
signal(SIGBUS, htsparachute_sighandler);
|
||||
signal(SIGILL, htsparachute_sighandler);
|
||||
signal(SIGABRT, htsparachute_sighandler);
|
||||
signal(SIGFPE, htsparachute_sighandler);
|
||||
htsparachute_userhandler = handler;
|
||||
}
|
176
src/trap.c
Normal file
176
src/trap.c
Normal file
|
@ -0,0 +1,176 @@
|
|||
/**
|
||||
* Crash handling
|
||||
* Copyright (C) 2009 Andreas Öman
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <link.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <ucontext.h>
|
||||
#include <execinfo.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <libavutil/sha1.h>
|
||||
|
||||
#include "trap.h"
|
||||
#include "tvhead.h"
|
||||
|
||||
|
||||
static char traceline[4096];
|
||||
static int tracepos = 0;
|
||||
|
||||
#define MAXFRAMES 100
|
||||
|
||||
static void
|
||||
traceappend(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int n;
|
||||
|
||||
va_start(ap, fmt);
|
||||
n = vsnprintf(traceline + tracepos, sizeof(traceline) - tracepos, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if(n < 1)
|
||||
return;
|
||||
tracepos += n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
traphandler(int sig, siginfo_t *si, void *UC)
|
||||
{
|
||||
ucontext_t *uc = UC;
|
||||
static void *frames[MAXFRAMES];
|
||||
int nframes = backtrace(frames, MAXFRAMES);
|
||||
|
||||
int i;
|
||||
|
||||
traceappend("SIGNAL: %d ", sig);
|
||||
traceappend("REGDUMP[%d]: ", NGREG);
|
||||
for(i = 0; i < NGREG; i++) {
|
||||
#if __WORDSIZE == 64
|
||||
traceappend("%016llx ", uc->uc_mcontext.gregs[i]);
|
||||
#else
|
||||
traceappend("%08x ", uc->uc_mcontext.gregs[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
traceappend("STACKTRACE[%d]: ", nframes);
|
||||
for(i = 0; i < nframes; i++)
|
||||
traceappend("%p ", frames[i]);
|
||||
|
||||
tvhlog_spawn(LOG_ALERT, "CRASH", "%s", traceline);
|
||||
}
|
||||
|
||||
static struct AVSHA1 *binsum;
|
||||
|
||||
|
||||
static int
|
||||
callback(struct dl_phdr_info *info, size_t size, void *data)
|
||||
{
|
||||
int j;
|
||||
|
||||
// Other lib, just record its presence
|
||||
if(info->dlpi_name[0]) {
|
||||
traceappend("%s ", info->dlpi_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Our self, hash huge R-X segments which in practice is the main text seg.
|
||||
|
||||
for(j = 0; j < info->dlpi_phnum; j++) {
|
||||
if(info->dlpi_phdr[j].p_flags & PF_W)
|
||||
continue;
|
||||
|
||||
if(!(info->dlpi_phdr[j].p_flags & PF_X))
|
||||
continue;
|
||||
|
||||
if(info->dlpi_phdr[j].p_memsz < 65536)
|
||||
continue;
|
||||
|
||||
av_sha1_update(binsum,
|
||||
(void *)(info->dlpi_addr + info->dlpi_phdr[j].p_vaddr),
|
||||
info->dlpi_phdr[j].p_memsz);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern const char *htsversion_full;
|
||||
|
||||
|
||||
void
|
||||
trap_init(const char *ver)
|
||||
{
|
||||
uint8_t digest[20];
|
||||
struct sigaction sa, old;
|
||||
char path[256];
|
||||
|
||||
traceappend("PRG: %s [%s] CWD: %s ", ver, htsversion_full,
|
||||
getcwd(path, sizeof(path)));
|
||||
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
|
||||
sa.sa_sigaction = traphandler;
|
||||
sa.sa_flags = SA_SIGINFO | SA_RESETHAND;
|
||||
|
||||
sigaction(SIGSEGV, &sa, &old);
|
||||
sigaction(SIGBUS, &sa, &old);
|
||||
sigaction(SIGILL, &sa, &old);
|
||||
sigaction(SIGABRT, &sa, &old);
|
||||
sigaction(SIGFPE, &sa, &old);
|
||||
|
||||
|
||||
traceappend("OBJS: ");
|
||||
binsum = malloc(av_sha1_size);
|
||||
|
||||
av_sha1_init(binsum);
|
||||
dl_iterate_phdr(callback, NULL);
|
||||
|
||||
av_sha1_final(binsum, digest);
|
||||
|
||||
traceappend("SHA1: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x ",
|
||||
digest[0],
|
||||
digest[1],
|
||||
digest[2],
|
||||
digest[3],
|
||||
digest[4],
|
||||
digest[5],
|
||||
digest[6],
|
||||
digest[7],
|
||||
digest[8],
|
||||
digest[9],
|
||||
digest[10],
|
||||
digest[11],
|
||||
digest[12],
|
||||
digest[13],
|
||||
digest[14],
|
||||
digest[15],
|
||||
digest[16],
|
||||
digest[17],
|
||||
digest[18],
|
||||
digest[19]);
|
||||
|
||||
free(binsum);
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Crash Parachute
|
||||
* Copyright (C) 2007-2008 Andreas Öman
|
||||
/**
|
||||
* Crash handling
|
||||
* Copyright (C) 2009 Andreas Öman
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,10 +16,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HTSPARACHUTE_H
|
||||
#define HTSPARACHUTE_H
|
||||
#ifndef TRAP_H__
|
||||
#define TRAP_H__
|
||||
|
||||
#include <signal.h>
|
||||
void trap_init(const char *swname);
|
||||
|
||||
#endif /* TRAP_H__ */
|
||||
|
||||
void htsparachute_init (void (*handler) (int));
|
||||
#endif /* HTSPARACHUTE_H */
|
Loading…
Add table
Reference in a new issue