diff options
author | Petr Machata <pmachata@redhat.com> | 2012-09-27 23:43:25 +0200 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2012-10-01 14:18:53 +0200 |
commit | 51e74aca71ff7e8be91c074afd4f2264f46294e9 (patch) | |
tree | 9d55d829ceef7262f86e0e733eeb3a0fd4d4eaba | |
parent | 74e57dd396818b1a9414c44e397ac82f692f5582 (diff) | |
download | ltrace-51e74aca71ff7e8be91c074afd4f2264f46294e9.tar.gz |
Add parsing of -l option
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | ltrace.1 | 18 | ||||
-rw-r--r-- | options.c | 53 | ||||
-rw-r--r-- | options.h | 5 | ||||
-rw-r--r-- | testsuite/ltrace.main/main-threaded.exp | 2 | ||||
-rw-r--r-- | testsuite/ltrace.main/main-vfork.exp | 2 | ||||
-rw-r--r-- | testsuite/ltrace.main/main.exp | 2 | ||||
-rw-r--r-- | testsuite/ltrace.main/parameters-lib.c | 5 | ||||
-rw-r--r-- | testsuite/ltrace.main/parameters.c | 11 | ||||
-rw-r--r-- | testsuite/ltrace.main/parameters.conf | 2 | ||||
-rw-r--r-- | testsuite/ltrace.main/parameters.exp | 12 |
11 files changed, 86 insertions, 41 deletions
@@ -1,5 +1,20 @@ 2012-09-27 Petr Machata <pmachata@redhat.com> + * options.h (struct options_t.export_filter): New field. + * options.c (parse_filter): Take argument OPERATORS. + (recursive_parse_chain): Likewise. + (slist_chase_end): New function. + (process_options): Handle 'l' option, initialize export_filter. + * ltrace.1: Explain -l. + * testsuite/ltrace.main/main-vfork.exp: Update use of -l. + * testsuite/ltrace.main/main.exp: Likewise. + * testsuite/ltrace.main/parameters-lib.c (func_printf): New function. + * testsuite/ltrace.main/parameters.c: Call it instead of printf. + * testsuite/ltrace.main/parameters.conf: Declare it. + * testsuite/ltrace.main/parameters.exp: Update expectations and -l. + +2012-09-27 Petr Machata <pmachata@redhat.com> + * library.h (library_symbol_named_cb): New function. * library.c (library_symbol_named_cb): Implemented here. @@ -7,7 +7,7 @@ ltrace \- A library call tracer .SH SYNOPSIS .B ltrace -.I "[-bCfghiLrStttV] [-a column] [-A maxelts] [-D level] [-e expr] [-l filename] [-n nr] [-o filename] [-p pid] ... [-s strsize] [-u username] [-w count] [-x extern] ... [--align=column] [--debug=level] [--demangle] [--help] [--indent=nr] [--library=filename] [--no-signals] [--output=filename] [--version] [--where=NR] [command [arg ...]]" +.I "[-bCfghiLrStttV] [-a column] [-A maxelts] [-D level] [-e expr] [-l library_pattern] [-n nr] [-o filename] [-p pid] ... [-s strsize] [-u username] [-w count] [-x extern] ... [--align=column] [--debug=level] [--demangle] [--help] [--indent=nr] [--library=library_pattern] [--no-signals] [--output=filename] [--version] [--where=NR] [command [arg ...]]" .SH DESCRIPTION .B ltrace @@ -95,16 +95,16 @@ Show a summary of the options to ltrace and exit. .I \-i Print the instruction pointer at the time of the library call. .TP -.I \-l, \-\-library filename -Display only the symbols included in the library -.I filename. -Up to 30 library names can be specified with several instances -of this option. +.I \-l, \-\-library library_pattern +Display only the symbols implemented by libraries that match +.I library_pattern. +Multiple library patters can be specified with several instances of +this option. Syntax of library_pattern is described in section +\fBFILTER EXPRESSIONS\fR. .TP .I \-L -DON'T display library calls (use it with the -.I \-S -option). +When no -e option is given, don't assume the default action of +\fB@MAIN\fR. .TP .I \-n, \-\-indent nr Indent trace output by @@ -74,7 +74,7 @@ usage(void) { " -F, --config=FILE load alternate configuration file (may be repeated).\n" " -h, --help display this help and exit.\n" " -i print instruction pointer at time of library call.\n" - " -l, --library=FILE print library calls from this library only.\n" + " -l, --library=FILE only trace symbols implemented by this library.\n" " -L do NOT display library calls.\n" " -n, --indent=NR indent output by NR spaces for each call level nesting.\n" " -o, --output=FILE write the trace output to that file.\n" @@ -257,7 +257,7 @@ grok_libname_pattern(char **libnamep, char **libendp) } static int -parse_filter(struct filter *filt, char *expr) +parse_filter(struct filter *filt, char *expr, int operators) { /* Filter is a chain of sym@lib rules separated by '-' or '+'. * If the filter expression starts with '-', the missing @@ -266,7 +266,7 @@ parse_filter(struct filter *filt, char *expr) enum filter_rule_type type = FR_ADD; while (*expr != 0) { - size_t s = strcspn(expr, "@-+"); + size_t s = strcspn(expr, "-+@" + (operators ? 0 : 2)); char *symname = expr; char *libname; char *next = expr + s + 1; @@ -285,7 +285,7 @@ parse_filter(struct filter *filt, char *expr) } else { assert(expr[s] == '@'); expr[s] = 0; - s = strcspn(next, "-+"); + s = strcspn(next, "-+" + (operators ? 0 : 2)); if (s == 0) { libname = "*"; expr = next; @@ -357,7 +357,7 @@ parse_filter(struct filter *filt, char *expr) } static struct filter * -recursive_parse_chain(char *expr) +recursive_parse_chain(char *expr, int operators) { struct filter *filt = malloc(sizeof(*filt)); if (filt == NULL) { @@ -367,7 +367,7 @@ recursive_parse_chain(char *expr) } filter_init(filt); - if (parse_filter(filt, expr) < 0) { + if (parse_filter(filt, expr, operators) < 0) { fprintf(stderr, "Filter '%s' will be ignored.\n", expr); free(filt); filt = NULL; @@ -376,6 +376,14 @@ recursive_parse_chain(char *expr) return filt; } +static struct filter ** +slist_chase_end(struct filter **begin) +{ + for (; *begin != NULL; begin = &(*begin)->next) + ; + return begin; +} + static void parse_filter_chain(const char *expr, struct filter **retp) { @@ -389,10 +397,7 @@ parse_filter_chain(const char *expr, struct filter **retp) if (str[0] == '!') str[0] = '-'; - struct filter **tailp; - for (tailp = retp; *tailp != NULL; tailp = &(*tailp)->next) - ; - *tailp = recursive_parse_chain(str); + *slist_chase_end(retp) = recursive_parse_chain(str, 1); } char ** @@ -499,10 +504,16 @@ process_options(int argc, char **argv) case 'i': opt_i++; break; - case 'l': - // XXX TODO - fprintf(stderr, "-l support not yet implemented\n"); + + case 'l': { + size_t patlen = strlen(optarg); + char buf[patlen + 2]; + sprintf(buf, "@%s", optarg); + *slist_chase_end(&options.export_filter) + = recursive_parse_chain(buf, 0); break; + } + case 'L': libcalls = 0; break; @@ -607,13 +618,21 @@ process_options(int argc, char **argv) opt_F = egg; } - /* Set default filter. Use @MAIN for now, as that's what - * ltrace used to have in the past. XXX Maybe we should make - * this "*" instead. */ - if (options.plt_filter == NULL && libcalls) { + /* If neither -e, nor -l, nor -L are used, set default -e. + * Use @MAIN for now, as that's what ltrace used to have in + * the past. XXX Maybe we should make this "*" instead. */ + if (libcalls + && options.plt_filter == NULL + && options.export_filter == NULL) { parse_filter_chain("@MAIN", &options.plt_filter); options.hide_caller = 1; } + if (!libcalls && options.plt_filter != NULL) { + fprintf(stderr, + "%s: Option -L can't be used with -e or -l.\n", + progname); + err_usage(); + } if (!opt_p && argc < 1) { fprintf(stderr, "%s: too few arguments\n", progname); @@ -21,6 +21,11 @@ struct options_t { #endif /* defined(HAVE_LIBUNWIND) */ struct filter *plt_filter; struct filter *static_filter; + + /* A filter matching library names of libraries, whose + * exported symbols we wish to trace. */ + struct filter *export_filter; + int hide_caller; /* Whether caller library should be hidden. */ }; extern struct options_t options; diff --git a/testsuite/ltrace.main/main-threaded.exp b/testsuite/ltrace.main/main-threaded.exp index 5539805..4f6c25d 100644 --- a/testsuite/ltrace.main/main-threaded.exp +++ b/testsuite/ltrace.main/main-threaded.exp @@ -19,7 +19,7 @@ if { [ltrace_compile_shlib $libsrc $lib_sl debug ] != "" } # set options for ltrace. -ltrace_options "-l" "$lib_sl" "-f" +ltrace_options "-l" "lib$testfile.so" "-f" # Run PUT for ltarce. set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] diff --git a/testsuite/ltrace.main/main-vfork.exp b/testsuite/ltrace.main/main-vfork.exp index 299c5e0..989012d 100644 --- a/testsuite/ltrace.main/main-vfork.exp +++ b/testsuite/ltrace.main/main-vfork.exp @@ -19,7 +19,7 @@ if { [ltrace_compile_shlib $libsrc $lib_sl debug ] != "" } # set options for ltrace. -ltrace_options "-l" "$lib_sl" "-f" +ltrace_options "-l" "lib$testfile.so" "-f" "-evfork" # Run PUT for ltarce. set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] diff --git a/testsuite/ltrace.main/main.exp b/testsuite/ltrace.main/main.exp index 9e126bc..50c5353 100644 --- a/testsuite/ltrace.main/main.exp +++ b/testsuite/ltrace.main/main.exp @@ -19,7 +19,7 @@ if { [ltrace_compile_shlib $libsrc $lib_sl debug ] != "" } # set options for ltrace. -ltrace_options "-l" "$objdir/$subdir/libmain.so" +ltrace_options "-l" "libmain.so" # Run PUT for ltarce. set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] diff --git a/testsuite/ltrace.main/parameters-lib.c b/testsuite/ltrace.main/parameters-lib.c index 750075e..04effaf 100644 --- a/testsuite/ltrace.main/parameters-lib.c +++ b/testsuite/ltrace.main/parameters-lib.c @@ -456,3 +456,8 @@ func_hfa_d12(struct struct_hfa_d12 e) { return e; } + +void +func_printf(char *format, ...) +{ +} diff --git a/testsuite/ltrace.main/parameters.c b/testsuite/ltrace.main/parameters.c index 44d54b2..ae8e17b 100644 --- a/testsuite/ltrace.main/parameters.c +++ b/testsuite/ltrace.main/parameters.c @@ -182,10 +182,11 @@ main () 15, 16, 'B', 18.0, 19.0, 20.0, 21, 22.0, 23.0, 24.0, 25.0); - printf("sotnuh %d %ld %g %c\n", 5, 6L, 1.5, 'X'); - printf("sotnuh1 %d %ld %hd\n", 5, 6L, (short)7); - printf("sotnuh2 %s %10s %10s\n", "a string", "a trimmed string", "short"); - printf("many_args" + void func_printf(char *format, ...); + func_printf("sotnuh %d %ld %g %c\n", 5, 6L, 1.5, 'X'); + func_printf("sotnuh1 %d %ld %hd\n", 5, 6L, (short)7); + func_printf("sotnuh2 %s %10s %10s\n", "a string", "a trimmed string", "short"); + func_printf("many_args" "%d %d %ld %g %c %d %g " "%c %d %g %d %g %c %d " "%hd %d %c %g %g %g " @@ -195,7 +196,7 @@ main () (short)15, 16, 'B', 18.0, 19.0, 20.0, 21L, 22.0, 23.0, 24.0, 25.0); - printf("sotnuh3 %*s\n", 4, "a trimmed string"); + func_printf("sotnuh3 %*s\n", 4, "a trimmed string"); void func_lens(int, long, short, long); func_lens(22, 23, 24, 25); diff --git a/testsuite/ltrace.main/parameters.conf b/testsuite/ltrace.main/parameters.conf index 0531a6a..743237f 100644 --- a/testsuite/ltrace.main/parameters.conf +++ b/testsuite/ltrace.main/parameters.conf @@ -22,7 +22,7 @@ struct(long,long,long,long) func_struct_large(struct(long,long,long,long), struc struct(char,char,long,long) func_struct_large2(struct(char,char,long,long), struct(char,char,long,long)); struct(long,long,char,char) func_struct_large3(struct(long,long,char,char), struct(long,long,char,char)); void func_many_args(int, int, long, double, char, int, float, char, int, double, int, double, char, int, short, int, char, float, float, double, long, float, float, float, float); -int printf(format); +void func_printf(format); void func_lens(octal, octal(long), hex(short), hex(long)); bool(int) func_bool(int, bool(int)); void func_hide(int, hide(int), hide(int), int, hide(int), int); diff --git a/testsuite/ltrace.main/parameters.exp b/testsuite/ltrace.main/parameters.exp index badbe6b..367214f 100644 --- a/testsuite/ltrace.main/parameters.exp +++ b/testsuite/ltrace.main/parameters.exp @@ -20,7 +20,7 @@ if { [ltrace_compile_shlib $libsrc $lib_sl debug ] != "" } # set options for ltrace. -ltrace_options "-l" "$objdir/$subdir/libparameters.so" "-F" "$srcdir/$subdir/parameters.conf" +ltrace_options "-l" "libparameters.so" "-F" "$srcdir/$subdir/parameters.conf" # Run PUT for ltarce. set exec_output [ltrace_runtest $objdir/$subdir $objdir/$subdir/$binfile] @@ -100,19 +100,19 @@ ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "func_many_args(1, 2, 3, 4.00*, '5', 6, 7.00*, '8', 9, 10.00*, 11, 12.00*, 'A', 14, 15, 16, 'B', 18.00*, 19.00*, 20.00*, 21, 22.00*, 23.00*, 24.00*, 25.00*)" ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 -set pattern "printf(\\\"sotnuh %d %ld %g %c.n\\\", 5, 6, 1.500*, 'X')" +set pattern "func_printf(\\\"sotnuh %d %ld %g %c.n\\\", 5, 6, 1.500*, 'X')" ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 -set pattern "printf(\\\"sotnuh1 %d %ld %hd.n\\\", 5, 6, 7)" +set pattern "func_printf(\\\"sotnuh1 %d %ld %hd.n\\\", 5, 6, 7)" ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 -set pattern "printf(\\\"sotnuh2 %s %10s %10s.n\\\", \\\"a string\\\", \\\"a trimmed \\\", \\\"short\\\")" +set pattern "func_printf(\\\"sotnuh2 %s %10s %10s.n\\\", \\\"a string\\\", \\\"a trimmed \\\", \\\"short\\\")" ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 -set pattern "printf(\\\"sotnuh3 %.s.n\\\", 4, \\\"a tr\\\")" +set pattern "func_printf(\\\"sotnuh3 %.s.n\\\", 4, \\\"a tr\\\")" ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 -set pattern "printf(\\\"many_args%d %d %ld %g %c %d %g .*, 1, 2, 3, 4.00*, '5', 6, 7.00*, '8', 9, 10.00*, 11, 12.00*, 'A', 14, 15, 16, 'B', 18.00*, 19.00*, 20.00*, 21, 22.00*, 23.00*, 24.00*, 25.00*)" +set pattern "func_printf(\\\"many_args%d %d %ld %g %c %d %g .*, 1, 2, 3, 4.00*, '5', 6, 7.00*, '8', 9, 10.00*, 11, 12.00*, 'A', 14, 15, 16, 'B', 18.00*, 19.00*, 20.00*, 21, 22.00*, 23.00*, 24.00*, 25.00*)" ltrace_verify_output ${objdir}/${subdir}/${testfile}.ltrace $pattern 1 set pattern "func_lens(026, 027, 0x18, 0x19)" |