summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <Jiri Olsa jolsa@redhat.com>2012-01-11 23:45:18 +0100
committerJiri Olsa <Jiri Olsa jolsa@redhat.com>2012-01-11 23:45:18 +0100
commit50694d55abfdd0807e1617f84c905df330ed97a7 (patch)
treea736dab4985fcc98437a8249df251ff25a41a14d
parentdaafe68255b0fbae2d7c1d4c696538327037b067 (diff)
downloadlatrace-50694d55abfdd0807e1617f84c905df330ed97a7.tar.gz
latrace-50694d55abfdd0807e1617f84c905df330ed97a7.tar.xz
latrace-50694d55abfdd0807e1617f84c905df330ed97a7.zip
-rw-r--r--Makefile4
-rw-r--r--etc/latrace.d/latrace.conf.in2
-rw-r--r--src/audit-error.c59
-rw-r--r--src/config-bison.y32
-rw-r--r--src/config-flex.l5
-rw-r--r--src/config.c3
-rw-r--r--src/config.h7
-rw-r--r--src/error.c50
-rw-r--r--src/error.h32
9 files changed, 180 insertions, 14 deletions
diff --git a/Makefile b/Makefile
index 0f5a56c..10e3374 100644
--- a/Makefile
+++ b/Makefile
@@ -157,10 +157,10 @@ ALL_CFLAGS+=-D_GNU_SOURCE -imacros src/autoconf.h
.SECONDARY:
%.c: %.l LATRACE-CFLAGS
- $(QUIET_LEX)$(LEX) -t $< > $(basename $<).c
+ $(QUIET_LEX)$(LEX) -d -t $< > $(basename $<).c
%.c: %.y LATRACE-CFLAGS
- $(QUIET_YACC)$(YACC) -v $< -d -o $(basename $<).c
+ $(QUIET_YACC)$(YACC) -t -v $< -d -o $(basename $<).c
all:: $(PROGRAMS) LATRACE-CFLAGS
diff --git a/etc/latrace.d/latrace.conf.in b/etc/latrace.d/latrace.conf.in
index 3d9df8e..4444c52 100644
--- a/etc/latrace.d/latrace.conf.in
+++ b/etc/latrace.d/latrace.conf.in
@@ -206,7 +206,7 @@ OPTIONS {
# RUN run3 {
# TYPE REPLAY
#
-# START sym=sym4,lib=libc,n=4
+# START AFTER 10 EXITS OF sym1
#
# RETURN R1
# ARGS a a a
diff --git a/src/audit-error.c b/src/audit-error.c
index f6286cd..7636f35 100644
--- a/src/audit-error.c
+++ b/src/audit-error.c
@@ -118,6 +118,34 @@ static int install_sigsegv(struct lt_config_shared *cfg)
static __thread unsigned long automated_sym_cnt = 0;
+
+/* TODO make type agnostics... now only AFTER type */
+static void update_start_info(struct lt_config_audit *cfg,
+ const char *symname, int is_entry)
+{
+ if (cfg->error_allowed)
+ return;
+
+ if (is_entry && cfg->error_start_after_entries) {
+ if (strcmp(symname, cfg->error_start_after_sym))
+ return;
+
+ cfg->error_start_after_current++;
+
+ if (cfg->error_start_after_current != cfg->error_start_after_entries)
+ return;
+
+ cfg->error_allowed = 1;
+ }
+}
+
+int lt_error_sym_entry(struct lt_config_audit *cfg,
+ const char *symname)
+{
+ update_start_info(cfg, symname, 1);
+ return 0;
+}
+
int lt_error_sym_exit(struct lt_config_audit *cfg,
const char *symname,
struct lt_symbol *sym,
@@ -137,6 +165,11 @@ int lt_error_sym_exit(struct lt_config_audit *cfg,
if (!sym || !sym->error)
return -1;
+ update_start_info(cfg, symname, 0);
+
+ if (!cfg->error_allowed)
+ return -1;
+
if (cfg_err->type == LT_ERROR_RUN_TYPE_AUTO) {
struct lt_error_sym *esym;
@@ -251,6 +284,29 @@ static void display_error_symbols(struct lt_config_audit *cfg,
PRINT_VERBOSE(cfg, 1, "END\n");
}
+
+static int init_start_info(struct lt_config_audit *cfg,
+ struct lt_error_config *cfg_err,
+ char *names)
+{
+ struct lt_error_start *start = &cfg_err->start;
+
+ if (start->type == LT_ERROR_START_TYPE_AFTER) {
+ if (start->after.name.index != -1)
+ cfg->error_start_after_sym = names + start->after.name.index;
+
+ cfg->error_start_after_entries = start->after.entries;
+ cfg->error_start_after_exits = start->after.exits;
+
+ PRINT_VERBOSE(cfg, 1, "START AFTER entries %ld, exits %ld, sym %s\n",
+ cfg->error_start_after_entries,
+ cfg->error_start_after_exits,
+ cfg->error_start_after_sym);
+ }
+
+ return 0;
+}
+
int lt_error_init(struct lt_config_audit *cfg)
{
struct lt_error_config *cfg_err = cfg->error_config;
@@ -286,6 +342,9 @@ int lt_error_init(struct lt_config_audit *cfg)
return -1;
}
+ if (init_start_info(cfg, cfg_err, names))
+ return -1;
+
lt_sh(cfg, error_sim) = 1;
return 0;
}
diff --git a/src/config-bison.y b/src/config-bison.y
index 9d22b0b..cdd94be 100644
--- a/src/config-bison.y
+++ b/src/config-bison.y
@@ -73,9 +73,10 @@ static struct lt_list_head ln_names;
%token OPT_ARGS_STRING_POINTER_LENGTH
%token ERROR
%token ERR_DO ERR_DIR ERR_RUN ERR_GO ERR_RETURN ERR_N
-%token ERR_PROG ERR_ARGS ERR_FILTER ERR_SEQ ERR_START
+%token ERR_PROG ERR_ARGS ERR_FILTER ERR_SEQ
%token ERR_SIGSEGV ERR_AUTO ERR_REPLAY ERR_KEEP
%token ERR_TYPE
+%token ERR_START ERR_AFTER ERR_ENTRIES ERR_EXITS ERR_OF
%union
{
@@ -86,6 +87,7 @@ static struct lt_list_head ln_names;
%type <s> NAME
%type <s> BOOL
%type <l> VALUE
+%type <s> start_after_sym
%%
entry:
@@ -394,11 +396,6 @@ error_run_def ERR_RETURN list_names_comma
ABORT("failed to add run");
}
|
-error_run_def ERR_START ERR_N '=' VALUE
-{
- error_app_run->start.n = $5;
-}
-|
error_run_def ERR_TYPE ERR_SEQ
{
if (lt_error_run_type(scfg, &error_app_run, LT_ERROR_RUN_TYPE_SEQ))
@@ -417,6 +414,29 @@ error_run_def ERR_TYPE ERR_REPLAY
ABORT("failed to add run");
}
|
+error_run_def ERR_START ERR_AFTER VALUE ERR_ENTRIES start_after_sym
+{
+ if (lt_error_run_start_after(scfg, &error_app_run,
+ 1, $4, $6))
+ ABORT("failed to add run");
+}
+|
+error_run_def ERR_START ERR_AFTER VALUE ERR_EXITS start_after_sym
+{
+ if (lt_error_run_start_after(scfg, &error_app_run,
+ 0, $4, $6))
+ ABORT("failed to add run");
+}
+|
+
+start_after_sym: ERR_OF NAME
+{
+ $$ = $2;
+}
+|
+{
+ $$ = NULL;
+}
error_go:
ERR_GO NAME list_names_comma
diff --git a/src/config-flex.l b/src/config-flex.l
index 9204375..3578561 100644
--- a/src/config-flex.l
+++ b/src/config-flex.l
@@ -132,6 +132,11 @@ ERROR { BEGIN(error); return ERROR; }
<error>REPLAY { return ERR_REPLAY; }
<error>SIGSEGV { return ERR_SIGSEGV; }
<error>KEEP { return ERR_KEEP; }
+<error>START { return ERR_START; }
+<error>AFTER { return ERR_AFTER; }
+<error>ENTRIES { return ERR_ENTRIES; }
+<error>EXITS { return ERR_EXITS; }
+<error>OF { return ERR_OF; }
<error>{value} { RETURN_LONG(VALUE); }
<error>{name} { RETURN_STR(NAME); }
diff --git a/src/config.c b/src/config.c
index 6bffc93..9609c4d 100644
--- a/src/config.c
+++ b/src/config.c
@@ -128,6 +128,8 @@ static int get_type(struct lt_config_app *cfg, struct lt_config_tv *tv,
return -1;
}
+extern int lt_config_debug;
+
/* read conf file */
static int read_config(struct lt_config_app *cfg, char *file)
{
@@ -139,6 +141,7 @@ static int read_config(struct lt_config_app *cfg, char *file)
if (lt_inc_open(cfg->sh, &inc, file))
return -1;
+ lt_config_debug = 1;
if (lt_config_parse()) {
printf("failed to parse config file %s\n", file);
ret = -1;
diff --git a/src/config.h b/src/config.h
index 28215f1..5c017c3 100644
--- a/src/config.h
+++ b/src/config.h
@@ -267,6 +267,13 @@ struct lt_config_audit {
/* error definition (error_sim = 1 in shared config) */
struct lt_error_config *error_config;
+ long error_allowed;
+
+ /* start condition for entries and exits */
+ long error_start_after_entries;
+ long error_start_after_exits;
+ long error_start_after_current;
+ char *error_start_after_sym;
};
enum {
diff --git a/src/error.c b/src/error.c
index 48afa23..7f0d985 100644
--- a/src/error.c
+++ b/src/error.c
@@ -548,6 +548,27 @@ static int add_error_symbol(struct lt_config_app *cfg, char *name)
return index;
}
+static int copy_start_info(struct lt_config_app *cfg,
+ struct lt_error_config *cfg_err,
+ struct lt_error_app_run *run)
+{
+ struct lt_error_start *start = &run->start;
+
+ cfg_err->start = *start;
+
+ if (start->type == LT_ERROR_START_TYPE_AFTER) {
+ if (start->after.name.sym) {
+ int index = add_error_symbol(cfg, start->after.name.sym);
+ if (index < 0)
+ return -ENOMEM;
+ cfg_err->start.after.name.index = index;
+ } else
+ cfg_err->start.after.name.index = -1;
+ }
+
+ return 0;
+}
+
static int prepare_config_error(struct lt_config_app *cfg,
struct lt_error_app_run *run)
{
@@ -591,6 +612,10 @@ static int prepare_config_error(struct lt_config_app *cfg,
sym->name, cfg_sym->keep, cfg_sym->ret);
}
+ /* copy the start information */
+ if (copy_start_info(cfg, cfg_err, run))
+ return -ENOMEM;
+
cfg_err->names_size = cfg->error_symbols_size_names;
cfg->error_config = cfg_err;
return 0;
@@ -928,6 +953,31 @@ int lt_error_run_args(struct lt_config_app *cfg,
return 0;
}
+int lt_error_run_start_after(struct lt_config_app *cfg,
+ struct lt_error_app_run **run,
+ int is_entries, long cnt, char *sym)
+{
+ struct lt_error_app_run *app_run = app_run_get(cfg, run);
+ struct lt_error_start *start;
+
+ if (!app_run)
+ return -ENOMEM;
+
+ PRINT_VERBOSE(cfg, 1, "is_entries %d, cnt %ld, sym %s\n",
+ is_entries, cnt, sym);
+
+ start->type = LT_ERROR_START_TYPE_AFTER;
+
+ start = &app_run->start;
+ if (is_entries)
+ start->after.entries = cnt;
+ else
+ start->after.exits = cnt;
+
+ start->after.name.sym = sym;
+ return 0;
+}
+
static struct lt_error_app_run *find_run(struct lt_config_app *cfg,
struct lt_error_app *error_app,
char *name)
diff --git a/src/error.h b/src/error.h
index 97a16dd..b01cedb 100644
--- a/src/error.h
+++ b/src/error.h
@@ -8,8 +8,22 @@ enum {
LT_ERROR_FILTER_TYPE_INTERACTIVE,
};
-struct lt_error_config_filter {
+enum {
+ LT_ERROR_START_TYPE_AFTER,
+};
+
+struct lt_error_start {
int type;
+ union {
+ struct {
+ long entries;
+ long exits;
+ union {
+ int index;
+ char *sym;
+ } name;
+ } after;
+ };
};
struct lt_error_sym {
@@ -43,6 +57,7 @@ struct lt_error_config {
int type;
int sym_cnt;
int names_size;
+ struct lt_error_start start;
struct lt_error_sym sym[0];
};
@@ -80,10 +95,6 @@ struct lt_error_app_return {
struct lt_list_head list_run;
};
-struct lt_error_start {
- long n;
-};
-
enum {
LT_ERROR_RUN_TYPE_SEQ,
LT_ERROR_RUN_TYPE_AUTO,
@@ -138,6 +149,9 @@ int lt_error_run_args(struct lt_config_app *cfg,
int lt_error_run_type(struct lt_config_app *cfg,
struct lt_error_app_run **run,
int type);
+int lt_error_run_start_after(struct lt_config_app *cfg,
+ struct lt_error_app_run **run,
+ int is_entries, long cnt, char *sym);
int lt_error_return_ass(struct lt_config_app *cfg,
struct lt_error_app_return **ret,
char *name, struct lt_list_head *list_vals,
@@ -185,6 +199,14 @@ static inline int lt_error_run_type(struct lt_config_app *cfg,
return -1;
}
+
+static int lt_error_run_start_after(struct lt_config_app *cfg,
+ struct lt_error_app_run **run,
+ int is_entries, long cnt, char *sym)
+{
+ return -1;
+}
+
static inline int lt_error_app_init(struct lt_error_app *app)
{
return -1;