From ab82b3b949caad0be4e0759a0bce6fa9fd76d2f5 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 15 Aug 2012 16:35:38 -0700 Subject: [PATCH] trim: Add a new --print-callset option. This is useful whenever one has a need to manually tweak the trim operation. Simply run: apitrace trim --print-callset --frames= --calls= as desired. Then take the resulting callset that is printed and run: apitrace trim --calls= --exact This should yield an identical trimming operation. Then this operation can be tweaked by appending call ranges to the --calls option, deleting rangess from the --calls option, or by appending a new --frames option. --- cli/cli_trim.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/cli/cli_trim.cpp b/cli/cli_trim.cpp index 1d891df..4cfe18f 100644 --- a/cli/cli_trim.cpp +++ b/cli/cli_trim.cpp @@ -62,6 +62,7 @@ usage(void) " --no-prune Do not prune uninteresting calls from the trace.\n" " -x, --exact Trim exactly to calls specified in --calls/--frames\n" " Equivalent to both --no-deps and --no-prune\n" + " --print-callset Print the final set of calls included in output\n" " --thread=THREAD_ID Only retain calls from specified thread\n" " -o, --output=TRACE_FILE Output trace file\n" ; @@ -106,6 +107,12 @@ help() " --calls and --frames. This option is equivalent\n" " to passing both --no-deps and --no-prune.\n" "\n" + " --print-callset Print to stdout the final set of calls included\n" + " in the trim output. This can be useful for\n" + " debugging trim operations by using a modified\n" + " callset on the command-line along with --exact.\n" + " Use --calls=@ to read callset from a file.\n" + "\n" " --thread=THREAD_ID Only retain calls from specified thread\n" "\n" " -o, --output=TRACE_FILE Output trace file\n" @@ -121,6 +128,7 @@ enum { PRUNE_OPT, NO_PRUNE_OPT, THREAD_OPT, + PRINT_CALLSET_OPT, }; const static char * @@ -138,6 +146,7 @@ longOptions[] = { {"exact", no_argument, 0, 'x'}, {"thread", required_argument, 0, THREAD_OPT}, {"output", required_argument, 0, 'o'}, + {"print-callset", no_argument, 0, PRINT_CALLSET_OPT}, {0, 0, 0, 0} }; @@ -711,6 +720,9 @@ struct trim_options { /* Emit only calls from this thread (-1 == all threads) */ int thread; + + /* Print resulting callset */ + int print_callset; }; static int @@ -721,6 +733,7 @@ trim_trace(const char *filename, struct trim_options *options) TraceAnalyzer analyzer; std::set *required; unsigned frame; + int call_range_first, call_range_last; if (!p.open(filename)) { std::cerr << "error: failed to open " << filename << "\n"; @@ -799,6 +812,8 @@ trim_trace(const char *filename, struct trim_options *options) required = analyzer.get_required(); frame = 0; + call_range_first = -1; + call_range_last = -1; while ((call = p.parse_call())) { /* There's no use doing any work past the last call or frame @@ -811,6 +826,19 @@ trim_trace(const char *filename, struct trim_options *options) if (required->find(call->no) != required->end()) { writer.writeCall(call); + + if (options->print_callset) { + if (call_range_first < 0) { + call_range_first = call->no; + printf ("%d", call_range_first); + } else if (call->no != call_range_last + 1) { + if (call_range_last != call_range_first) + printf ("-%d", call_range_last); + call_range_first = call->no; + printf (",%d", call_range_first); + } + call_range_last = call->no; + } } if (call->flags & trace::CALL_FLAG_END_FRAME) { @@ -820,6 +848,11 @@ trim_trace(const char *filename, struct trim_options *options) delete call; } + if (options->print_callset) { + if (call_range_last != call_range_first) + printf ("-%d\n", call_range_last); + } + std::cout << "Trimmed trace is available as " << options->output << "\n"; return 0; @@ -836,6 +869,7 @@ command(int argc, char *argv[]) options.prune_uninteresting = true; options.output = ""; options.thread = -1; + options.print_callset = 0; int opt; while ((opt = getopt_long(argc, argv, shortOptions, longOptions, NULL)) != -1) { @@ -871,6 +905,9 @@ command(int argc, char *argv[]) case 'o': options.output = optarg; break; + case PRINT_CALLSET_OPT: + options.print_callset = 1; + break; default: std::cerr << "error: unexpected option `" << opt << "`\n"; usage(); -- 2.43.0