summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <Jiri Olsa jolsa@redhat.com>2011-06-12 19:05:07 +0200
committerJiri Olsa <Jiri Olsa jolsa@redhat.com>2011-06-17 12:08:17 +0200
commitb56d0731ccb162f5830a94c037d6975371a067ac (patch)
treebedb84a830db5b2dfbda22ad81a12d9d3c360572
parent84e8f950cc8705bfdc7dee571f59153daeea180a (diff)
downloadlatrace-b56d0731ccb162f5830a94c037d6975371a067ac.tar.gz
latrace-b56d0731ccb162f5830a94c037d6975371a067ac.tar.xz
latrace-b56d0731ccb162f5830a94c037d6975371a067ac.zip
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.
-rw-r--r--ChangeLog2
-rw-r--r--etc/latrace.d/latrace.conf.in27
-rw-r--r--src/config-bison.y92
-rw-r--r--src/config-flex.l15
-rw-r--r--src/config.c99
-rw-r--r--src/config.h14
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 <olsajiri@gmail.com>
* 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 <stdlib.h>
+#include <string.h>
+
#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 <s> FILENAME
+%type <s> NAME
%type <s> BOOL
%type <l> 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; }
-<include>{filename} { RETURN_STR(FILENAME); }
+<include>{name} { RETURN_STR(NAME); }
<include>"\"" { return '"'; }
<include>\n { BEGIN(INITIAL); NEW_LINE(); }
<include>. { ; }
@@ -86,15 +84,22 @@ OPTIONS { BEGIN(options); return OPTIONS; }
<options>ENABLE_ARGS { return OPT_ENABLE_ARGS; }
<options>DETAIL_ARGS { return OPT_DETAIL_ARGS; }
<options>OUTPUT_TTY { return OPT_OUTPUT_TTY; }
+<options>LIBS { return OPT_LIBS; }
+<options>LIBS_TO { return OPT_LIBS_TO; }
+<options>LIBS_FROM { return OPT_LIBS_FROM; }
+<options>SYM { return OPT_SYM; }
+<options>SYM_OMIT { return OPT_SYM_OMIT; }
+<options>SYM_BELOW { return OPT_SYM_BELOW; }
<options>{bool} { RETURN_STR(BOOL); }
<options>{value} { RETURN_LONG(VALUE); }
-<options>{filename} { RETURN_STR(FILENAME); }
+<options>{name} { RETURN_STR(NAME); }
<options>{comment} { ; }
<options>"}" { BEGIN(INITIAL); return '}'; }
<options>"{" { return '{'; }
<options>"=" { return '='; }
<options>"\"" { return '"'; }
+<options>"," { return ','; }
<options>"\\" { ; }
<options>"\n" { NEW_LINE(); }
<options>. { ; }
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);