Coverage for /Syzygy/instrument/instrument_app.cc

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

Coverage information generated Thu Jan 14 17:40:38 2016.