summaryrefslogtreecommitdiffstats
path: root/src/audit-error.c
diff options
context:
space:
mode:
authorjolsa@redhat.com <jolsa@redhat.com>2011-08-28 19:54:51 +0200
committerJiri Olsa <Jiri Olsa jolsa@redhat.com>2011-11-24 21:20:27 +0100
commitba8c8bd79445a34d24b061cb6fed94578f0af212 (patch)
tree13e95e9cf24934a1f57d3f0a35b44e40df24c64e /src/audit-error.c
parentfa668f3b96fd0363bae1adc640105b3914faa138 (diff)
downloadlatrace-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.c43
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;