diff options
author | jolsa@redhat.com <jolsa@redhat.com> | 2011-11-11 19:42:52 -0500 |
---|---|---|
committer | Jiri Olsa <Jiri Olsa jolsa@redhat.com> | 2011-11-13 11:06:42 +0100 |
commit | 291cd946a26bfd3a6edf1a232e1a2bf7888ddf42 (patch) | |
tree | 5e1243a9ca2bf8328e6b5627ca7821df5599f402 | |
parent | 78a2fe366cf23632dd561e34d849e7fceaefd017 (diff) | |
download | latrace-error_simulation.tar.gz latrace-error_simulation.tar.xz latrace-error_simulation.zip |
changeserror_simulation
-rw-r--r-- | src/audit-error.c | 116 | ||||
-rw-r--r-- | src/audit-init.c | 2 | ||||
-rw-r--r-- | src/audit.c | 2 | ||||
-rw-r--r-- | src/config.h | 1 | ||||
-rw-r--r-- | src/error.c | 32 | ||||
-rw-r--r-- | src/error.h | 2 | ||||
-rw-r--r-- | src/run.c | 2 |
7 files changed, 138 insertions, 19 deletions
diff --git a/src/audit-error.c b/src/audit-error.c index 2ece447..b1b0cd9 100644 --- a/src/audit-error.c +++ b/src/audit-error.c @@ -19,6 +19,9 @@ 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); + struct lt_error_sym* lt_error_sym_get(struct lt_config_shared *cfg, const char *name) { @@ -118,6 +121,7 @@ static int install_sigsegv(struct lt_config_shared *cfg) static __thread unsigned long automated_sym_cnt = 0; int lt_error_sym_exit(struct lt_config_audit *cfg, + const char *symname, struct lt_symbol *sym, struct timeval *tv, struct link_map *lr, @@ -128,34 +132,41 @@ int lt_error_sym_exit(struct lt_config_audit *cfg, struct lt_error_sym *esym; struct lt_error_config *cfg_err = cfg->error_config; int keep = 0; + int handle_sigsegv; long ret; - /* 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); - if (cfg_err->automated) { struct lt_error_config_sym *cfg_sym; + if (!automated_symbols_find(cfg, symname)) + return 0; + 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; *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); + /* we are not interested in this call number */ if (esym->call++ != cfg_err->n) return -1; ret = esym->ret; + handle_sigsegv = esym->handle_sigsegv; } if (keep) @@ -173,7 +184,7 @@ int lt_error_sym_exit(struct lt_config_audit *cfg, /* and share some info about the sinner */ share_info(cfg, ret, keep, tv, lr, inregs); - if (esym->handle_sigsegv && install_sigsegv(cfg->sh)) + if (handle_sigsegv && install_sigsegv(cfg->sh)) PRINT_VERBOSE(cfg, 1, "failed to install SIGSEGV handler\n"); return 0; @@ -241,6 +252,9 @@ 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; + lt_sh(cfg, error_sim) = 0; for(i = 0; i < sym_cnt; i++) { @@ -264,21 +278,89 @@ 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 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 = symbols; + 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; struct lt_error_config *cfg_err, cfg_err_st; + ssize_t n; - if (-1 == read(fd, &cfg_err_st, sizeof(cfg_err_st))) { + n = read(fd, &cfg_err_st, sizeof(cfg_err_st)); + if (n != sizeof(cfg_err_st)) { perror("read failed"); return -1; } size = cfg_err_st.sym_cnt * sizeof(struct lt_error_config_sym); - if (size <= 0) { - PRINT_VERBOSE(cfg, 1, "failed: no error symbols defined\n"); - return -1; - } + + PRINT_VERBOSE(cfg, 1, "symbols count %d\n", cfg_err_st.sym_cnt); cfg_err = malloc(sizeof(*cfg_err) + size); if (!cfg_err) { @@ -293,6 +375,10 @@ int lt_error_config_read(struct lt_config_audit *cfg, int fd) 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); diff --git a/src/audit-init.c b/src/audit-init.c index 0324508..b0fdea3 100644 --- a/src/audit-init.c +++ b/src/audit-init.c @@ -101,10 +101,12 @@ static int read_config(char *dir) 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"); diff --git a/src/audit.c b/src/audit.c index 4488d24..337dd74 100644 --- a/src/audit.c +++ b/src/audit.c @@ -156,7 +156,7 @@ static int sym_exit(const char *symname, void *ptr, #ifdef CONFIG_ARCH_HAVE_ERROR_SIM if (lt_sh(&cfg, error_sim)) - lt_error_sym_exit(&cfg, sym, &tv, lr, inregs, outregs, &info); + lt_error_sym_exit(&cfg, symname, sym, &tv, lr, inregs, outregs, &info); #endif #ifdef CONFIG_ARCH_HAVE_ARGS diff --git a/src/config.h b/src/config.h index ab71324..859f444 100644 --- a/src/config.h +++ b/src/config.h @@ -455,6 +455,7 @@ int lt_error_init(struct lt_config_audit *cfg); struct lt_error_sym* lt_error_sym_get(struct lt_config_shared *cfg, const char *name); int lt_error_sym_exit(struct lt_config_audit *cfg, + const char *symname, struct lt_symbol *sym, struct timeval *tv, struct link_map *lr, diff --git a/src/error.c b/src/error.c index ec457be..4a99889 100644 --- a/src/error.c +++ b/src/error.c @@ -407,9 +407,9 @@ static int automated_get_all_syms(struct lt_config_app *cfg, } lt_list_for_each_entry(ret, &run->head_return, list_run) { - struct lt_error_app_return_sym *sym; + struct lt_error_app_return_sym *sym, *n; - lt_list_for_each_entry(sym, &ret->head_sym, list) { + lt_list_for_each_entry_safe(sym, n, &ret->head_sym, list) { lt_list_move_tail(&sym->list, sym_all); count++; } @@ -644,6 +644,8 @@ static int process_run_automated(struct lt_config_app *cfg, return -1; while(1) { + PRINT_VERBOSE(cfg, 1, "round %d\n", n); + if (dir_run(cfg, dir, dir_base, run, n)) break; @@ -671,7 +673,7 @@ static int process_go_automated(struct lt_config_app *cfg, char *dir, { struct lt_error_app_run *run; - if (!automated_get_all_syms(cfg, go) <= 0) + if (automated_get_all_syms(cfg, go) <= 0) return -1; run = lt_list_first_entry(&go->head_run, struct lt_error_app_run, list_go); @@ -1044,6 +1046,8 @@ 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); @@ -1051,10 +1055,32 @@ int lt_error_config_write(struct lt_config_app *cfg, int fd) size += cfg_err->sym_cnt * sizeof(struct lt_error_config_sym); + PRINT_VERBOSE(cfg, 1, "sym_cnt %d\n", cfg_err->sym_cnt); + if (size != write(fd, cfg_err, size)) { perror("write failed"); return -1; } + if (!cfg_err->automated) + return 0; + + PRINT_VERBOSE(cfg, 1, "writing automated list info\n"); + + 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); + } + + PRINT_VERBOSE(cfg, 1, "OK\n"); + return 0; } diff --git a/src/error.h b/src/error.h index e60ef5b..e22fe0d 100644 --- a/src/error.h +++ b/src/error.h @@ -13,6 +13,7 @@ struct lt_error_config_filter { }; struct lt_error_config_sym { +/* FIXME put to the end of the structure as symbol[0] */ #define LT_MAXNAME 20 char symbol[LT_MAXNAME]; #define LT_MAXRET 20 @@ -27,6 +28,7 @@ struct lt_error_config { unsigned long n; int automated; int sym_cnt; + off_t names_size; struct lt_error_config_sym sym[0]; }; @@ -167,6 +167,8 @@ static int process_fifo(struct lt_config_app *cfg, struct lt_thread *t) if (-1 == lt_fifo_recv(cfg->sh, t, mbase, LT_FIFO_MSG_MAXLEN)) return -1; + PRINT_VERBOSE(cfg, 1, "DEBIL\n"); + lt_list_for_each_entry(func, &cfg->process_funcs, list) { int ret; |