From c5ae864395919663cce9c70ff6078a42ba1acaa8 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 8 Jan 2012 19:54:14 +0100 Subject: changes --- etc/latrace.d/latrace.conf.in | 2 +- src/audit-error.c | 190 ++++---------- src/audit-init.c | 16 +- src/config-bison.y | 12 +- src/config-flex.l | 4 +- src/config.c | 1 + src/config.h | 6 +- src/error.c | 588 ++++++++++++++++++++++-------------------- src/error.h | 59 +++-- 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; } N { return ERR_N; } TYPE { return ERR_TYPE; } SEQ { return ERR_SEQ; } -AUTOMATED { return ERR_AUTOMATED; } +AUTO { return ERR_AUTO; } REPLAY { return ERR_REPLAY; } SIGSEGV { return ERR_SIGSEGV; } -AUTOMATED { return ERR_AUTOMATED; } -REPLAY { return ERR_REPLAY; } KEEP { return ERR_KEEP; } {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; -- cgit