From b56d0731ccb162f5830a94c037d6975371a067ac Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 12 Jun 2011 19:05:07 +0200 Subject: config: Add libs and symbols specfication config file options Added following config file options: LIBS, LIBS_TO, LIBS_FROM, SYM, SYM_OMIT, SYM_BELOW They match their command line equivalents. --- ChangeLog | 2 + etc/latrace.d/latrace.conf.in | 27 ++++++++++++ src/config-bison.y | 92 +++++++++++++++++++++++++++++++++++++--- src/config-flex.l | 15 ++++--- src/config.c | 99 +++++++++++++++++++++++++++++++++++++------ src/config.h | 14 ++++++ 6 files changed, 227 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 02130df..16a5e6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,8 @@ * global_symbol fix - proper tree management * make tracer return actual tracee status * move all tests to scripts + * added following options + LIBS, LIBS_TO, LIBS_FROM, SYM, SYM_OMIT, SYM_BELOW 2011-06-02 Jiri Olsa * adding large file support diff --git a/etc/latrace.d/latrace.conf.in b/etc/latrace.d/latrace.conf.in index 1c547df..a14c51a 100644 --- a/etc/latrace.d/latrace.conf.in +++ b/etc/latrace.d/latrace.conf.in @@ -61,4 +61,31 @@ OPTIONS { # no command line option equivalent # stores terminal output to the file # OUTPUT_TTY = "output-tty" + + # Following options: + # LIBS/LIBS_TO/LIBS_FROM + # SYM/SYM_OMIT/SYM_BELOW + # + # use list of names as value. Single names in the list are + # separated by comma ','. If the first char of a single name + # is '*', then the name is search for as substring, otherwise + # exact match is used. + + # -l, --libs + # LIBS = krava.so + + # -t, --libs-to + # LIBS_TO = krava.so + + # -f, --libs-from + # LIBS_FROM = krava.so + + # -s, --sym + # SYM = krava + + # -n, --sym-omit + # SYM_OMIT = krava + + # -b, --flow-below + # SYM_BELOW = krava } diff --git a/src/config-bison.y b/src/config-bison.y index 4f9dae5..0000907 100644 --- a/src/config-bison.y +++ b/src/config-bison.y @@ -21,6 +21,9 @@ %name-prefix "lt_config_" %{ +#include +#include + #include "config.h" #include "lib-include.h" @@ -48,15 +51,20 @@ do { \ ERROR("failed to process option\n"); \ lt_list_add_tail(&opt->list, &opt_list); \ } while(0) + +static struct lt_list_head ln_names; + %} -%token INCLUDE FILENAME BOOL VALUE END +%token INCLUDE NAME BOOL VALUE END %token OPTIONS %token OPT_HEADERS OPT_INDENT_SYM OPT_PIPE %token OPT_TIMESTAMP OPT_FRAMESIZE OPT_FRAMESIZE_CHECK %token OPT_HIDE_TID OPT_FOLLOW_FORK OPT_FOLLOW_EXEC %token OPT_DEMANGLE OPT_BRACES OPT_ENABLE_ARGS %token OPT_DETAIL_ARGS OPT_OUTPUT_TTY +%token OPT_LIBS OPT_LIBS_TO OPT_LIBS_FROM +%token OPT_SYM OPT_SYM_OMIT OPT_SYM_BELOW %union { @@ -64,7 +72,7 @@ do { \ unsigned long l; } -%type FILENAME +%type NAME %type BOOL %type VALUE @@ -82,7 +90,7 @@ entry END | /* left blank intentionally */ -include_def: INCLUDE '"' FILENAME '"' +include_def: INCLUDE '"' NAME '"' { if (lt_inc_open(scfg->sh, lt_config_sinc, $3)) ERROR("failed to process include"); @@ -102,7 +110,7 @@ options_def: OPTIONS '{' OPTIONS_DEF '}' } OPTIONS_DEF: -OPTIONS_DEF OPT_HEADERS '=' '"' FILENAME '"' +OPTIONS_DEF OPT_HEADERS '=' '"' NAME '"' { OPTION_ADD(LT_OPT_HEADERS, $5, -1); } @@ -167,18 +175,92 @@ OPTIONS_DEF OPT_DETAIL_ARGS '=' BOOL OPTION_ADD(LT_OPT_DETAIL_ARGS, $4, -1); } | -OPTIONS_DEF OPT_OUTPUT_TTY '=' '"' FILENAME '"' +OPTIONS_DEF OPT_OUTPUT_TTY '=' '"' NAME '"' { OPTION_ADD(LT_OPT_OUTPUT_TTY, $5, -1); } | +OPTIONS_DEF OPT_LIBS '=' list_names_comma +{ + char libs[LT_LIBS_MAXSIZE]; + + if (lt_config_ln_fill(&ln_names, libs, LT_LIBS_MAXSIZE)) + ERROR("failed to process libs option"); + + OPTION_ADD(LT_OPT_LIBS, libs, -1); +} +| +OPTIONS_DEF OPT_LIBS_TO '=' list_names_comma +{ + char libs_to[LT_LIBS_MAXSIZE]; + + if (lt_config_ln_fill(&ln_names, libs_to, LT_LIBS_MAXSIZE)) + ERROR("failed to process libs_to option"); + + OPTION_ADD(LT_OPT_LIBS_TO, libs_to, -1); +} +| +OPTIONS_DEF OPT_LIBS_FROM '=' list_names_comma +{ + char libs_from[LT_LIBS_MAXSIZE]; + + if (lt_config_ln_fill(&ln_names, libs_from, LT_LIBS_MAXSIZE)) + ERROR("failed to process libs_from option"); + + OPTION_ADD(LT_OPT_LIBS_FROM, libs_from, -1); +} +| +OPTIONS_DEF OPT_SYM '=' list_names_comma +{ + char sym[LT_LIBS_MAXSIZE]; + + if (lt_config_ln_fill(&ln_names, sym, LT_LIBS_MAXSIZE)) + ERROR("failed to process sym option"); + + OPTION_ADD(LT_OPT_SYM, sym, -1); +} +| +OPTIONS_DEF OPT_SYM_OMIT '=' list_names_comma +{ + char sym_omit[LT_SYMBOLS_MAXSIZE]; + + if (lt_config_ln_fill(&ln_names, sym_omit, LT_SYMBOLS_MAXSIZE)) + ERROR("failed to process sym_omit option"); + + OPTION_ADD(LT_OPT_SYM_OMIT, sym_omit, -1); +} +| +OPTIONS_DEF OPT_SYM_BELOW '=' list_names_comma +{ + char sym_below[LT_SYMBOLS_MAXSIZE]; + + if (lt_config_ln_fill(&ln_names, sym_below, LT_SYMBOLS_MAXSIZE)) + ERROR("failed to process sym_below option"); + + OPTION_ADD(LT_OPT_SYM_BELOW, sym_below, -1); +} +| /* left blank intentionally */ +list_names_comma: +list_names_comma ',' NAME +{ + if (lt_config_ln_add(&ln_names, $3)) + ERROR("failed to add list name"); +} +| +NAME +{ + if (lt_config_ln_add(&ln_names, $1)) + ERROR("failed to add list name"); +} + %% int lt_config_parse_init(struct lt_config_app *cfg, struct lt_include *inc) { scfg = cfg; lt_config_sinc = inc; + lt_init_list_head(&ln_names); return 0; } diff --git a/src/config-flex.l b/src/config-flex.l index c2ed192..a15a687 100644 --- a/src/config-flex.l +++ b/src/config-flex.l @@ -50,9 +50,7 @@ do { \ num [-0-9] value ({num})+ -alphnum [-0-9a-zA-Z_] -name ({alphnum})+ -filename ([-0-9a-zA-Z\./_])+ +name ([-0-9a-zA-Z\./_\-\*])+ bool YES|NO comment ^([\s\t])*#.* @@ -66,7 +64,7 @@ comment ^([\s\t])*#.* . { ; } INCLUDE { BEGIN(include); return INCLUDE; } -{filename} { RETURN_STR(FILENAME); } +{name} { RETURN_STR(NAME); } "\"" { return '"'; } \n { BEGIN(INITIAL); NEW_LINE(); } . { ; } @@ -86,15 +84,22 @@ OPTIONS { BEGIN(options); return OPTIONS; } ENABLE_ARGS { return OPT_ENABLE_ARGS; } DETAIL_ARGS { return OPT_DETAIL_ARGS; } OUTPUT_TTY { return OPT_OUTPUT_TTY; } +LIBS { return OPT_LIBS; } +LIBS_TO { return OPT_LIBS_TO; } +LIBS_FROM { return OPT_LIBS_FROM; } +SYM { return OPT_SYM; } +SYM_OMIT { return OPT_SYM_OMIT; } +SYM_BELOW { return OPT_SYM_BELOW; } {bool} { RETURN_STR(BOOL); } {value} { RETURN_LONG(VALUE); } -{filename} { RETURN_STR(FILENAME); } +{name} { RETURN_STR(NAME); } {comment} { ; } "}" { BEGIN(INITIAL); return '}'; } "{" { return '{'; } "=" { return '='; } "\"" { return '"'; } +"," { return ','; } "\\" { ; } "\n" { NEW_LINE(); } . { ; } diff --git a/src/config.c b/src/config.c index df78c10..4ab9f97 100644 --- a/src/config.c +++ b/src/config.c @@ -283,6 +283,42 @@ static int process_option_val(struct lt_config_app *cfg, int idx, cfg->output_tty_file); break; + case LT_OPT_LIBS: + strcpy(lt_sh(cfg, libs_both), sval); + PRINT_VERBOSE(cfg, 1, "LIBS '%s'\n", + lt_sh(cfg, libs_both)); + break; + + case LT_OPT_LIBS_TO: + strcpy(lt_sh(cfg, libs_to), sval); + PRINT_VERBOSE(cfg, 1, "LIBS_TO '%s'\n", + lt_sh(cfg, libs_to)); + break; + + case LT_OPT_LIBS_FROM: + strcpy(lt_sh(cfg, libs_from), sval); + PRINT_VERBOSE(cfg, 1, "LIBS_FROM '%s'\n", + lt_sh(cfg, libs_from)); + break; + + case LT_OPT_SYM: + strcpy(lt_sh(cfg, symbols), sval); + PRINT_VERBOSE(cfg, 1, "SYM '%s'\n", + lt_sh(cfg, symbols)); + break; + + case LT_OPT_SYM_OMIT: + strcpy(lt_sh(cfg, symbols_omit), sval); + PRINT_VERBOSE(cfg, 1, "SYM_OMIT '%s'\n", + lt_sh(cfg, symbols_omit)); + break; + + case LT_OPT_SYM_BELOW: + strcpy(lt_sh(cfg, flow_below), sval); + PRINT_VERBOSE(cfg, 1, "SYM_BELOW '%s'\n", + lt_sh(cfg, flow_below)); + break; + default: return -1; } @@ -325,6 +361,45 @@ struct lt_config_opt *lt_config_opt_new(int idx, char *sval, long nval) return opt; } +int lt_config_ln_add(struct lt_list_head *head, char *name) +{ + struct lt_config_ln *ln = malloc(sizeof(*ln)); + + if (!ln) + return -1; + + ln->name = strdup(name); + lt_init_list_head(&ln->list); + lt_list_add_tail(&ln->list, head); + return 0; +} + +int lt_config_ln_fill(struct lt_list_head *head, char *buf, int size) +{ + struct lt_config_ln *ln, *n; + int first = 1; + char *b = buf; + + buf[0] = 0x00; + + lt_list_for_each_entry_safe(ln, n, head, list) { + int ret; + + ret = snprintf(b, size, "%s%s", + first ? "" : ",", + ln->name); + + if (ret >= size) + return -1; + + size -= ret; + b += ret; + first = 0; + } + + return 0; +} + int lt_config(struct lt_config_app *cfg, int argc, char **argv) { memset(cfg, 0, sizeof(*cfg)); @@ -393,45 +468,45 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv) switch (c) { case 'l': - if (strlen(optarg) > LT_LIBS_MAXSIZE) + if (strlen(optarg) >= LT_LIBS_MAXSIZE) return -1; - strncpy(lt_sh(cfg, libs_both), optarg, strlen(optarg)); + process_option_val(cfg, LT_OPT_LIBS, optarg, -1); break; case 't': - if (strlen(optarg) > LT_LIBS_MAXSIZE) + if (strlen(optarg) >= LT_LIBS_MAXSIZE) return -1; - strncpy(lt_sh(cfg, libs_to), optarg, strlen(optarg)); + process_option_val(cfg, LT_OPT_LIBS_TO, optarg, -1); break; case 'f': - if (strlen(optarg) > LT_LIBS_MAXSIZE) + if (strlen(optarg) >= LT_LIBS_MAXSIZE) return -1; - strncpy(lt_sh(cfg, libs_from), optarg, strlen(optarg)); + process_option_val(cfg, LT_OPT_LIBS_FROM, optarg, -1); break; case 's': - if (strlen(optarg) > LT_SYMBOLS_MAXSIZE) + if (strlen(optarg) >= LT_SYMBOLS_MAXSIZE) return -1; - strncpy(lt_sh(cfg, symbols), optarg, strlen(optarg)); + process_option_val(cfg, LT_OPT_SYM, optarg, -1); break; case 'n': - if (strlen(optarg) > LT_SYMBOLS_MAXSIZE) + if (strlen(optarg) >= LT_SYMBOLS_MAXSIZE) return -1; - strncpy(lt_sh(cfg, symbols_omit), optarg, strlen(optarg)); + process_option_val(cfg, LT_OPT_SYM_OMIT, optarg, -1); break; case 'b': - if (strlen(optarg) > LT_SYMBOLS_MAXSIZE) + if (strlen(optarg) >= LT_SYMBOLS_MAXSIZE) return -1; - strncpy(lt_sh(cfg, flow_below), optarg, strlen(optarg)); + process_option_val(cfg, LT_OPT_SYM_BELOW, optarg, -1); break; case 'v': diff --git a/src/config.h b/src/config.h index 7c88b8c..2006f7e 100644 --- a/src/config.h +++ b/src/config.h @@ -84,6 +84,12 @@ enum { LT_OPT_ENABLE_ARGS, LT_OPT_DETAIL_ARGS, LT_OPT_OUTPUT_TTY, + LT_OPT_LIBS, + LT_OPT_LIBS_TO, + LT_OPT_LIBS_FROM, + LT_OPT_SYM, + LT_OPT_SYM_OMIT, + LT_OPT_SYM_BELOW, }; struct lt_config_opt { @@ -228,6 +234,12 @@ struct lt_config_audit { int init_ok; }; +/* config - list name support */ +struct lt_config_ln { + char *name; + struct lt_list_head list; +}; + #define lt_sh(cfg, field) ((cfg)->sh->field) #define FIFO_MSG_MAXLEN 2000 @@ -354,6 +366,8 @@ struct lt_symbol* lt_symbol_get(struct lt_config_shared *cfg, /* config options */ struct lt_config_opt *lt_config_opt_new(int idx, char *sval, long nval); int lt_config_opt_process(struct lt_config_app *cfg, struct lt_list_head *list); +int lt_config_ln_add(struct lt_list_head *head, char *name); +int lt_config_ln_fill(struct lt_list_head *head, char *buf, int size); /* tty */ int tty_master(struct lt_config_app *cfg); -- cgit