diff options
| author | jolsa@redhat.com <jolsa@redhat.com> | 2011-08-28 19:54:51 +0200 |
|---|---|---|
| committer | Jiri Olsa <Jiri Olsa jolsa@redhat.com> | 2011-11-24 21:20:27 +0100 |
| commit | ba8c8bd79445a34d24b061cb6fed94578f0af212 (patch) | |
| tree | 13e95e9cf24934a1f57d3f0a35b44e40df24c64e /src/audit-error.c | |
| parent | fa668f3b96fd0363bae1adc640105b3914faa138 (diff) | |
| download | latrace-ba8c8bd79445a34d24b061cb6fed94578f0af212.tar.gz latrace-ba8c8bd79445a34d24b061cb6fed94578f0af212.tar.xz latrace-ba8c8bd79445a34d24b061cb6fed94578f0af212.zip | |
error simulation: adding sigsegv handler support
Diffstat (limited to 'src/audit-error.c')
| -rw-r--r-- | src/audit-error.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/audit-error.c b/src/audit-error.c index 428d41e..b313a56 100644 --- a/src/audit-error.c +++ b/src/audit-error.c @@ -6,6 +6,7 @@ #include <sys/syscall.h> #include <strings.h> #include <string.h> +#include <signal.h> #include "config.h" #include "backtrace.h" @@ -73,6 +74,43 @@ static void share_info(struct lt_config_audit *cfg, dump_backtrace(cfg->sh, 0); } +static struct lt_config_shared *ss_cfg; + +static void sig_segv_handler(int sig) +{ + char text[LT_MAXMSG]; + struct timeval tv; + + gettimeofday(&tv, NULL); + + snprintf(text, LT_MAXMSG, "ERROR SIMULATION got SIGSEGV"); + + if (lt_sh(ss_cfg, pipe)) { + char buf[LT_FIFO_MSG_MAXLEN]; + int len; + + len = lt_fifo_mtext_get(ss_cfg, buf, &tv, text); + /* TODO erro handling */ + lt_fifo_send(ss_cfg, pipe_fd, buf, len); + } else + lt_out_text(ss_cfg->sh, &tv, syscall(SYS_gettid), text); + + dump_backtrace(ss_cfg, 0); + exit(-1); +} + +static int install_sigsegv(struct lt_config_shared *cfg) +{ + struct sigaction act; + + bzero(&act, sizeof(act)); + act.sa_handler = sig_segv_handler; + + ss_cfg = cfg; + + return sigaction(SIGSEGV, &act, NULL); +} + int lt_error_sym_exit(struct lt_config_audit *cfg, struct lt_symbol *sym, struct timeval *tv, @@ -104,6 +142,10 @@ int lt_error_sym_exit(struct lt_config_audit *cfg, /* and share some info about the sinner */ share_info(cfg, esym, tv, lr, inregs); + + if (esym->handle_sigsegv && install_sigsegv(cfg->sh)) + PRINT_VERBOSE(cfg, 1, "failed to install SIGSEGV handler\n"); + return 0; } @@ -135,6 +177,7 @@ static int symbol_add(struct lt_config_audit *cfg, sym->name = strdup(def_sym->symbol); sym->ret = def_sym->ret; + sym->handle_sigsegv = def_sym->handle_sigsegv; e.key = sym->name; e.data = sym; |
