diff options
Diffstat (limited to 'src/error.c')
-rw-r--r-- | src/error.c | 588 |
1 files changed, 313 insertions, 275 deletions
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; } |