summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <Jiri Olsa jolsa@redhat.com>2011-11-13 15:15:32 +0100
committerJiri Olsa <Jiri Olsa jolsa@redhat.com>2011-11-24 21:20:27 +0100
commit7e56639fe33fe39cb3f4da7dc90f547634cb4d2e (patch)
tree620591119bb7c80bba63d94cb4b3917a4bd27c96
parentaf5dafdd61af5a29043a1d8ae79427caa2136c7d (diff)
downloadlatrace-7e56639fe33fe39cb3f4da7dc90f547634cb4d2e.tar.gz
latrace-7e56639fe33fe39cb3f4da7dc90f547634cb4d2e.tar.xz
latrace-7e56639fe33fe39cb3f4da7dc90f547634cb4d2e.zip
-rw-r--r--TODO5
-rw-r--r--src/args.c4
-rw-r--r--src/args.h2
-rw-r--r--src/audit-error.c141
-rw-r--r--src/audit-init.c2
-rw-r--r--src/audit.c8
-rw-r--r--src/config.h7
-rw-r--r--src/error.c54
-rw-r--r--src/error.h2
-rw-r--r--src/symbol.c6
10 files changed, 189 insertions, 42 deletions
diff --git a/TODO b/TODO
index f29957c..d08baf8 100644
--- a/TODO
+++ b/TODO
@@ -31,3 +31,8 @@ bugs
- check we dont cross all the hardcoded limits
- consolidate leveled VERBOSE output
- info doc (produce html, pdf... outputs)
+
+error simulation:
+ - config extra size read/write
+ - put automated into separate files
+ - consolidate patches
diff --git a/src/args.c b/src/args.c
index 4fd06f4..8272a7f 100644
--- a/src/args.c
+++ b/src/args.c
@@ -981,7 +981,7 @@ static int getargs(struct lt_config_shared *cfg, struct lt_args_sym *asym,
return lt_stack_process(cfg, asym, regs, &data);
}
-struct lt_args_sym* lt_args_sym_get(struct lt_config_shared *cfg,
+struct lt_args_sym* lt_args_sym_get(struct lt_config_audit *cfg,
const char *sym)
{
struct lt_args_sym *a;
@@ -990,7 +990,7 @@ struct lt_args_sym* lt_args_sym_get(struct lt_config_shared *cfg,
PRINT_VERBOSE(cfg, 1, "request for <%s>\n", sym);
e.key = (char*) sym;
- hsearch_r(e, FIND, &ep, &cfg->args_tab);
+ hsearch_r(e, FIND, &ep, &cfg->sh->args_tab);
if (!ep)
return NULL;
diff --git a/src/args.h b/src/args.h
index 439fb79..0a2b176 100644
--- a/src/args.h
+++ b/src/args.h
@@ -120,7 +120,7 @@ struct lt_args_data {
/* arguments */
int lt_args_init(struct lt_config_shared *cfg);
-struct lt_args_sym* lt_args_sym_get(struct lt_config_shared *cfg,
+struct lt_args_sym* lt_args_sym_get(struct lt_config_audit *cfg,
const char *sym);
int lt_args_sym_entry(struct lt_config_shared *cfg, struct lt_symbol *sym,
La_regs *regs, char **argbuf, char **argdbuf);
diff --git a/src/audit-error.c b/src/audit-error.c
index 2ece447..c93c75c 100644
--- a/src/audit-error.c
+++ b/src/audit-error.c
@@ -19,12 +19,22 @@ extern FILE *lt_audit_in;
static struct hsearch_data symbol_tab;
static int symbol_tab_init = 0;
-struct lt_error_sym* lt_error_sym_get(struct lt_config_shared *cfg,
+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);
PRINT_VERBOSE(cfg, 1, "request for <%s>\n", name);
@@ -59,11 +69,11 @@ static void share_info(struct lt_config_audit *cfg,
ret_addr -= lr->l_addr;
if (keep)
- snprintf(text, LT_MAXMSG, "ERROR SIMULATION inserted %ld, ret %p",
- ret, ret_addr);
- else
snprintf(text, LT_MAXMSG, "ERROR SIMULATION no change, ret %p",
ret_addr);
+ else
+ snprintf(text, LT_MAXMSG, "ERROR SIMULATION inserted %ld, ret %p",
+ ret, ret_addr);
if (lt_sh(cfg, pipe)) {
char buf[LT_FIFO_MSG_MAXLEN];
@@ -118,6 +128,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 +139,44 @@ 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;
+
+ PRINT_VERBOSE(cfg, 1, "automated_sym_cnt %d, cfg_err->sym_cnt %d\n",
+ automated_sym_cnt, cfg_err->sym_cnt);
+
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 +194,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 +262,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 +288,96 @@ 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;
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 +392,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..31465d4 100644
--- a/src/audit.c
+++ b/src/audit.c
@@ -99,7 +99,7 @@ static int sym_entry(const char *symname, void *ptr,
gettimeofday(&tv, NULL);
if (lt_sh(&cfg, global_symbols))
- sym = lt_symbol_get(cfg.sh, ptr, symname);
+ sym = lt_symbol_get(&cfg, ptr, symname);
#ifdef CONFIG_ARCH_HAVE_ARGS
argret = lt_sh(&cfg, args_enabled) ?
@@ -152,11 +152,11 @@ static int sym_exit(const char *symname, void *ptr,
gettimeofday(&tv, NULL);
if (lt_sh(&cfg, global_symbols))
- sym = lt_symbol_get(cfg.sh, ptr, symname);
+ sym = lt_symbol_get(&cfg, ptr, symname);
#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
@@ -277,7 +277,7 @@ static unsigned int la_symbind(ElfW(Sym) *sym, const char *symname)
/* we are interested in this symbol */
if (lt_sh(&cfg, global_symbols) &&
!(flags & LA_SYMB_NOPLTENTER))
- lt_symbol_bind(cfg.sh, (void*) sym->st_value, symname);
+ lt_symbol_bind(&cfg, (void*) sym->st_value, symname);
return flags;
}
diff --git a/src/config.h b/src/config.h
index 167aa25..fd4a032 100644
--- a/src/config.h
+++ b/src/config.h
@@ -425,9 +425,9 @@ char* lt_objsearch(struct lt_config_audit *cfg, const char *name,
int lt_stack_framesize(struct lt_config_audit *cfg, La_regs *regs);
/* symbol */
-struct lt_symbol* lt_symbol_bind(struct lt_config_shared *cfg,
+struct lt_symbol* lt_symbol_bind(struct lt_config_audit *cfg,
void *ptr, const char *name);
-struct lt_symbol* lt_symbol_get(struct lt_config_shared *cfg,
+struct lt_symbol* lt_symbol_get(struct lt_config_audit *cfg,
void *ptr, const char *name);
/* config options */
@@ -456,9 +456,10 @@ int lt_error_run(struct lt_config_app *cfg);
/* error simulation lib */
int lt_error_init(struct lt_config_audit *cfg);
-struct lt_error_sym* lt_error_sym_get(struct lt_config_shared *cfg,
+struct lt_error_sym* lt_error_sym_get(struct lt_config_audit *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..adf5948 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++;
}
@@ -475,24 +475,33 @@ static int process_run_automated_cb(struct lt_config_app *cfg,
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;
- if (cfg->error_automated_symbol_index < error_config->sym_cnt) {
+ 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);
+
+ symname = automated_get_symname(cfg, mbase);
+ PRINT_VERBOSE(cfg, 1, "symname %s\n", symname);
+
+ if (cfg->error_automated_symbol_index < (error_config->sym_cnt - 1)) {
if (index != -1)
- BUG_ON((cfg->error_automated_symbol_index + 1) != index);
cfg->error_automated_symbol_index = index;
+
return 0;
}
- symname = automated_get_symname(cfg, mbase);
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;
@@ -557,8 +566,6 @@ static int prepare_config_error_automated(struct lt_config_app *cfg,
lt_list_for_each_entry(sym, sym_current, list)
sym_cnt++;
- BUG_ON(sym_cnt);
-
PRINT_VERBOSE(cfg, 1, "number of symbols %d\n", sym_cnt);
cfg_err = malloc(sizeof(*cfg_err) +
@@ -580,11 +587,12 @@ static int prepare_config_error_automated(struct lt_config_app *cfg,
cfg_sym->keep = sym->keep;
cfg_sym->handle_sigsegv = sym->handle_sigsegv;
- PRINT_VERBOSE(cfg, 1, "symbol %s, ret %s\n",
- sym->name, cfg_sym->ret);
+ PRINT_VERBOSE(cfg, 1, "symbol %s, keep %d, ret %llu\n",
+ cfg_sym->symbol, cfg_sym->keep, cfg_sym->ret);
}
cfg->error_config = cfg_err;
+ cfg->error_automated_symbol_index = -1;
return 0;
}
@@ -644,6 +652,8 @@ static int process_run_automated(struct lt_config_app *cfg,
return -1;
while(1) {
+ printf("round %d\n", n);
+
if (dir_run(cfg, dir, dir_base, run, n))
break;
@@ -671,7 +681,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 +1054,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 +1063,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];
};
diff --git a/src/symbol.c b/src/symbol.c
index 707fbf6..cbbec6e 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -70,7 +70,7 @@ static int compare(const void *a, const void *b)
#endif
}
-static int symbol_init(struct lt_config_shared *cfg,
+static int symbol_init(struct lt_config_audit *cfg,
struct lt_symbol *sym, const char *name)
{
struct lt_args_sym *a = NULL;
@@ -93,7 +93,7 @@ static int symbol_init(struct lt_config_shared *cfg,
return 0;
}
-struct lt_symbol* lt_symbol_bind(struct lt_config_shared *cfg,
+struct lt_symbol* lt_symbol_bind(struct lt_config_audit *cfg,
void *ptr, const char *name)
{
static struct lt_symbol *sym = NULL;
@@ -138,7 +138,7 @@ struct lt_symbol* lt_symbol_bind(struct lt_config_shared *cfg,
return s;
}
-struct lt_symbol* lt_symbol_get(struct lt_config_shared *cfg,
+struct lt_symbol* lt_symbol_get(struct lt_config_audit *cfg,
void *ptr, const char *name)
{
void *val;