]> git.cworth.org Git - apitrace/commitdiff
trim: Add a new --print-callset option.
authorCarl Worth <cworth@cworth.org>
Wed, 15 Aug 2012 23:35:38 +0000 (16:35 -0700)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Thu, 22 Nov 2012 08:03:20 +0000 (08:03 +0000)
This is useful whenever one has a need to manually tweak the trim operation.

Simply run:

apitrace trim --print-callset --frames=<whatever> --calls=<whatever>

as desired. Then take the resulting callset that is printed and run:

apitrace trim --calls=<callset> --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

index 1d891df53bb22b4c934a1cda95f5f652a2bbdb0d..4cfe18f8fb769943fb1fcdd548a96363831a3935 100644 (file)
@@ -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=@<file> 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<unsigned> *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();