summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <Jiri Olsa jolsa@redhat.com>2012-01-08 19:54:14 +0100
committerJiri Olsa <Jiri Olsa jolsa@redhat.com>2012-01-09 21:34:42 +0100
commitc5ae864395919663cce9c70ff6078a42ba1acaa8 (patch)
treeb70af8bc45497003b79b912ea12cc914722538fc
parentd6b83af2ca0c27c873fcd6d149b9b5ac8a590848 (diff)
downloadlatrace-error_simulation4.tar.gz
latrace-error_simulation4.tar.xz
latrace-error_simulation4.zip
-rw-r--r--etc/latrace.d/latrace.conf.in2
-rw-r--r--src/audit-error.c190
-rw-r--r--src/audit-init.c16
-rw-r--r--src/config-bison.y12
-rw-r--r--src/config-flex.l4
-rw-r--r--src/config.c1
-rw-r--r--src/config.h6
-rw-r--r--src/error.c588
-rw-r--r--src/error.h59
9 files changed, 422 insertions, 456 deletions
diff --git a/etc/latrace.d/latrace.conf.in b/etc/latrace.d/latrace.conf.in
index b7d6e0a..3d9df8e 100644
--- a/etc/latrace.d/latrace.conf.in
+++ b/etc/latrace.d/latrace.conf.in
@@ -173,7 +173,7 @@ OPTIONS {
# }
#
# RETURN R2 {
-# sym1 = -1
+# sym1 = -1 SIGSEGV
# sym2 = 0
# sym1 = KEEP
# sym1 = -2
diff --git a/src/audit-error.c b/src/audit-error.c
index c93c75c..f6286cd 100644
--- a/src/audit-error.c
+++ b/src/audit-error.c
@@ -19,23 +19,14 @@ extern FILE *lt_audit_in;
static struct hsearch_data symbol_tab;
static int symbol_tab_init = 0;
-static int automated_symbols_find(struct lt_config_audit *cfg,
- const char *name);
-
-static struct lt_error_sym*
-automated_sym_get(struct lt_config_audit *cfg, const char *name);
-
struct lt_error_sym* lt_error_sym_get(struct lt_config_audit *cfg,
const char *name)
{
- struct lt_error_config *cfg_err = cfg->error_config;
struct lt_error_sym *sym;
ENTRY e, *ep;
- if (cfg_err->automated)
- return automated_sym_get(cfg, name);
-
- BUG_ON(!symbol_tab_init);
+ if (!symbol_tab_init)
+ return NULL;
PRINT_VERBOSE(cfg, 1, "request for <%s>\n", name);
@@ -142,11 +133,12 @@ int lt_error_sym_exit(struct lt_config_audit *cfg,
int handle_sigsegv;
long ret;
- if (cfg_err->automated) {
- struct lt_error_config_sym *cfg_sym;
+ /* we're not interested in this symbol */
+ if (!sym || !sym->error)
+ return -1;
- if (!automated_symbols_find(cfg, symname))
- return 0;
+ if (cfg_err->type == LT_ERROR_RUN_TYPE_AUTO) {
+ struct lt_error_sym *esym;
PRINT_VERBOSE(cfg, 1, "automated_sym_cnt %d, cfg_err->sym_cnt %d\n",
automated_sym_cnt, cfg_err->sym_cnt);
@@ -154,25 +146,21 @@ int lt_error_sym_exit(struct lt_config_audit *cfg,
if (automated_sym_cnt >= cfg_err->sym_cnt)
return -1;
- cfg_sym = &cfg_err->sym[automated_sym_cnt];
- ret = cfg_sym->ret;
- keep = cfg_sym->keep;
- handle_sigsegv = cfg_sym->handle_sigsegv;
+ esym = &cfg_err->sym[automated_sym_cnt];
+ ret = esym->ret;
+ keep = esym->keep;
+ handle_sigsegv = esym->handle_sigsegv;
*info = automated_sym_cnt++;
} else {
- /* we're not interested in this symbol */
- if (!sym || !sym->error)
- return -1;
-
esym = sym->error;
PRINT_VERBOSE(cfg, 1, "symbol %s, call %lu, n %ld\n",
- sym->name, esym->call, cfg_err->n);
+ sym->name, esym->call_configured, cfg_err->n);
/* we are not interested in this call number */
- if (esym->call++ != cfg_err->n)
+ if (esym->call_current++ != esym->call_configured)
return -1;
ret = esym->ret;
@@ -202,13 +190,12 @@ int lt_error_sym_exit(struct lt_config_audit *cfg,
static int symbol_add(struct lt_config_audit *cfg,
struct lt_error_config *cfg_err,
- struct lt_error_config_sym *cfg_sym)
+ struct lt_error_sym *sym)
{
ENTRY e, *ep;
- struct lt_error_sym *sym;
PRINT_VERBOSE(cfg, 1, "symbol %s, ret %ld\n",
- cfg_sym->symbol, cfg_sym->ret);
+ sym->name.symbol, sym->ret);
/* should be safe, since only one thread
* is doing the initialization */
@@ -221,26 +208,16 @@ static int symbol_add(struct lt_config_audit *cfg,
PRINT_VERBOSE(cfg, 1, "symbol table initialized\n");
}
- e.key = cfg_sym->symbol;
- if (!hsearch_r(e, FIND, &ep, &symbol_tab)) {
+ e.key = sym->name.symbol;
+ if (hsearch_r(e, FIND, &ep, &symbol_tab)) {
PRINT_VERBOSE(cfg, 1, "symbol %s already in the table\n",
- cfg_sym->symbol);
+ sym->name.symbol);
/* This is a bug in normal processing,
* but completelly ok in automated mode. */
- return cfg_err->automated ? 0 : -1;
- }
-
- sym = malloc(sizeof(*sym));
- if (!sym) {
- PRINT_VERBOSE(cfg, 1, "failed to allocate error symbol\n");
- return -1;
+ return cfg_err->type == LT_ERROR_RUN_TYPE_AUTO? 0 : -1;
}
- sym->name = strdup(cfg_sym->symbol);
- sym->ret = cfg_sym->ret;
- sym->handle_sigsegv = cfg_sym->handle_sigsegv;
-
- e.key = sym->name;
+ e.key = sym->name.symbol;
e.data = sym;
if (!hsearch_r(e, ENTER, &ep, &symbol_tab)) {
@@ -257,22 +234,47 @@ static int symbol_add(struct lt_config_audit *cfg,
return 0;
}
+static void display_error_symbols(struct lt_config_audit *cfg,
+ char *names, int size)
+{
+ char *p;
+
+ PRINT_VERBOSE(cfg, 1, "START size %d\n", size);
+
+ while(size) {
+ PRINT_VERBOSE(cfg, 1, "name %s\n", names);
+ p = memchr(names, 0, size);
+ size -= ++p - names;
+ names = p;
+ }
+
+ PRINT_VERBOSE(cfg, 1, "END\n");
+}
+
int lt_error_init(struct lt_config_audit *cfg)
{
struct lt_error_config *cfg_err = cfg->error_config;
int sym_cnt = cfg_err->sym_cnt, i, ok = 1;
-
- if (cfg_err->automated)
- return 0;
+ char *names;
lt_sh(cfg, error_sim) = 0;
+ names = (char*) (((void*) &cfg_err->sym) +
+ (sym_cnt * sizeof(struct lt_error_sym)));
+
+ display_error_symbols(cfg, names, cfg_err->names_size);
+
for(i = 0; i < sym_cnt; i++) {
- struct lt_error_config_sym *cfg_sym;
+ struct lt_error_sym *sym;
+
+ sym = &cfg_err->sym[i];
+
+ PRINT_VERBOSE(cfg, 1, "symbol index %d, name %s\n",
+ sym->name.index, names + sym->name.index);
- cfg_sym = &cfg_err->sym[i];
+ sym->name.symbol = names + sym->name.index;
- if (symbol_add(cfg, cfg_err, cfg_sym)) {
+ if (symbol_add(cfg, cfg_err, sym)) {
ok = 0;
break;
}
@@ -288,81 +290,6 @@ int lt_error_init(struct lt_config_audit *cfg)
return 0;
}
-static struct hsearch_data automated_symbol_tab;
-
-static int automated_symbols_find(struct lt_config_audit *cfg,
- const char *name)
-{
- ENTRY e, *ep;
- int found;
-
- e.key = (char*) name;
- found = hsearch_r(e, FIND, &ep, &automated_symbol_tab);
-
- PRINT_VERBOSE(cfg, 1, "found %d, name %s\n", found, name);
-
- return found;
-}
-
-static struct lt_error_sym*
-automated_sym_get(struct lt_config_audit *cfg,
- const char *name)
-{
- return NULL;
-}
-
-static int automated_symbols_init(struct lt_config_audit *cfg,
- struct lt_error_config *cfg_err,
- int fd)
-{
- char *symbols, *name;
- off_t off = lseek(fd, 0, SEEK_CUR);
- off_t file_size = lseek(fd, 0, SEEK_END);
- int size = (int) (file_size - off);
-
- PRINT_VERBOSE(cfg, 1, "size %d\n", size);
-
- symbols = malloc(size);
- if (!symbols) {
- perror("malloc failed");
- return -1;
- }
-
- lseek(fd, off, SEEK_SET);
- if (size != read(fd, symbols, size)) {
- perror("read failed");
- return -1;
- }
-
- if (!hcreate_r(SYMBOL_TAB_SIZE, &automated_symbol_tab)) {
- perror("failed to create hash table");
- return -1;
- }
-
- name = symbols;
-
- while(1) {
- ENTRY e, *ep;
-
- e.key = name;
- e.data = (void*) 1;
-
- PRINT_VERBOSE(cfg, 1, "name %s\n", name);
-
- if (!hsearch_r(e, ENTER, &ep, &automated_symbol_tab)) {
- perror("hsearch_r failed");
- break;
- }
-
- name += strlen(name) + 1;
- if (name >= (symbols + size))
- break;
- }
-
- PRINT_VERBOSE(cfg, 1, "done\n");
- return 0;
-}
-
int lt_error_config_read(struct lt_config_audit *cfg, int fd)
{
int size;
@@ -375,9 +302,11 @@ int lt_error_config_read(struct lt_config_audit *cfg, int fd)
return -1;
}
- size = cfg_err_st.sym_cnt * sizeof(struct lt_error_config_sym);
+ size = cfg_err_st.sym_cnt * sizeof(struct lt_error_sym);
+ size += cfg_err_st.names_size;
- PRINT_VERBOSE(cfg, 1, "symbols count %d\n", cfg_err_st.sym_cnt);
+ PRINT_VERBOSE(cfg, 1, "symbols count %d, names_size %d, total size %d\n",
+ cfg_err_st.sym_cnt, cfg_err_st.names_size, size);
cfg_err = malloc(sizeof(*cfg_err) + size);
if (!cfg_err) {
@@ -387,16 +316,11 @@ int lt_error_config_read(struct lt_config_audit *cfg, int fd)
*cfg_err = cfg_err_st;
- if (size != read(fd, cfg_err->sym, size)) {
+ if (size != read(fd, &cfg_err->sym, size)) {
PRINT_VERBOSE(cfg, 1, "failed: no error symbols defined\n");
return -1;
}
- if (cfg_err->automated &&
- automated_symbols_init(cfg, cfg_err, fd))
- return -1;
-
cfg->error_config = cfg_err;
-
- return size + sizeof(cfg_err_st);
+ return 0;
}
diff --git a/src/audit-init.c b/src/audit-init.c
index b0fdea3..73a5208 100644
--- a/src/audit-init.c
+++ b/src/audit-init.c
@@ -70,7 +70,6 @@ static int init_ctl_config(char *file)
static int read_config(char *dir)
{
int fd;
- off_t len, extra_size = 0;
char file[LT_MAXFILE];
memset(&cfg, 0, sizeof(cfg));
@@ -91,23 +90,10 @@ static int read_config(char *dir)
cfg.sh = cfg.sh_storage.sh = &cfg.sh_storage;
if (lt_sh(&cfg, error_sim)) {
- extra_size = lt_error_config_read(&cfg, fd);
- if (extra_size < 0)
+ if (lt_error_config_read(&cfg, fd))
return -1;
}
- if (-1 == (len = lseek(fd, 0, SEEK_END))) {
- perror("lseek failed");
- return -1;
- }
-
-#if 0
- if ((len - extra_size) != sizeof(cfg.sh_storage)) {
- printf("config file size differs\n");
- return -1;
- }
-#endif
-
if (LT_CONFIG_MAGIC != cfg.sh_storage.magic) {
printf("config file magic check failed\n");
return -1;
diff --git a/src/config-bison.y b/src/config-bison.y
index 45c59b1..9d22b0b 100644
--- a/src/config-bison.y
+++ b/src/config-bison.y
@@ -74,7 +74,8 @@ static struct lt_list_head ln_names;
%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_SIGSEGV ERR_AUTOMATED ERR_REPLAY ERR_KEEP
+%token ERR_SIGSEGV ERR_AUTO ERR_REPLAY ERR_KEEP
+%token ERR_TYPE
%union
{
@@ -400,15 +401,22 @@ error_run_def ERR_START ERR_N '=' VALUE
|
error_run_def ERR_TYPE ERR_SEQ
{
+ if (lt_error_run_type(scfg, &error_app_run, LT_ERROR_RUN_TYPE_SEQ))
+ ABORT("failed to add run");
}
|
-error_run_def ERR_TYPE ERR_AUTOMATED
+error_run_def ERR_TYPE ERR_AUTO
{
+ if (lt_error_run_type(scfg, &error_app_run, LT_ERROR_RUN_TYPE_AUTO))
+ ABORT("failed to add run");
}
|
error_run_def ERR_TYPE ERR_REPLAY
{
+ if (lt_error_run_type(scfg, &error_app_run, LT_ERROR_RUN_TYPE_REPLAY))
+ ABORT("failed to add run");
}
+|
error_go:
ERR_GO NAME list_names_comma
diff --git a/src/config-flex.l b/src/config-flex.l
index 5ff63bc..9204375 100644
--- a/src/config-flex.l
+++ b/src/config-flex.l
@@ -128,11 +128,9 @@ ERROR { BEGIN(error); return ERROR; }
<error>N { return ERR_N; }
<error>TYPE { return ERR_TYPE; }
<error>SEQ { return ERR_SEQ; }
-<error>AUTOMATED { return ERR_AUTOMATED; }
+<error>AUTO { return ERR_AUTO; }
<error>REPLAY { return ERR_REPLAY; }
<error>SIGSEGV { return ERR_SIGSEGV; }
-<error>AUTOMATED { return ERR_AUTOMATED; }
-<error>REPLAY { return ERR_REPLAY; }
<error>KEEP { return ERR_KEEP; }
<error>{value} { RETURN_LONG(VALUE); }
diff --git a/src/config.c b/src/config.c
index 868f260..6bffc93 100644
--- a/src/config.c
+++ b/src/config.c
@@ -144,6 +144,7 @@ static int read_config(struct lt_config_app *cfg, char *file)
ret = -1;
}
+ PRINT_VERBOSE(cfg, 1, "passed\n");
return ret;
}
diff --git a/src/config.h b/src/config.h
index fd4a032..28215f1 100644
--- a/src/config.h
+++ b/src/config.h
@@ -197,10 +197,14 @@ struct lt_config_app {
/* error definition (error_sim = 1 in shared config) */
struct lt_error_config *error_config;
+ char *error_symbols;
+ int error_symbols_size_names;
+ int error_symbols_size_total;
struct lt_list_head error_symbols_all;
struct lt_list_head error_symbols_current;
- int error_automated_finished;
+ int error_symbols_all_cnt;
+ int error_finished;
int error_automated_symbol_index;
};
diff --git a/src/error.c b/src/error.c
index 502c100..ab9f76a 100644
--- a/src/error.c
+++ b/src/error.c
@@ -185,11 +185,28 @@ static int dir_go(struct lt_config_app *cfg,
static int dir_run(struct lt_config_app *cfg,
char *dir, char *dir_base,
- struct lt_error_app_run *run, int n)
+ struct lt_error_app_run *run)
{
int size;
- size = snprintf(dir, LT_MAXFILE, "%s/RUN-%s-%05d/", dir_base, run->name, n);
+ size = snprintf(dir, LT_MAXFILE, "%s/RUN-%s/", dir_base, run->name);
+ if (size == LT_MAXFILE)
+ return -1;
+
+ if (dir_get(cfg, dir, 0))
+ return -1;
+
+ return 0;
+}
+
+static int dir_round(struct lt_config_app *cfg,
+ char *dir, char *dir_run,
+ struct lt_error_app_run *run,
+ unsigned long round)
+{
+ int size;
+
+ size = snprintf(dir, LT_MAXFILE, "%s/%lu/", dir_run, round);
if (size == LT_MAXFILE)
return -1;
@@ -277,142 +294,19 @@ static int prepare_config_args(struct lt_config_app *cfg,
return 0;
}
-static int prepare_config_error(struct lt_config_app *cfg,
- struct lt_error_app_run *run,
- int n)
+static int get_symbols_all(struct lt_config_app *cfg,
+ struct lt_error_app_run *run)
{
+ struct lt_list_head *sym_all = &cfg->error_symbols_all;
struct lt_error_app_return *ret;
- struct lt_error_config *cfg_err;
- int sym_cnt = 0;
-
- /* get the nymber of configured symbols */
- lt_list_for_each_entry(ret, &run->head_return, list_run) {
- struct lt_error_app_return_sym *sym;
- lt_list_for_each_entry(sym, &ret->head_sym, list)
- sym_cnt++;
- }
-
- PRINT_VERBOSE(cfg, 1, "number of symbols %d\n", sym_cnt);
-
- cfg_err = malloc(sizeof(*cfg_err) +
- sym_cnt * sizeof(struct lt_error_config_sym));
- if (!cfg_err)
- return -ENOMEM;
-
- cfg_err->sym_cnt = sym_cnt;
- cfg_err->n = n;
-
- sym_cnt = 0;
+ int count = 0;
lt_list_for_each_entry(ret, &run->head_return, list_run) {
- struct lt_error_app_return_sym *sym;
-
- lt_list_for_each_entry(sym, &ret->head_sym, list) {
- struct lt_error_config_sym *cfg_sym;
-
- cfg_sym = &cfg_err->sym[sym_cnt++];
- strncpy(cfg_sym->symbol, sym->name, LT_MAXNAME);
- cfg_sym->ret = sym->val;
- cfg_sym->filter.type = ret->filter.type;
- cfg_sym->handle_sigsegv = sym->handle_sigsegv;
-
- PRINT_VERBOSE(cfg, 1, "symbol %s, ret %s\n",
- sym->name, sym->val);
- }
- }
-
- cfg->error_config = cfg_err;
- return 0;
-}
-
-static int prepare_config(struct lt_config_app *cfg, char *dir,
- struct lt_error_app *app,
- struct lt_error_app_run *run, int n)
-{
- PRINT_VERBOSE(cfg, 1, "dir '%s'\n", dir);
-
- if (!app->no_storage) {
- if (prepare_config_trace(cfg, dir))
- return -1;
-
- if (prepare_config_stat(cfg, dir))
- return -1;
-
- if (prepare_config_tty(cfg, dir))
- return -1;
- }
-
- if (prepare_config_args(cfg, app, run))
- return -1;
-
- if (prepare_config_error(cfg, run, n))
- return -1;
-
- return 0;
-}
-
-static void post_config(struct lt_config_app *cfg,
- struct lt_error_app *app)
-{
- if (!app->no_storage) {
- if ((lt_sh(cfg, pipe)) && (*lt_sh(cfg, output)))
- fclose(lt_sh(cfg, fout));
-
- fclose(cfg->fstat);
- }
-}
-
-static int process_run(struct lt_config_app *cfg,
- char *dir_base,
- struct lt_error_app *app,
- struct lt_error_app_go *go,
- struct lt_error_app_run *run,
- int n)
-{
- static char dir[LT_MAXFILE];
-
- if (!app->no_storage &&
- dir_run(cfg, dir, dir_base, run, n))
- return -1;
-
- PRINT_VERBOSE(cfg, 1, "dir '%s'\n", dir);
-
- if (prepare_config(cfg, dir, app, run, n))
- return -1;
-
- if (app->no_storage)
- printf("latrace error simulation [%s] n = %d\n", app->name, n);
-
- lt_run(cfg);
-
- post_config(cfg, app);
-
- return 0;
-}
-
-static int automated_get_all_syms(struct lt_config_app *cfg,
- struct lt_error_app_go *go)
-{
- struct lt_list_head *sym_all = &cfg->error_symbols_all;
- struct lt_error_app_run *run;
- int count = 0, runs = 1;
+ struct lt_error_app_return_sym *sym, *n;
- lt_list_for_each_entry(run, &go->head_run, list_go) {
- struct lt_error_app_return *ret;
-
- if (!runs--) {
- PRINT_VERBOSE(cfg, 1,
- "failed: supporting only single RUN within AUTOMATED go\n");
- return -1;
- }
-
- lt_list_for_each_entry(ret, &run->head_return, list_run) {
- struct lt_error_app_return_sym *sym, *n;
-
- lt_list_for_each_entry_safe(sym, n, &ret->head_sym, list) {
- lt_list_move_tail(&sym->list, sym_all);
- count++;
- }
+ lt_list_for_each_entry_safe(sym, n, &ret->head_sym, list) {
+ lt_list_move_tail(&sym->list, sym_all);
+ count++;
}
}
@@ -466,52 +360,25 @@ static int automated_add_symbol_current(struct lt_config_app *cfg,
return 0;
}
-static int process_run_automated_cb(struct lt_config_app *cfg,
- struct lt_thread *t,
- struct lt_fifo_mbase *mbase)
+static int
+prepare_config_symbols_automated(struct lt_config_app *cfg,
+ struct lt_error_app_run *run,
+ unsigned long round)
{
- struct lt_error_app_return_sym *sym;
- struct lt_error_config *error_config;
- char *symname;
- long index;
-
- PRINT_VERBOSE(cfg, 1, "type %d\n", mbase->type);
-
- if (mbase->type != LT_FIFO_MTYPE_EXIT)
- return 0;
-
- index = automated_get_index(cfg, mbase);
- error_config = cfg->error_config;
-
- PRINT_VERBOSE(cfg, 1, "index %d, error_automated_symbol_index %d, sym_cnt %d\n",
- index, cfg->error_automated_symbol_index, error_config->sym_cnt);
+ struct lt_list_head *sym_current = &cfg->error_symbols_current;
- symname = automated_get_symname(cfg, mbase);
- PRINT_VERBOSE(cfg, 1, "symname %s\n", symname);
+ cfg->error_automated_symbol_index = -1;
- if (cfg->error_automated_symbol_index < (error_config->sym_cnt - 1)) {
- if (index != -1)
- cfg->error_automated_symbol_index = index;
+ if (!round) {
+ int cnt;
+ cnt = get_symbols_all(cfg, run);
+ if (cnt <= 0)
+ return -EINVAL;
+ cfg->error_symbols_all_cnt = cnt;
return 0;
}
- sym = automated_find_symbol_all(cfg, symname);
- if (!sym)
- return 0;
-
- PRINT_VERBOSE(cfg, 1, "added %s\n", symname);
-
- if (automated_add_symbol_current(cfg, sym))
- return -1;
-
- return 0;
-}
-
-static int prepare_config_symbols_automated(struct lt_config_app *cfg)
-{
- struct lt_list_head *sym_current = &cfg->error_symbols_current;
-
while (!lt_list_empty(sym_current)) {
struct lt_error_app_return_sym *last;
@@ -548,15 +415,141 @@ static int prepare_config_symbols_automated(struct lt_config_app *cfg)
/* nothing more to try, we are done */
if (lt_list_empty(sym_current)) {
PRINT_VERBOSE(cfg, 1, "FINISHED\n");
- cfg->error_automated_finished = 1;
+ cfg->error_finished = 1;
return 0;
}
return 0;
}
-static int prepare_config_error_automated(struct lt_config_app *cfg,
- struct lt_error_app_run *run)
+static int
+prepare_config_symbols_replay(struct lt_config_app *cfg)
+{
+ return 0;
+}
+
+static int
+prepare_config_symbols_seq(struct lt_config_app *cfg,
+ unsigned long round)
+{
+ return 0;
+}
+
+static int prepare_config_symbols(struct lt_config_app *cfg,
+ struct lt_error_app_run *run,
+ unsigned long round)
+{
+ switch(run->type) {
+ case LT_ERROR_RUN_TYPE_SEQ:
+ return prepare_config_symbols_seq(cfg, round);
+
+ case LT_ERROR_RUN_TYPE_AUTO:
+ return prepare_config_symbols_automated(cfg, run, round);
+
+ case LT_ERROR_RUN_TYPE_REPLAY:
+ return prepare_config_symbols_replay(cfg);
+ }
+
+ BUG();
+ return -EINVAL;
+}
+
+static int find_error_symbol(struct lt_config_app *cfg, char *name,
+ int len)
+{
+ char *names = cfg->error_symbols;
+ int size_names = cfg->error_symbols_size_names;
+ char *p;
+
+ PRINT_VERBOSE(cfg, 1, "name %s\n", name);
+
+ while(size_names) {
+ if (!strncmp(names, name, len)) {
+ int idx = names - cfg->error_symbols;
+ PRINT_VERBOSE(cfg, 1, "found idx %d\n", idx);
+ return names - cfg->error_symbols;
+ }
+
+ p = memchr(names, 0, size_names);
+ size_names -= ++p - names;
+ names = p;
+ }
+
+ PRINT_VERBOSE(cfg, 1, "not found\n");
+ return -1;
+}
+
+static void display_error_symbols(struct lt_config_app *cfg)
+{
+ char *names = cfg->error_symbols;
+ int size_names = cfg->error_symbols_size_names;
+ char *p;
+
+ PRINT_VERBOSE(cfg, 1, "START\n");
+
+ while(size_names) {
+ PRINT_VERBOSE(cfg, 1, "name %s\n", names);
+ p = memchr(names, 0, size_names);
+ size_names -= ++p - names;
+ names = p;
+ }
+
+ PRINT_VERBOSE(cfg, 1, "END\n");
+}
+
+static int add_error_symbol(struct lt_config_app *cfg, char *name)
+{
+ char *names = cfg->error_symbols;
+ int len = strlen(name);
+ int size_names = cfg->error_symbols_size_names;
+ int size_total = cfg->error_symbols_size_total;
+ int index;
+
+ PRINT_VERBOSE(cfg, 1, "name %s\n", name);
+ display_error_symbols(cfg);
+
+ if (!names) {
+ names = malloc(1000);
+ if (!names)
+ return -ENOMEM;
+
+ PRINT_VERBOSE(cfg, 1, "initial allocation\n");
+ cfg->error_symbols = names;
+ size_names = cfg->error_symbols_size_names = 0;
+ size_total = cfg->error_symbols_size_total = 1000;
+ }
+
+ index = find_error_symbol(cfg, name, len);
+ if (index >= 0)
+ return index;
+
+ /* +1 for ZERO byte */
+ if (len + size_names + 1 >= size_total) {
+ size_total += 1000;
+ names = realloc(names, size_total);
+ if (!names)
+ return -ENOMEM;
+
+ PRINT_VERBOSE(cfg, 1, "reallocation size %d\n", size_total);
+ cfg->error_symbols = names;
+ cfg->error_symbols_size_total = size_total;
+ }
+
+ index = size_names;
+
+ strncpy(names + size_names, name, len);
+ size_names += len;
+ names[size_names++] = 0;
+
+ cfg->error_symbols_size_names = size_names;
+
+ PRINT_VERBOSE(cfg, 1, "added %s, index %d\n", name, index);
+ display_error_symbols(cfg);
+ return index;
+}
+
+static int prepare_config_error(struct lt_config_app *cfg,
+ struct lt_error_app_run *run)
{
struct lt_list_head *sym_current = &cfg->error_symbols_current;
struct lt_error_app_return_sym *sym;
@@ -569,56 +562,64 @@ static int prepare_config_error_automated(struct lt_config_app *cfg,
PRINT_VERBOSE(cfg, 1, "number of symbols %d\n", sym_cnt);
cfg_err = malloc(sizeof(*cfg_err) +
- sym_cnt * sizeof(struct lt_error_config_sym));
+ sym_cnt * sizeof(struct lt_error_sym));
if (!cfg_err)
return -ENOMEM;
+ memset(cfg_err, 0, sizeof(*cfg_err));
cfg_err->sym_cnt = sym_cnt;
- cfg_err->automated = 1;
+ cfg_err->type = run->type;
sym_cnt = 0;
lt_list_for_each_entry(sym, sym_current, list) {
- struct lt_error_config_sym *cfg_sym;
+ struct lt_error_sym *cfg_sym;
+ int index;
cfg_sym = &cfg_err->sym[sym_cnt++];
- strncpy(cfg_sym->symbol, sym->name, LT_MAXNAME);
+
+ index = add_error_symbol(cfg, sym->name);
+ if (index < 0)
+ return -ENOMEM;
+
+ cfg_sym->name.index = index;
cfg_sym->ret = sym->vals[sym->val_idx];
cfg_sym->keep = sym->keep;
cfg_sym->handle_sigsegv = sym->handle_sigsegv;
PRINT_VERBOSE(cfg, 1, "symbol %s, keep %d, ret %llu\n",
- cfg_sym->symbol, cfg_sym->keep, cfg_sym->ret);
+ sym->name, cfg_sym->keep, cfg_sym->ret);
}
+ cfg_err->names_size = cfg->error_symbols_size_names;
cfg->error_config = cfg_err;
- cfg->error_automated_symbol_index = -1;
return 0;
}
-static int prepare_config_automated(struct lt_config_app *cfg,
- char *dir,
- struct lt_error_app *app,
- struct lt_error_app_run *run,
- int n)
+static int prepare_config(struct lt_config_app *cfg,
+ char *dir,
+ struct lt_error_app *app,
+ struct lt_error_app_run *run,
+ unsigned long round)
{
- if (prepare_config_trace(cfg, dir))
- return -1;
+ if (!app->no_storage) {
+ if (prepare_config_trace(cfg, dir))
+ return -1;
- if (prepare_config_stat(cfg, dir))
- return -1;
+ if (prepare_config_stat(cfg, dir))
+ return -1;
- if (prepare_config_tty(cfg, dir))
- return -1;
+ if (prepare_config_tty(cfg, dir))
+ return -1;
+ }
if (prepare_config_args(cfg, app, run))
return -1;
- /* omit the first run */
- if (n && prepare_config_symbols_automated(cfg))
+ if (prepare_config_symbols(cfg, run, round))
return -1;
- if (prepare_config_error_automated(cfg, run))
+ if (prepare_config_error(cfg, run))
return -1;
return 0;
@@ -635,88 +636,126 @@ static void post_config_automated(struct lt_config_app *cfg,
struct lt_error_app *app,
char *dir)
{
- post_config(cfg, app);
automated_dump_config(cfg, app, dir);
- free(cfg->error_config);
}
-static int process_run_automated(struct lt_config_app *cfg,
- char *dir_base,
- struct lt_error_app *app,
- struct lt_error_app_run *run)
+static void post_config(struct lt_config_app *cfg,
+ struct lt_error_app *app,
+ struct lt_error_app_run *run,
+ char *dir)
{
- static char dir[LT_MAXFILE];
- int n = 0;
+ switch(run->type) {
+ case LT_ERROR_RUN_TYPE_AUTO:
+ return post_config_automated(cfg, app, dir);
+ }
- if (lt_process_register(cfg, process_run_automated_cb))
- return -1;
+ if (!app->no_storage) {
+ if ((lt_sh(cfg, pipe)) && (*lt_sh(cfg, output)))
+ fclose(lt_sh(cfg, fout));
- while(1) {
- printf("round %d\n", n);
+ fclose(cfg->fstat);
+ }
- if (dir_run(cfg, dir, dir_base, run, n))
- break;
+ free(cfg->error_config);
+ free(cfg->error_symbols);
- if (prepare_config_automated(cfg, dir, app, run, n))
- break;
+ cfg->error_config = NULL;
+ cfg->error_symbols = NULL;
+ cfg->error_symbols_size_names = 0;
+ cfg->error_symbols_size_total = 0;
+}
- if (cfg->error_automated_finished)
- break;
+static int process_run_automated_cb(struct lt_config_app *cfg,
+ struct lt_thread *t,
+ struct lt_fifo_mbase *mbase)
+{
+ struct lt_error_app_return_sym *sym;
+ struct lt_error_config *error_config;
+ char *symname;
+ long index;
- lt_run(cfg);
+ PRINT_VERBOSE(cfg, 1, "type %d\n", mbase->type);
- post_config_automated(cfg, app, dir);
+ if (mbase->type != LT_FIFO_MTYPE_EXIT)
+ return 0;
- n++;
- }
+ index = automated_get_index(cfg, mbase);
+ error_config = cfg->error_config;
- BUG_ON(lt_process_unregister(cfg, process_run_automated_cb));
+ PRINT_VERBOSE(cfg, 1, "index %d, error_automated_symbol_index %d, sym_cnt %d\n",
+ index, cfg->error_automated_symbol_index, error_config->sym_cnt);
- return cfg->error_automated_finished ? 0 : -1;
-}
+ symname = automated_get_symname(cfg, mbase);
+ PRINT_VERBOSE(cfg, 1, "symname %s\n", symname);
-static int process_go_automated(struct lt_config_app *cfg, char *dir,
- struct lt_error_app *app,
- struct lt_error_app_go *go)
-{
- struct lt_error_app_run *run;
+ if (cfg->error_automated_symbol_index < (error_config->sym_cnt - 1)) {
+ if (index != -1)
+ cfg->error_automated_symbol_index = index;
- if (automated_get_all_syms(cfg, go) <= 0)
- return -1;
+ return 0;
+ }
- run = lt_list_first_entry(&go->head_run, struct lt_error_app_run, list_go);
+ sym = automated_find_symbol_all(cfg, symname);
+ if (!sym)
+ return 0;
- if (process_run_automated(cfg, dir, app, run))
- PRINT_VERBOSE(cfg, 1, "failed: AUTOMATED run %s\n", run->name);
+ PRINT_VERBOSE(cfg, 1, "added %s\n", symname);
+
+ if (automated_add_symbol_current(cfg, sym))
+ return -1;
return 0;
}
-static int process_go_replay(struct lt_config_app *cfg, char *dir,
- struct lt_error_app *app,
- struct lt_error_app_go *go)
+static int process_run_cb(struct lt_config_app *cfg,
+ struct lt_thread *t,
+ struct lt_fifo_mbase *mbase)
{
- return 0;
+ /* TODO need a way to distiguish error type inside tracer */
+ return process_run_automated_cb(cfg, t, mbase);
}
-static int process_go_configured(struct lt_config_app *cfg, char *dir,
- struct lt_error_app *app,
- struct lt_error_app_go *go)
+static int process_run(struct lt_config_app *cfg,
+ char *dir_base,
+ struct lt_error_app *app,
+ struct lt_error_app_run *run)
{
- int i;
+ static char dir[LT_MAXFILE];
+ static char round[LT_MAXFILE];
+ unsigned long r = 0;
- PRINT_VERBOSE(cfg, 1, "dir '%s', name %s, start %d, n %d\n",
- dir, go->name, go->start, go->n);
+ if (!app->no_storage &&
+ dir_run(cfg, dir, dir_base, run))
+ return -1;
- for(i = go->start; i < (go->start + go->n); i++) {
- struct lt_error_app_run *run;
+ PRINT_VERBOSE(cfg, 1, "dir '%s'\n", dir);
- lt_list_for_each_entry(run, &go->head_run, list_go)
- if (process_run(cfg, dir, app, go, run, i))
- return -1;
- }
+ if (lt_process_register(cfg, process_run_cb))
+ return -1;
- return 0;
+ while(1) {
+ if (!app->no_storage &&
+ dir_round(cfg, round, dir, run, r))
+ return -1;
+
+ printf("round %lu\n", r);
+
+ if (prepare_config(cfg, round, app, run, r))
+ break;
+
+ if (cfg->error_finished)
+ break;
+
+ lt_run(cfg);
+
+ post_config(cfg, app, run, round);
+
+ r++;
+ };
+
+ BUG_ON(lt_process_unregister(cfg, process_run_cb));
+
+ return cfg->error_finished ? 0 : -1;
}
static int process_go(struct lt_config_app *cfg, char *dir_base,
@@ -724,21 +763,17 @@ static int process_go(struct lt_config_app *cfg, char *dir_base,
struct lt_error_app_go *go)
{
static char dir[LT_MAXFILE];
+ struct lt_error_app_run *run;
if (!app->no_storage &&
dir_go(cfg, dir, dir_base, go))
return -1;
- /* automated processing.. God save us */
- if (go->automated)
- return process_go_automated(cfg, dir, app, go);
-
- /* exact symbols return replay */
- if (go->replay)
- return process_go_replay(cfg, dir, app, go);
+ lt_list_for_each_entry(run, &go->head_run, list_go)
+ if (process_run(cfg, dir, app, run))
+ return -1;
- /* Whatever user configuration wants.. */
- return process_go_configured(cfg, dir, app, go);
+ return 0;
}
int lt_error_run(struct lt_config_app *cfg)
@@ -849,6 +884,19 @@ int lt_error_run_return(struct lt_config_app *cfg,
return 0;
}
+int lt_error_run_type(struct lt_config_app *cfg,
+ struct lt_error_app_run **run,
+ int type)
+{
+ struct lt_error_app_run *app_run = app_run_get(cfg, run);
+
+ if (!app_run)
+ return -ENOMEM;
+
+ app_run->type = type;
+ return 0;
+};
+
int lt_error_run_args(struct lt_config_app *cfg,
struct lt_error_app_run **run,
struct lt_list_head *head)
@@ -1048,14 +1096,12 @@ int lt_error_app_init(struct lt_error_app *app)
int lt_error_config_write(struct lt_config_app *cfg, int fd)
{
- struct lt_list_head *sym_all = &cfg->error_symbols_all;
- struct lt_error_app_return_sym *sym;
struct lt_error_config *cfg_err = cfg->error_config;
- int size = sizeof(struct lt_error_config);
+ int len, size = sizeof(struct lt_error_config);
BUG_ON(!cfg_err);
- size += cfg_err->sym_cnt * sizeof(struct lt_error_config_sym);
+ size += cfg_err->sym_cnt * sizeof(struct lt_error_sym);
PRINT_VERBOSE(cfg, 1, "sym_cnt %d\n", cfg_err->sym_cnt);
@@ -1064,25 +1110,17 @@ int lt_error_config_write(struct lt_config_app *cfg, int fd)
return -1;
}
- if (!cfg_err->automated)
- return 0;
+ PRINT_VERBOSE(cfg, 1, "writing names size %d\n", cfg->error_symbols_size_names);
+ display_error_symbols(cfg);
- PRINT_VERBOSE(cfg, 1, "writing automated list info\n");
+ len = cfg->error_symbols_size_names;
+ size = write(fd, cfg->error_symbols, len);
- lt_list_for_each_entry(sym, sym_all, list) {
- char symbol[LT_MAXNAME];
- int len;
-
- len = snprintf(symbol, LT_MAXNAME, "%s", sym->name);
- if (len != write(fd, symbol, len)) {
- perror("write failed");
- return -1;
- }
- len = 0;
- write(fd, &len, 1);
+ if (size != len) {
+ perror("write failed");
+ return -1;
}
PRINT_VERBOSE(cfg, 1, "OK\n");
-
return 0;
}
diff --git a/src/error.h b/src/error.h
index 5090749..97a16dd 100644
--- a/src/error.h
+++ b/src/error.h
@@ -12,41 +12,38 @@ struct lt_error_config_filter {
int type;
};
-struct lt_error_config_sym {
-/* FIXME put to the end of the structure as symbol[0] */
-#define LT_MAXNAME 20
- char symbol[LT_MAXNAME];
+struct lt_error_sym {
+ /*
+ * It is 'symbol' for normal usage and 'index' for
+ * file storage in names section (see struct
+ * lt_error_config definition
+ */
+ union {
+ char *symbol;
+ int index;
+ } name;
#define LT_MAXRET 20
long ret;
- struct lt_error_config_filter filter;
+ long call_current;
+ long call_configured;
int handle_sigsegv;
int keep;
};
+/*
+ * stored in file like:
+ *
+ * struct lt_error_config
+ * struct lt_error_config_sym array
+ * names..
+ */
struct lt_error_config {
unsigned long n;
- int automated;
- int sym_cnt;
- off_t names_size;
- struct lt_error_config_sym sym[0];
-};
-
-struct lt_error_audit_filter {
int type;
- union {
- int **nth;
- };
-};
-
-struct lt_error_sym {
- char *name;
- unsigned long ret;
- unsigned long call;
- int handle_sigsegv;
- struct lt_error_audit_filter filter;
-
- struct lt_list_head list;
+ int sym_cnt;
+ int names_size;
+ struct lt_error_sym sym[0];
};
struct lt_error_app_return_sym {
@@ -89,7 +86,7 @@ struct lt_error_start {
enum {
LT_ERROR_RUN_TYPE_SEQ,
- LT_ERROR_RUN_TYPE_AUTOMATED,
+ LT_ERROR_RUN_TYPE_AUTO,
LT_ERROR_RUN_TYPE_REPLAY,
};
@@ -138,6 +135,9 @@ int lt_error_run_return(struct lt_config_app *cfg,
int lt_error_run_args(struct lt_config_app *cfg,
struct lt_error_app_run **run,
struct lt_list_head *args);
+int lt_error_run_type(struct lt_config_app *cfg,
+ struct lt_error_app_run **run,
+ int type);
int lt_error_return_ass(struct lt_config_app *cfg,
struct lt_error_app_return **ret,
char *name, struct lt_list_head *list_vals,
@@ -178,6 +178,13 @@ static inline int lt_error_run_args(struct lt_config_app *cfg,
return -1;
}
+static inline int lt_error_run_type(struct lt_config_app *cfg,
+ struct lt_error_app_run **run,
+ int type);
+{
+ return -1;
+}
+
static inline int lt_error_app_init(struct lt_error_app *app)
{
return -1;