Coverage for /Syzygy/instrument/instrument_app.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
91.2%52570.C++source

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  //
  15    :  // Defines the InstrumentApp class, which implements the command-line
  16    :  // "instrument" tool.
  17    :  
  18    :  #include "syzygy/instrument/instrument_app.h"
  19    :  
  20    :  #include <algorithm>
  21    :  #include <iostream>
  22    :  
  23    :  #include "base/strings/string_util.h"
  24    :  #include "base/strings/stringprintf.h"
  25    :  #include "syzygy/instrument/instrumenters/archive_instrumenter.h"
  26    :  #include "syzygy/instrument/instrumenters/asan_instrumenter.h"
  27    :  #include "syzygy/instrument/instrumenters/bbentry_instrumenter.h"
  28    :  #include "syzygy/instrument/instrumenters/branch_instrumenter.h"
  29    :  #include "syzygy/instrument/instrumenters/coverage_instrumenter.h"
  30    :  #include "syzygy/instrument/instrumenters/entry_call_instrumenter.h"
  31    :  #include "syzygy/instrument/instrumenters/entry_thunk_instrumenter.h"
  32    :  
  33    :  namespace instrument {
  34    :  
  35    :  namespace {
  36    :  
  37    :  static const char kUsageFormatStr[] =
  38    :      "Usage: %ls [options]\n"
  39    :      "  Required arguments:\n"
  40    :      "    --input-image=<path> The input image to instrument.\n"
  41    :      "    --mode=asan|bbentry|branch|calltrace|coverage|profile\n"
  42    :      "                            Specifies which instrumentation mode is to\n"
  43    :      "                            be used. If this is not specified it is\n"
  44    :      "                            equivalent to specifying --mode=calltrace\n"
  45    :      "                            (this default behaviour is DEPRECATED).\n"
  46    :      "    --output-image=<path>\n"
  47    :      "                            The instrumented output image.\n"
  48    :      "  DEPRECATED options:\n"
  49    :      "    --input-dll is aliased to --input-image.\n"
  50    :      "    --output-dll is aliased to --output-image.\n"
  51    :      "    --call-trace-client=RPC\n"
  52    :      "                            Equivalent to --mode=calltrace.\n"
  53    :      "    --call-trace-client=PROFILER\n"
  54    :      "                            Equivalent to --mode=profile.\n"
  55    :      "    --call-trace-client=<path>\n"
  56    :      "                            Equivalent to --mode=calltrace\n"
  57    :      "                                 --agent=<path>.\n"
  58    :      "  General options (applicable in all modes):\n"
  59    :      "    --agent=<path>          If specified indicates exactly which DLL to\n"
  60    :      "                            use when instrumenting the provided module.\n"
  61    :      "                            If not specified a default agent library\n"
  62    :      "                            will be used. This is ignored in Asan mode.\n"
  63    :      "    --debug-friendly        Generate more debugger friendly output by\n"
  64    :      "                            making the thunks resolve to the original\n"
  65    :      "                            function's name. This is at the cost of the\n"
  66    :      "                            uniqueness of address->name resolution.\n"
  67    :      "    --inline-fast-path      Inline a fast path into the instrumented\n"
  68    :      "                            image.\n"
  69    :      "    --input-pdb=<path>      The PDB for the DLL to instrument. If not\n"
  70    :      "                            explicitly provided will be searched for.\n"
  71    :      "    --filter=<path>         The path of the filter to be used in\n"
  72    :      "                            applying the instrumentation. Ranges marked\n"
  73    :      "                            in the filter will not be instrumented.\n"
  74    :      "    --no-augment-pdb        Indicates that the relinker should not\n"
  75    :      "                            augment the output PDB with additional.\n"
  76    :      "                            metadata.\n"
  77    :      "    --no-strip-strings      Indicates that the relinker should not strip\n"
  78    :      "                            the strings when augmenting the PDB. They\n"
  79    :      "                            are stripped by default to keep PDB sizes\n"
  80    :      "                            down.\n"
  81    :      "    --output-pdb=<path>     The PDB for the instrumented DLL. If not\n"
  82    :      "                            provided will attempt to generate one.\n"
  83    :      "    --overwrite             Allow output files to be overwritten.\n"
  84    :      "  asan mode options:\n"
  85    :      "    --asan-rtl-options=OPTIONS\n"
  86    :      "                            Allows specification of options that will\n"
  87    :      "                            influence the Asan RTL that attaches to the\n"
  88    :      "                            instrumented module. For descriptions of\n"
  89    :      "                            these options see common/asan_parameters. If\n"
  90    :      "                            not specified then the defaults of the RTL\n"
  91    :      "                            will be used.\n"
  92    :      "    --instrumentation-rate=DOUBLE\n"
  93    :      "                            Specifies the fraction of instructions to\n"
  94    :      "                            be instrumented, as a value in the range\n"
  95    :      "                            0..1, inclusive. Defaults to 1.\n"
  96    :      "    --no-interceptors       Disable the interception of the functions\n"
  97    :      "                            like memset, memcpy, stcpy, ReadFile... to\n"
  98    :      "                            check their parameters.\n"
  99    :      "    --no-liveness-analysis  Disables register and flags liveness\n"
 100    :      "                            analysis.\n"
 101    :      "    --no-redundancy-analysis\n"
 102    :      "                            Disables redundant memory access analysis.\n"
 103    :      "  branch mode options:\n"
 104    :      "    --buffering             Enable per-thread buffering of events.\n"
 105    :      "    --fs-slot=<slot>        Specify which FS slot to use for thread\n"
 106    :      "                            local storage.\n"
 107    :      "  calltrace mode options:\n"
 108    :      "    --instrument-imports    Also instrument calls to imports.\n"
 109    :      "    --module-entry-only     If specified then the per-function entry\n"
 110    :      "                            hook will not be used and only module entry\n"
 111    :      "                            points will be hooked.\n"
 112    :      "    --no-unsafe-refs        Perform no instrumentation of references\n"
 113    :      "                            between code blocks that contain anything\n"
 114    :      "                            but C/C++.\n"
 115    :      "  profile mode options:\n"
 116    :      "    --instrument-imports    Also instrument calls to imports.\n"
 117    :      "\n";
 118    :  
 119    :  // Currently only Asan supports COFF/LIB instrumentation. As other
 120    :  // instrumenters add COFF support they need to be added with a similar
 121    :  // mechanism.
 122  E :  InstrumenterInterface* AsanInstrumenterFactory() {
 123  E :    return new instrumenters::AsanInstrumenter();
 124  E :  }
 125    :  
 126    :  }  // namespace
 127    :  
 128  E :  void InstrumentApp::ParseDeprecatedMode(const CommandLine* cmd_line) {
 129  E :    DCHECK(cmd_line != NULL);
 130    :  
 131  E :    std::string client = cmd_line->GetSwitchValueASCII("call-trace-client");
 132    :  
 133  E :    if (client.empty()) {
 134  E :      LOG(INFO) << "DEPRECATED: No mode specified, using --mode=calltrace.";
 135    :      instrumenter_.reset(new instrumenters::EntryThunkInstrumenter(
 136  E :          instrumenters::EntryThunkInstrumenter::CALL_TRACE));
 137  E :      return;
 138    :    }
 139    :  
 140  E :    if (LowerCaseEqualsASCII(client, "profiler")) {
 141  E :      LOG(INFO) << "DEPRECATED: Using --mode=profile.";
 142    :      instrumenter_.reset(new instrumenters::EntryThunkInstrumenter(
 143  E :          instrumenters::EntryThunkInstrumenter::PROFILE));
 144  E :    } else if (LowerCaseEqualsASCII(client, "rpc")) {
 145  E :      LOG(INFO) << "DEPRECATED: Using --mode=calltrace.";
 146    :      instrumenter_.reset(new instrumenters::EntryThunkInstrumenter(
 147  E :          instrumenters::EntryThunkInstrumenter::CALL_TRACE));
 148  E :    } else {
 149  i :      LOG(INFO) << "DEPRECATED: Using --mode=calltrace --agent=" << client << ".";
 150    :      instrumenter_.reset(new instrumenters::EntryThunkInstrumenter(
 151  i :          instrumenters::EntryThunkInstrumenter::CALL_TRACE));
 152    :    }
 153  E :  }
 154    :  
 155  E :  bool InstrumentApp::ParseCommandLine(const CommandLine* cmd_line) {
 156  E :    DCHECK(cmd_line != NULL);
 157    :  
 158  E :    if (cmd_line->HasSwitch("help"))
 159  E :      return Usage(cmd_line, "");
 160    :  
 161    :    // Get the mode and the default client DLL.
 162  E :    if (!cmd_line->HasSwitch("mode")) {
 163    :      // TODO(chrisha): Remove this once build scripts and profiling tools have
 164    :      //     been updated.
 165  E :      ParseDeprecatedMode(cmd_line);
 166  E :    } else {
 167  E :      std::string mode = cmd_line->GetSwitchValueASCII("mode");
 168  E :      if (LowerCaseEqualsASCII(mode, "asan")) {
 169    :        // We wrap the Asan instrumenter in an ArchiveInstrumenter adapter so
 170    :        // that it can transparently handle .lib files.
 171    :        instrumenter_.reset(new instrumenters::ArchiveInstrumenter(
 172  E :            &AsanInstrumenterFactory));
 173  E :      } else if (LowerCaseEqualsASCII(mode, "bbentry")) {
 174  E :        instrumenter_.reset(new instrumenters::BasicBlockEntryInstrumenter());
 175  E :      } else if (LowerCaseEqualsASCII(mode, "branch")) {
 176  E :        instrumenter_.reset(new instrumenters::BranchInstrumenter());
 177  E :      } else if (LowerCaseEqualsASCII(mode, "calltrace")) {
 178    :        instrumenter_.reset(new instrumenters::EntryThunkInstrumenter(
 179  E :            instrumenters::EntryThunkInstrumenter::CALL_TRACE));
 180  E :      } else if (LowerCaseEqualsASCII(mode, "coverage")) {
 181  E :        instrumenter_.reset(new instrumenters::CoverageInstrumenter());
 182  E :      } else if (LowerCaseEqualsASCII(mode, "profile")) {
 183  E :        instrumenter_.reset(new instrumenters::EntryCallInstrumenter());
 184  E :      } else {
 185    :        return Usage(cmd_line,
 186    :                     base::StringPrintf("Unknown instrumentation mode: %s.",
 187  i :                                        mode.c_str()).c_str());
 188    :      }
 189  E :    }
 190  E :    DCHECK(instrumenter_.get() != NULL);
 191    :  
 192  E :    return instrumenter_->ParseCommandLine(cmd_line);
 193  E :  }
 194    :  
 195  E :  int InstrumentApp::Run() {
 196  E :    DCHECK(instrumenter_.get() != NULL);
 197    :  
 198  E :    return instrumenter_->Instrument() ? 0 : 1;
 199  E :  }
 200    :  
 201    :  bool InstrumentApp::Usage(const CommandLine* cmd_line,
 202  E :                            const base::StringPiece& message) const {
 203  E :    if (!message.empty()) {
 204  i :      ::fwrite(message.data(), 1, message.length(), err());
 205  i :      ::fprintf(err(), "\n\n");
 206    :    }
 207    :  
 208    :    ::fprintf(err(),
 209    :              kUsageFormatStr,
 210  E :              cmd_line->GetProgram().BaseName().value().c_str());
 211    :  
 212  E :    return false;
 213  E :  }
 214    :  
 215    :  }  // namespace instrument

Coverage information generated Thu Mar 26 16:15:41 2015.