Coverage for /Syzygy/integration_tests/instrument_integration_test.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
96.8%8708990.C++test

Line-by-line coverage:

   1    :  // Copyright 2013 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    :  #include "base/environment.h"
  16    :  #include "base/files/file_enumerator.h"
  17    :  #include "base/files/file_path.h"
  18    :  #include "base/process/kill.h"
  19    :  #include "base/strings/string_util.h"
  20    :  #include "base/strings/stringprintf.h"
  21    :  #include "base/strings/utf_string_conversions.h"
  22    :  #include "base/win/pe_image.h"
  23    :  #include "base/win/scoped_com_initializer.h"
  24    :  #include "gmock/gmock.h"
  25    :  #include "gtest/gtest.h"
  26    :  #include "pcrecpp.h"  // NOLINT
  27    :  #include "syzygy/agent/asan/rtl_impl.h"
  28    :  #include "syzygy/agent/asan/runtime.h"
  29    :  #include "syzygy/block_graph/transforms/chained_basic_block_transforms.h"
  30    :  #include "syzygy/common/asan_parameters.h"
  31    :  #include "syzygy/common/indexed_frequency_data.h"
  32    :  #include "syzygy/common/unittest_util.h"
  33    :  #include "syzygy/core/disassembler_util.h"
  34    :  #include "syzygy/core/unittest_util.h"
  35    :  #include "syzygy/grinder/basic_block_util.h"
  36    :  #include "syzygy/grinder/grinder.h"
  37    :  #include "syzygy/grinder/grinders/coverage_grinder.h"
  38    :  #include "syzygy/grinder/grinders/indexed_frequency_data_grinder.h"
  39    :  #include "syzygy/grinder/grinders/profile_grinder.h"
  40    :  #include "syzygy/instrument/instrument_app.h"
  41    :  #include "syzygy/instrument/transforms/asan_transform.h"
  42    :  #include "syzygy/integration_tests/asan_page_protection_tests.h"
  43    :  #include "syzygy/integration_tests/integration_tests_dll.h"
  44    :  #include "syzygy/pe/decomposer.h"
  45    :  #include "syzygy/pe/pe_transform_policy.h"
  46    :  #include "syzygy/pe/unittest_util.h"
  47    :  #include "syzygy/poirot/minidump_processor.h"
  48    :  #include "syzygy/testing/laa.h"
  49    :  #include "syzygy/trace/agent_logger/agent_logger.h"
  50    :  #include "syzygy/trace/common/unittest_util.h"
  51    :  
  52    :  namespace integration_tests {
  53    :  
  54    :  namespace {
  55    :  
  56    :  // The exit code used by report_crash_with_protobuf_harness if the
  57    :  // exception was appropriately dispatched but did not contain a valid protobuf.
  58    :  const int kExeReportCrashWithProtobufExitCodeBadProtobuf = 97;
  59    :  
  60    :  // The exit code used by report_crash_with_protobuf_harness if the
  61    :  // exception was appropriately dispatched and contained a valid protobuf.
  62    :  const int kExeReportCrashWithProtobufExitCode = 98;
  63    :  
  64    :  // The exit code used by crash_for_exception_harness if the exception
  65    :  // was appropriately dispatched.
  66    :  const int kExeCrashForExceptionExitCode = 99;
  67    :  
  68    :  using grinder::basic_block_util::IndexedFrequencyInformation;
  69    :  using grinder::basic_block_util::IndexedFrequencyMap;
  70    :  using grinder::basic_block_util::ModuleIndexedFrequencyMap;
  71    :  using instrument::InstrumentApp;
  72    :  using trace::parser::Parser;
  73    :  typedef block_graph::BlockGraph::Block Block;
  74    :  typedef block_graph::BlockGraph::BlockMap BlockMap;
  75    :  typedef application::Application<InstrumentApp> TestApp;
  76    :  typedef grinder::CoverageData::LineExecutionCountMap LineExecutionCountMap;
  77    :  typedef grinder::CoverageData::SourceFileCoverageData SourceFileCoverageData;
  78    :  typedef grinder::CoverageData::SourceFileCoverageDataMap
  79    :      SourceFileCoverageDataMap;
  80    :  
  81    :  #define _STRINGIFY(s) #s
  82    :  #define STRINGIFY(s) _STRINGIFY(s)
  83    :  
  84    :  const char kAsanAccessViolationLog[] =
  85    :      "SyzyASAN: Caught an invalid access via an access violation exception.";
  86    :  const char kAsanHandlingException[] = "SyzyASAN: Handling an exception.";
  87    :  const char kAsanHeapBufferOverflow[] = "SyzyASAN error: heap-buffer-overflow ";
  88    :  const char kAsanCorruptHeap[] = "SyzyASAN error: corrupt-heap ";
  89    :  const char kAsanHeapUseAfterFree[] = "SyzyASAN error: heap-use-after-free ";
  90    :  const char kAsanNearNullptrAccessHeapCorruption[] =
  91    :      "SyzyASAN: Caught a near-nullptr access with heap corruption.";
  92    :  const char kAsanNearNullptrAccessNoHeapCorruption[] =
  93    :      "SyzyASAN: Ignoring a near-nullptr access without heap corruption.";
  94    :  
  95    :  // A convenience class for controlling an out of process agent_logger instance,
  96    :  // and getting the contents of its log file. Not thread safe.
  97    :  struct ScopedAgentLogger {
  98  E :    explicit ScopedAgentLogger(base::FilePath temp_dir)
  99  E :        : nul_(NULL), temp_dir_(temp_dir) {
 100  E :      agent_logger_ = testing::GetOutputRelativePath(
 101    :          L"agent_logger.exe");
 102  E :      instance_id_ = base::StringPrintf("integra%08X", ::GetCurrentProcessId());
 103  E :    }
 104    :  
 105  E :    ~ScopedAgentLogger() {
 106    :      // Clean up the temp directory if we created one.
 107  E :      if (!temp_dir_.empty())
 108  E :        base::DeleteFile(temp_dir_, true);
 109    :  
 110  E :      if (nul_) {
 111  E :        ::CloseHandle(nul_);
 112  E :        nul_ = NULL;
 113    :      }
 114  E :    }
 115    :  
 116  E :    void RunAction(const char* action, base::Process* process) {
 117  E :      DCHECK_NE(static_cast<const char*>(nullptr), action);
 118  E :      DCHECK_NE(static_cast<base::Process*>(nullptr), process);
 119    :  
 120  E :      base::CommandLine cmd_line(agent_logger_);
 121  E :      cmd_line.AppendSwitchASCII("instance-id", instance_id_);
 122  E :      cmd_line.AppendSwitchPath("minidump-dir", temp_dir_);
 123  E :      cmd_line.AppendSwitchPath("output-file", log_file_);
 124  E :      cmd_line.AppendArg(action);
 125  E :      base::LaunchOptions options;
 126  E :      options.inherit_handles = true;
 127  E :      options.stderr_handle = nul_;
 128  E :      options.stdin_handle = nul_;
 129  E :      options.stdout_handle = nul_;
 130  E :      *process = base::LaunchProcess(cmd_line, options);
 131  E :      DCHECK(process->IsValid());
 132  E :    }
 133    :  
 134  E :    void Start() {
 135  E :      DCHECK(!process_.IsValid());
 136    :  
 137  E :      if (nul_ == NULL) {
 138  E :        nul_ = CreateFile(L"NUL", GENERIC_READ | GENERIC_WRITE, 0, NULL,
 139    :                          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
 140  E :        CHECK(nul_);
 141    :      }
 142    :  
 143  E :      log_file_ = temp_dir_.Append(L"integration_test.log");
 144    :  
 145  E :      std::wstring start_event_name(L"syzygy-logger-started-");
 146  E :      start_event_name += base::ASCIIToUTF16(instance_id_);
 147  E :      base::win::ScopedHandle start_event(
 148    :          ::CreateEvent(NULL, FALSE, FALSE, start_event_name.c_str()));
 149    :  
 150  E :      RunAction("start", &process_);
 151    :  
 152  E :      ::WaitForSingleObject(start_event.Get(), INFINITE);
 153  E :    }
 154    :  
 155  E :    void Stop() {
 156  E :      DCHECK(process_.IsValid());
 157    :  
 158  E :      base::Process process;
 159  E :      RunAction("stop", &process);
 160  E :      int exit_code = 0;
 161  E :      CHECK(process.WaitForExit(&exit_code));
 162  E :      CHECK(process_.WaitForExit(&exit_code));
 163    :  
 164    :      // Read the contents of the log file.
 165  E :      if (base::PathExists(log_file_))
 166  E :        CHECK(base::ReadFileToString(log_file_, &log_contents_));
 167  E :    }
 168    :  
 169  E :    void GetLog(std::string* log) {
 170  E :      DCHECK_NE(static_cast<std::string*>(nullptr), log);
 171  E :      *log = log_contents_;
 172  E :    }
 173    :  
 174    :    // Initialized at construction.
 175    :    base::FilePath agent_logger_;
 176    :    std::string instance_id_;
 177    :  
 178    :    // Modified by Start and Stop.
 179    :    base::FilePath temp_dir_;
 180    :    base::FilePath log_file_;
 181    :    base::Process process_;
 182    :    HANDLE nul_;
 183    :  
 184    :    // Modified by Stop.
 185    :    std::string log_contents_;
 186    :  };
 187    :  
 188    :  enum AccessMode {
 189    :    ASAN_READ_ACCESS = agent::asan::ASAN_READ_ACCESS,
 190    :    ASAN_WRITE_ACCESS = agent::asan::ASAN_WRITE_ACCESS,
 191    :    ASAN_UNKNOWN_ACCESS = agent::asan::ASAN_UNKNOWN_ACCESS,
 192    :  };
 193    :  
 194    :  enum BadAccessKind {
 195    :    UNKNOWN_BAD_ACCESS = agent::asan::UNKNOWN_BAD_ACCESS,
 196    :    USE_AFTER_FREE = agent::asan::USE_AFTER_FREE,
 197    :    HEAP_BUFFER_OVERFLOW = agent::asan::HEAP_BUFFER_OVERFLOW,
 198    :    HEAP_BUFFER_UNDERFLOW = agent::asan::HEAP_BUFFER_UNDERFLOW,
 199    :    CORRUPT_BLOCK = agent::asan::CORRUPT_BLOCK,
 200    :    CORRUPT_HEAP = agent::asan::CORRUPT_HEAP,
 201    :  };
 202    :  
 203    :  // Contains the number of Asan errors reported with our callback.
 204    :  int asan_error_count;
 205    :  // Contains the last Asan error reported.
 206    :  agent::asan::AsanErrorInfo last_asan_error;
 207    :  
 208  E :  void AsanCallback(agent::asan::AsanErrorInfo* info) {
 209  E :    asan_error_count++;
 210  E :    last_asan_error = *info;
 211    :    // We want to prevent write errors from corrupting the underlying block hence
 212    :    // we stop the flow of execution by raising an exception. The faulty calls are
 213    :    // themselves wrapped in try/catch statements, and continue executing
 214    :    // afterwards. Thus, they clean up after themselves.
 215    :    //
 216    :    // In the case of block corruption we elect to allow the code to continue
 217    :    // executing so that the normal code path is taken. If we raise an exception
 218    :    // this actually prevents the AsanHeap cleanup code from continuing, and we
 219    :    // leak memory.
 220  E :    if (info->error_type != CORRUPT_BLOCK)
 221  E :      ::RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, 0, 0, NULL);
 222  E :  }
 223    :  
 224  E :  void ResetAsanErrors() {
 225  E :    asan_error_count = 0;
 226  E :  }
 227    :  
 228  E :  HMODULE GetAsanModule() {
 229  E :    HMODULE asan_module = GetModuleHandle(L"syzyasan_rtl.dll");
 230  E :    return asan_module;
 231  E :  }
 232    :  
 233  E :  void SetAsanDefaultCallBack(AsanErrorCallBack callback) {
 234    :    typedef void (WINAPI *AsanSetCallBack)(AsanErrorCallBack);
 235    :  
 236  E :    HMODULE asan_module = GetAsanModule();
 237  E :    DCHECK(asan_module != NULL);
 238    :    AsanSetCallBack set_callback = reinterpret_cast<AsanSetCallBack>(
 239  E :        ::GetProcAddress(asan_module, "asan_SetCallBack"));
 240  E :    DCHECK(set_callback != NULL);
 241    :  
 242  E :    set_callback(callback);
 243  E :  }
 244    :  
 245  E :  agent::asan::OnExceptionCallback on_exception_callback;
 246    :  
 247  i :  void DispatchOnExceptionCallback(EXCEPTION_POINTERS* e) {
 248  i :    if (!on_exception_callback.is_null())
 249  i :      on_exception_callback.Run(e);
 250  i :  }
 251    :  
 252  E :  void SetOnExceptionCallback(agent::asan::OnExceptionCallback callback) {
 253    :    typedef void (*OnExceptionCallback)(EXCEPTION_POINTERS*);
 254    :    typedef void (WINAPI *SetOnExceptionCallback)(OnExceptionCallback);
 255    :  
 256  E :    HMODULE asan_module = GetAsanModule();
 257  E :    DCHECK(asan_module != NULL);
 258    :    SetOnExceptionCallback set_callback =
 259    :        reinterpret_cast<SetOnExceptionCallback>(
 260  E :            ::GetProcAddress(asan_module, "asan_SetOnExceptionCallback"));
 261  E :    DCHECK(set_callback != NULL);
 262    :  
 263  E :    if (callback.is_null()) {
 264  i :      set_callback(nullptr);
 265  i :      on_exception_callback.Reset();
 266  i :    } else {
 267  E :      set_callback(&DispatchOnExceptionCallback);
 268  E :      on_exception_callback = callback;
 269    :    }
 270  E :  }
 271    :  
 272  E :  agent::asan::AsanRuntime* GetActiveAsanRuntime() {
 273  E :    HMODULE asan_module = GetAsanModule();
 274  E :    DCHECK(asan_module != NULL);
 275    :  
 276    :    typedef agent::asan::AsanRuntime* (WINAPI *AsanGetActiveRuntimePtr)();
 277    :    AsanGetActiveRuntimePtr asan_get_active_runtime =
 278    :        reinterpret_cast<AsanGetActiveRuntimePtr>(
 279  E :        ::GetProcAddress(asan_module, "asan_GetActiveRuntime"));
 280  E :    DCHECK_NE(reinterpret_cast<AsanGetActiveRuntimePtr>(NULL),
 281  E :              asan_get_active_runtime);
 282    :  
 283  E :    return (*asan_get_active_runtime)();
 284  E :  }
 285    :  
 286    :  // Filters non-continuable exceptions in the given module.
 287    :  int FilterExceptionsInModule(HMODULE module,
 288    :                               unsigned int code,
 289  E :                               struct _EXCEPTION_POINTERS* ep) {
 290    :    // Do a basic sanity check on the input parameters.
 291    :    if (module == NULL ||
 292    :        code != EXCEPTION_NONCONTINUABLE_EXCEPTION ||
 293    :        ep == NULL ||
 294  E :        ep->ContextRecord == NULL ||
 295    :        ep->ExceptionRecord == NULL) {
 296  i :      return EXCEPTION_CONTINUE_SEARCH;
 297    :    }
 298    :  
 299    :    // Get the module extents in memory.
 300  E :    base::win::PEImage image(module);
 301  E :    uint8_t* module_start = reinterpret_cast<uint8_t*>(module);
 302    :    uint8_t* module_end =
 303  E :        module_start + image.GetNTHeaders()->OptionalHeader.SizeOfImage;
 304    :  
 305    :    // Filter exceptions where the return address originates from within the
 306    :    // instrumented module.
 307  E :    uint8_t** ebp = reinterpret_cast<uint8_t**>(ep->ContextRecord->Ebp);
 308  E :    uint8_t* ret = ebp[1];
 309  E :    if (ret >= module_start && ret < module_end)
 310  E :      return EXCEPTION_EXECUTE_HANDLER;
 311    :  
 312  i :    return EXCEPTION_CONTINUE_SEARCH;
 313  E :  }
 314    :  
 315    :  typedef std::map<std::string, FARPROC> ImportMap;
 316    :  bool OnImport(const base::win::PEImage& image,
 317    :                LPCSTR module,
 318    :                DWORD ordinal,
 319    :                LPCSTR name,
 320    :                DWORD hint,
 321    :                PIMAGE_THUNK_DATA iat,
 322  E :                PVOID cookie) {
 323  E :    if (name == nullptr) {
 324    :      // This is an ordinal import.
 325  E :      return true;
 326    :    }
 327    :  
 328  E :    ImportMap* imports = reinterpret_cast<ImportMap*>(cookie);
 329  E :    imports->insert(
 330    :        std::make_pair(name, reinterpret_cast<FARPROC>(iat->u1.Function)));
 331  E :    return true;
 332  E :  }
 333    :  
 334  E :  bool GetModuleNamedImports(HMODULE module, ImportMap* imports) {
 335  E :    base::win::PEImage image(module);
 336  E :    if (!image.VerifyMagic())
 337  i :      return false;
 338    :  
 339  E :    return image.EnumAllImports(OnImport, imports);
 340  E :  }
 341    :  
 342    :  class TestingProfileGrinder : public grinder::grinders::ProfileGrinder {
 343    :   public:
 344    :    // Expose for testing.
 345    :    typedef grinder::grinders::ProfileGrinder::InvocationNodeMap
 346    :        InvocationNodeMap;
 347    :    typedef grinder::grinders::ProfileGrinder::ModuleInformationSet
 348    :        ModuleInformationSet;
 349    :  
 350    :    using grinder::grinders::ProfileGrinder::PartData;
 351    :    using grinder::grinders::ProfileGrinder::PartDataMap;
 352    :    using grinder::grinders::ProfileGrinder::PartKey;
 353    :  
 354    :    using grinder::grinders::ProfileGrinder::modules_;
 355    :    using grinder::grinders::ProfileGrinder::parts_;
 356    :  };
 357    :  
 358    :  class LenientInstrumentAppIntegrationTest : public testing::PELibUnitTest {
 359    :   public:
 360    :    typedef testing::PELibUnitTest Super;
 361    :  
 362    :    // A callback that gets hooked up to catch exceptions in the RTL.
 363  i :    MOCK_METHOD1(OnExceptionCallback, void(EXCEPTION_POINTERS*));
 364    :  
 365    :    LenientInstrumentAppIntegrationTest()
 366  E :        : cmd_line_(base::FilePath(L"instrument.exe")),
 367  E :          test_impl_(test_app_.implementation()),
 368  E :          image_layout_(&block_graph_),
 369  E :          get_my_rva_(NULL) {
 370  E :    }
 371    :  
 372  E :    void SetUp() {
 373  E :      Super::SetUp();
 374    :  
 375    :      // Several of the tests generate progress and (deliberate) error messages
 376    :      // that would otherwise clutter the unittest output.
 377  E :      logging::SetMinLogLevel(logging::LOG_FATAL);
 378    :  
 379    :      // Setup the IO streams.
 380  E :      this->CreateTemporaryDir(&temp_dir_);
 381  E :      stdin_path_ = temp_dir_.Append(L"NUL");
 382  E :      stdout_path_ = temp_dir_.Append(L"stdout.txt");
 383  E :      stderr_path_ = temp_dir_.Append(L"stderr.txt");
 384  E :      InitStreams(stdin_path_, stdout_path_, stderr_path_);
 385    :  
 386    :      // Initialize the (potential) input and output path values.
 387    :      base::FilePath abs_input_dll_path_ =
 388  E :          testing::GetExeRelativePath(testing::kIntegrationTestsDllName);
 389  E :      input_dll_path_ = testing::GetRelativePath(abs_input_dll_path_);
 390  E :      output_dll_path_ = temp_dir_.Append(input_dll_path_.BaseName());
 391    :  
 392    :      // Initialize call_service output directory for produced trace files.
 393  E :      traces_dir_ = temp_dir_.Append(L"traces");
 394    :  
 395    :      // Initialize call_service session id.
 396  E :      service_.SetEnvironment();
 397    :  
 398  E :      ASSERT_NO_FATAL_FAILURE(ConfigureTestApp(&test_app_));
 399  E :    }
 400    :  
 401  E :    void TearDown() {
 402    :      // We need to release the module handle before Super::TearDown, otherwise
 403    :      // the library file cannot be deleted.
 404  E :      module_.Release();
 405  E :      Super::TearDown();
 406  E :    }
 407    :  
 408    :    // Points the application at the fixture's command-line and IO streams.
 409    :    template<typename TestAppType>
 410  E :    void ConfigureTestApp(TestAppType* test_app) {
 411  E :      test_app->set_command_line(&cmd_line_);
 412  E :      test_app->set_in(in());
 413  E :      test_app->set_out(out());
 414  E :      test_app->set_err(err());
 415  E :    }
 416    :  
 417  E :    void StartService() {
 418  E :      service_.Start(traces_dir_);
 419  E :    }
 420    :  
 421  E :    void StopService() {
 422  E :      service_.Stop();
 423  E :    }
 424    :  
 425  E :    void UnloadDll() {
 426  E :      module_.Reset(NULL);
 427  E :    }
 428    :  
 429    :    // Runs an instrumentation pass in the given mode and validates that the
 430    :    // resulting output DLL loads.
 431  E :    void EndToEndTest(const std::string& mode) {
 432  E :      cmd_line_.AppendSwitchPath("input-image", input_dll_path_);
 433  E :      cmd_line_.AppendSwitchPath("output-image", output_dll_path_);
 434  E :      cmd_line_.AppendSwitchASCII("mode", mode);
 435    :  
 436    :      // Create the instrumented DLL.
 437  E :      application::Application<instrument::InstrumentApp> app;
 438  E :      ASSERT_NO_FATAL_FAILURE(ConfigureTestApp(&app));
 439  E :      ASSERT_EQ(0, app.Run());
 440    :  
 441    :      // Validate that the test dll loads post instrumentation.
 442  E :      ASSERT_NO_FATAL_FAILURE(LoadTestDll(output_dll_path_, &module_));
 443  E :    }
 444    :  
 445    :    // Invoke a test function inside test_dll by addressing it with a test id.
 446    :    // Returns the value resulting from the test function execution.
 447  E :    unsigned int InvokeTestDllFunction(testing::EndToEndTestId test) {
 448    :      // Load the exported 'function_name' function.
 449    :      typedef unsigned int (CALLBACK* TestDllFuncs)(unsigned int);
 450    :      TestDllFuncs func = reinterpret_cast<TestDllFuncs>(
 451  E :          ::GetProcAddress(module_, "EndToEndTest"));
 452  E :      DCHECK(func != NULL);
 453    :  
 454    :      // Invoke it, and returns its value.
 455  E :      return func(test);
 456  E :    }
 457    :  
 458    :    int RunOutOfProcessFunction(const base::string16& harness_name,
 459    :                                testing::EndToEndTestId test,
 460  E :                                bool expect_exception) {
 461  E :      base::FilePath harness = testing::GetExeRelativePath(harness_name.c_str());
 462  E :      base::CommandLine cmd_line(harness);
 463  E :      cmd_line.AppendSwitchASCII("test", base::StringPrintf("%d", test));
 464  E :      cmd_line.AppendSwitchPath("dll", output_dll_path_);
 465  E :      if (expect_exception)
 466  E :        cmd_line.AppendSwitch("expect-exception");
 467    :  
 468  E :      base::LaunchOptions options;
 469  E :      base::Process process = base::LaunchProcess(cmd_line, options);
 470  E :      EXPECT_TRUE(process.IsValid());
 471    :  
 472  E :      int exit_code = 0;
 473  E :      EXPECT_TRUE(process.WaitForExit(&exit_code));
 474  E :      return exit_code;
 475  E :    }
 476    :  
 477    :    // Runs an asan error check in an external process, invoking the test via the
 478    :    // integration test harness.
 479    :    void OutOfProcessAsanErrorCheck(testing::EndToEndTestId test,
 480    :                                    bool expect_exception,
 481  E :                                    std::string* log) {
 482  E :      DCHECK_NE(static_cast<std::string*>(nullptr), log);
 483    :  
 484    :      // If running under the debugger then don't do this test. The debugger's
 485    :      // exception handler prevents this from completing as expected.
 486  E :      if (expect_exception && ::IsDebuggerPresent())
 487  i :        return;
 488    :  
 489  E :      ScopedAgentLogger logger(temp_dir_);
 490  E :      logger.Start();
 491    :  
 492  E :      std::unique_ptr<base::Environment> env(base::Environment::Create());
 493  E :      CHECK_NE(static_cast<base::Environment*>(nullptr), env.get());
 494    :  
 495    :      // Update the instance ID environment variable to specifically aim the
 496    :      // Asan RTL to the agent logger we are running. We have to be careful not
 497    :      // to influence other RPC settings so as not to break coverage support.
 498  E :      base::FilePath agent = testing::GetExeRelativePath(L"syzyasan_rtl.dll");
 499  E :      std::string instance_id = base::WideToUTF8(agent.value());
 500  E :      instance_id.append(",");
 501  E :      instance_id.append(logger.instance_id_);
 502  E :      bool had_instance_id = false;
 503  E :      std::string orig_instance_id;
 504  E :      had_instance_id = env->GetVar(kSyzygyRpcInstanceIdEnvVar,
 505    :                                    &orig_instance_id);
 506  E :      if (had_instance_id) {
 507  E :        instance_id.append(";");
 508  E :        instance_id.append(orig_instance_id);
 509    :      }
 510  E :      env->SetVar(kSyzygyRpcInstanceIdEnvVar, instance_id);
 511    :  
 512  E :      int exit_code = RunOutOfProcessFunction(L"integration_tests_harness.exe",
 513    :                                              test, expect_exception);
 514  E :      EXPECT_EQ(0, exit_code);
 515  E :      logger.Stop();
 516    :  
 517    :      // Restore the instance ID variable to its original state.
 518  E :      if (had_instance_id) {
 519  E :        env->SetVar(kSyzygyRpcInstanceIdEnvVar, orig_instance_id);
 520  E :      } else {
 521  i :        env->UnSetVar(kSyzygyRpcInstanceIdEnvVar);
 522    :      }
 523    :  
 524  E :      logger.GetLog(log);
 525  E :    }
 526    :  
 527    :    void OutOfProcessAsanErrorCheckAndValidateLog(
 528    :        testing::EndToEndTestId test,
 529    :        bool expect_exception,
 530    :        const base::StringPiece& log_message_1,
 531  E :        const base::StringPiece& log_message_2) {
 532    :      // If running under the debugger then don't do this test. The debugger's
 533    :      // exception handler prevents this from completing as expected.
 534  E :      if (expect_exception && ::IsDebuggerPresent())
 535  i :        return;
 536    :  
 537  E :      std::string log;
 538  E :      OutOfProcessAsanErrorCheck(test, expect_exception, &log);
 539    :  
 540  E :      if (!expect_exception)
 541  E :        return;
 542    :      // Check the log for any messages that are expected.
 543  E :      if (!log_message_1.empty()) {
 544  E :        EXPECT_NE(std::string::npos, log.find(log_message_1.as_string()))
 545    :            << "Expected to find '" << log_message_1 << "' in logs: " << log;
 546    :      }
 547  E :      if (!log_message_2.empty()) {
 548  E :        EXPECT_NE(std::string::npos, log.find(log_message_2.as_string()))
 549    :            << "Expected to find '" << log_message_2 << "' in logs: " << log;
 550    :      }
 551  E :    }
 552    :  
 553  E :    void CheckTestDllImportsRedirected() {
 554  E :      HMODULE rtl = GetAsanModule();
 555  E :      ASSERT_NE(static_cast<HMODULE>(nullptr), rtl);
 556    :  
 557  E :      ImportMap imports;
 558  E :      ASSERT_TRUE(GetModuleNamedImports(module_, &imports));
 559  E :      for (auto pair : imports) {
 560  E :        const std::string& name = pair.first;
 561  E :        const FARPROC imported_fn = pair.second;
 562    :  
 563    :        // Is this an instrumentation import?
 564    :        const bool is_asan_fn =
 565  E :            base::StartsWith(name, "asan_", base::CompareCase::SENSITIVE);
 566  E :        if (!is_asan_fn)
 567  E :          continue;
 568    :  
 569    :        // Retrieve the corresponding export on the instrumentation DLL.
 570  E :        FARPROC rtl_export_fn = ::GetProcAddress(rtl, name.c_str());
 571    :  
 572    :        // Is it a memory accessor?
 573    :        const bool is_asan_check_fn =
 574  E :            base::StartsWith(name, "asan_check", base::CompareCase::SENSITIVE);
 575  E :        if (is_asan_check_fn) {
 576    :          // Memory acessors in the dynamic RTL must be redirected after first
 577    :          // use of the function. If the dynamic RTL doesn't redirect the imports
 578    :          // everything will still work, just terribly slowly.
 579  E :          ASSERT_NE(rtl_export_fn, imported_fn);
 580  E :        } else {
 581  E :          ASSERT_EQ(rtl_export_fn, imported_fn);
 582    :        }
 583  E :      }
 584  E :    }
 585    :  
 586  E :    void EndToEndCheckTestDll() {
 587    :      // Validate that behavior is unchanged after instrumentation.
 588  E :      EXPECT_EQ(0xfff80200, InvokeTestDllFunction(testing::kArrayComputation1));
 589  E :      EXPECT_EQ(0x00000200, InvokeTestDllFunction(testing::kArrayComputation2));
 590  E :    }
 591    :  
 592    :    bool AsanErrorCheck(testing::EndToEndTestId test,
 593    :                        BadAccessKind kind,
 594    :                        AccessMode mode,
 595    :                        size_t size,
 596    :                        size_t max_tries,
 597  E :                        bool unload) {
 598    :      // A small selection of tests can fail due to hash collisions. These are
 599    :      // run repeatedly and expected to pass at least once. Every other test is
 600    :      // run with max_tries == 1.
 601  E :      if (max_tries != 1) {
 602    :        // Ensure that only the desired tests are being run with retries. This is
 603    :        // a second layer of safety to make sure that flaky tests aren't simply
 604    :        // being hidden.
 605  E :        EXPECT_TRUE(test == testing::kAsanCorruptBlock ||
 606    :                    test == testing::kAsanCorruptBlockInQuarantine);
 607    :      }
 608    :  
 609  E :      ResetAsanErrors();
 610  E :      EXPECT_NO_FATAL_FAILURE(SetAsanDefaultCallBack(AsanCallback));
 611    :  
 612    :      // Hook up the OnException callback to the test fixture.
 613  E :      SetOnExceptionCallback(base::Bind(
 614    :          &LenientInstrumentAppIntegrationTest::OnExceptionCallback,
 615    :          base::Unretained(this)));
 616    :  
 617  E :      for (size_t i = 0; i < max_tries; ++i) {
 618  E :        InvokeTestDllFunction(test);
 619  E :        if (unload)
 620  E :          UnloadDll();
 621    :  
 622    :        // If this appears to have failed then retry it for all but the last
 623    :        // attempt. Some tests have a non-zero chance of failure, but their
 624    :        // chances of failing repeatedly are infinitesimally small.
 625  E :        if (asan_error_count == 0 && i + 1 < max_tries) {
 626    :          // If the module was unloaded and the test is retrying, then reload it.
 627  i :          if (unload)
 628  i :            EXPECT_NO_FATAL_FAILURE(LoadTestDll(output_dll_path_, &module_));
 629  i :          continue;
 630    :        }
 631    :  
 632    :        if (asan_error_count == 0 ||
 633    :            last_asan_error.error_type != kind ||
 634  E :            last_asan_error.access_mode != mode ||
 635    :            last_asan_error.access_size != size) {
 636  i :          return false;
 637    :        }
 638  E :        break;
 639  i :      }
 640    :  
 641    :      // Clear any expectations on this fixture.
 642  E :      testing::Mock::VerifyAndClearExpectations(this);
 643    :  
 644  E :      return true;
 645  E :    }
 646    :  
 647    :    bool FilteredAsanErrorCheck(testing::EndToEndTestId test,
 648    :                                BadAccessKind kind,
 649    :                                AccessMode mode,
 650    :                                size_t size,
 651    :                                size_t max_tries,
 652  i :                                bool unload) {
 653  i :      __try {
 654  i :        return AsanErrorCheck(test, kind, mode, size, max_tries, unload);
 655  i :      } __except (FilterExceptionsInModule(module_,  // NOLINT
 656    :                                           GetExceptionCode(),
 657    :                                           GetExceptionInformation())) {
 658    :        // If the exception is of the expected type and originates from the
 659    :        // instrumented module, then we indicate that no Asan error was
 660    :        // detected.
 661  i :        return false;
 662    :      }
 663  i :    }
 664    :  
 665  E :    void AsanErrorCheckTestDll() {
 666  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead8BufferOverflow,
 667    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 668  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead16BufferOverflow,
 669    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 2, 1, false));
 670  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead32BufferOverflow,
 671    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 4, 1, false));
 672  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead64BufferOverflow,
 673    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 8, 1, false));
 674    :  
 675  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead8BufferUnderflow,
 676    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 677  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead16BufferUnderflow,
 678    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 2, 1, false));
 679  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead32BufferUnderflow,
 680    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 4, 1, false));
 681  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead64BufferUnderflow,
 682    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 8, 1, false));
 683    :  
 684  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite8BufferOverflow,
 685    :          HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
 686  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite16BufferOverflow,
 687    :          HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 2, 1, false));
 688  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite32BufferOverflow,
 689    :          HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 4, 1, false));
 690  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite64BufferOverflow,
 691    :          HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 8, 1, false));
 692    :  
 693  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite8BufferUnderflow,
 694    :          HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
 695  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite16BufferUnderflow,
 696    :          HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 2, 1, false));
 697  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite32BufferUnderflow,
 698    :          HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 4, 1, false));
 699  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite64BufferUnderflow,
 700    :          HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 8, 1, false));
 701    :  
 702  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead8UseAfterFree,
 703    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
 704  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead16UseAfterFree,
 705    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 2, 1, false));
 706  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead32UseAfterFree,
 707    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 4, 1, false));
 708  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead64UseAfterFree,
 709    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 8, 1, false));
 710    :  
 711  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite8UseAfterFree,
 712    :          USE_AFTER_FREE, ASAN_WRITE_ACCESS, 1, 1, false));
 713  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite16UseAfterFree,
 714    :          USE_AFTER_FREE, ASAN_WRITE_ACCESS, 2, 1, false));
 715  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite32UseAfterFree,
 716    :          USE_AFTER_FREE, ASAN_WRITE_ACCESS, 4, 1, false));
 717  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite64UseAfterFree,
 718    :          USE_AFTER_FREE, ASAN_WRITE_ACCESS, 8, 1, false));
 719  E :    }
 720    :  
 721  E :    void AsanErrorCheckSampledAllocations() {
 722    :      // This assumes we have a 50% allocation sampling rate.
 723    :  
 724    :      // Run Asan tests over and over again until we've done enough of them. We
 725    :      // only check the read operations as the writes may actually cause
 726    :      // corruption if not caught.
 727  E :      size_t good = 0;
 728  E :      size_t test = 0;
 729  E :      while (test < 1000) {
 730  E :        good += FilteredAsanErrorCheck(testing::kAsanRead8BufferOverflow,
 731    :            HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false) ? 1 : 0;
 732  E :        good += FilteredAsanErrorCheck(testing::kAsanRead16BufferOverflow,
 733    :            HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 2, 1, false) ? 1 : 0;
 734  E :        good += FilteredAsanErrorCheck(testing::kAsanRead32BufferOverflow,
 735    :            HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 4, 1, false) ? 1 : 0;
 736  E :        good += FilteredAsanErrorCheck(testing::kAsanRead64BufferOverflow,
 737    :            HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 8, 1, false) ? 1 : 0;
 738  E :        test += 4;
 739    :  
 740  E :        good += FilteredAsanErrorCheck(testing::kAsanRead8BufferUnderflow,
 741    :            HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false) ? 1 : 0;
 742  E :        good += FilteredAsanErrorCheck(testing::kAsanRead16BufferUnderflow,
 743    :            HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 2, 1, false) ? 1 : 0;
 744  E :        good += FilteredAsanErrorCheck(testing::kAsanRead32BufferUnderflow,
 745    :            HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 4, 1, false) ? 1 : 0;
 746  E :        good += FilteredAsanErrorCheck(testing::kAsanRead64BufferUnderflow,
 747    :            HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 8, 1, false) ? 1 : 0;
 748  E :        test += 4;
 749  E :      }
 750    :  
 751    :      // We expect half of the bugs to have been found, as the allocations are
 752    :      // subsampled. With 1000 allocations this gives us 10 nines of confidence
 753    :      // that the detection rate will be within 50 +/- 10%.
 754  E :      EXPECT_LE(4 * test / 10, good);
 755  E :      EXPECT_GE(6 * test / 10, good);
 756  E :    }
 757    :  
 758  E :    void AsanErrorCheckInterceptedFunctions() {
 759  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemsetOverflow,
 760    :          HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
 761  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemsetUnderflow,
 762    :          HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
 763  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemsetUseAfterFree,
 764    :          USE_AFTER_FREE, ASAN_WRITE_ACCESS, 1, 1, false));
 765  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemchrOverflow,
 766    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 767  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemchrUnderflow,
 768    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 769  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemchrUseAfterFree,
 770    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
 771  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemmoveReadOverflow,
 772    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 773  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemmoveReadUnderflow,
 774    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 775    :      // In this test both buffers passed to memmove have been freed, but as the
 776    :      // interceptor starts by checking the source buffer this use after free is
 777    :      // seen as an invalid read access.
 778  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemmoveUseAfterFree,
 779    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
 780  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemmoveWriteOverflow,
 781    :          HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
 782  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemmoveWriteUnderflow,
 783    :          HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
 784  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemcpyReadOverflow,
 785    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 786  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemcpyReadUnderflow,
 787    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 788  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemcpyUseAfterFree,
 789    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
 790  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemcpyWriteOverflow,
 791    :          HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
 792  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemcpyWriteUnderflow,
 793    :          HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
 794    :  
 795  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrlenOverflow,
 796    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 797  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrlenUnderflow,
 798    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 799  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrlenUseAfterFree,
 800    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
 801  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrnlenOverflow,
 802    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 803  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrnlenUnderflow,
 804    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 805  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrnlenUseAfterFree,
 806    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
 807    :      // TODO(chrisha): These should actually be indicated as 2 byte reads. This
 808    :      // needs to be fixed in the runtime.
 809  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcsnlenOverflow,
 810    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 811  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcsnlenUnderflow,
 812    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 813  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcsnlenUseAfterFree,
 814    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
 815  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrrchrOverflow,
 816    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 817  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrrchrUnderflow,
 818    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 819  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrrchrUseAfterFree,
 820    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
 821  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcsrchrOverflow,
 822    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 823  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcsrchrUnderflow,
 824    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 825  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcsrchrUseAfterFree,
 826    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
 827  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcschrOverflow,
 828    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 829  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcschrUnderflow,
 830    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 831  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcschrUseAfterFree,
 832    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
 833  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcsstrKeysOverflow,
 834    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 835  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncpySrcOverflow,
 836    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 837  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncpySrcUnderflow,
 838    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 839  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncpySrcUseAfterFree,
 840    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
 841  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncpyDstOverflow,
 842    :          HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
 843  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncpyDstUnderflow,
 844    :          HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
 845  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncpyDstUseAfterFree,
 846    :          USE_AFTER_FREE, ASAN_WRITE_ACCESS, 1, 1, false));
 847  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncatSuffixOverflow,
 848    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 849  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncatSuffixUnderflow,
 850    :          HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 851  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncatSuffixUseAfterFree,
 852    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
 853  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncatDstOverflow,
 854    :          HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
 855  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncatDstUnderflow,
 856    :          HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
 857  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncatDstUseAfterFree,
 858    :          USE_AFTER_FREE, ASAN_WRITE_ACCESS, 1, 1, false));
 859    :  
 860  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanReadFileOverflow,
 861    :          HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
 862  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanReadFileUseAfterFree,
 863    :          USE_AFTER_FREE, ASAN_WRITE_ACCESS, 1, 1, false));
 864  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWriteFileOverflow,
 865    :          HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
 866  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanWriteFileUseAfterFree,
 867    :          USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
 868    :  
 869  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanCorruptBlock,
 870    :          CORRUPT_BLOCK, ASAN_UNKNOWN_ACCESS, 0, 10, false));
 871    :  
 872    :      // We need to force the module to unload so that the quarantine gets
 873    :      // cleaned up and fires off the error we're looking for.
 874  E :      EXPECT_TRUE(AsanErrorCheck(testing::kAsanCorruptBlockInQuarantine,
 875    :          CORRUPT_BLOCK, ASAN_UNKNOWN_ACCESS, 0, 10, true));
 876    :  
 877  E :      OutOfProcessAsanErrorCheckAndValidateLog(
 878    :          testing::kAsanMemcmpAccessViolation, true, kAsanHandlingException,
 879    :          nullptr);
 880  E :    }
 881    :  
 882  E :    void AsanLargeBlockHeapTests(bool expect_exception) {
 883  E :      OutOfProcessAsanErrorCheckAndValidateLog(
 884    :          testing::kAsanReadLargeAllocationTrailerBeforeFree, expect_exception,
 885    :          kAsanAccessViolationLog, kAsanHeapBufferOverflow);
 886  E :      OutOfProcessAsanErrorCheckAndValidateLog(
 887    :          testing::kAsanReadLargeAllocationBodyAfterFree, true,
 888    :          kAsanAccessViolationLog, kAsanHeapUseAfterFree);
 889  E :    }
 890    :  
 891    :    void AsanZebraHeapTest(bool enabled);
 892    :  
 893  E :    void BBEntryInvokeTestDll() {
 894  E :      EXPECT_EQ(42, InvokeTestDllFunction(testing::kBBEntryCallOnce));
 895  E :      EXPECT_EQ(42, InvokeTestDllFunction(testing::kBBEntryCallTree));
 896  E :      EXPECT_EQ(42, InvokeTestDllFunction(testing::kBBEntryCallRecursive));
 897  E :    }
 898    :  
 899  E :    void ProfileInvokeTestDll() {
 900  E :      EXPECT_EQ(5, InvokeTestDllFunction(testing::kProfileCallExport));
 901    :      // Save the RVA of one of the invoked functions for testing later.
 902  E :      get_my_rva_ = InvokeTestDllFunction(testing::kProfileGetMyRVA);
 903    :  
 904    :      // The profiler will record the address of the first instruction of the
 905    :      // original function, which is six bytes past the start of the function
 906    :      // as seen by itself post-instrumentation.
 907  E :      get_my_rva_ += 6;
 908  E :    }
 909    :  
 910    :    uint32_t ProfileInvokeGetRVA() {
 911    :      return InvokeTestDllFunction(testing::kProfileGetMyRVA);
 912    :    }
 913    :  
 914  E :    void QueueTraces(Parser* parser) {
 915  E :      DCHECK(parser != NULL);
 916    :  
 917    :      // Queue up the trace file(s) we engendered.
 918  E :      base::FileEnumerator enumerator(traces_dir_,
 919    :                                      false,
 920    :                                      base::FileEnumerator::FILES);
 921  E :      while (true) {
 922  E :        base::FilePath trace_file = enumerator.Next();
 923  E :        if (trace_file.empty())
 924  E :          break;
 925  E :        ASSERT_TRUE(parser->OpenTraceFile(trace_file));
 926  E :      }
 927  E :    }
 928    :  
 929  E :    const Block* FindBlockWithName(std::string name) {
 930  E :      const BlockMap& blocks = block_graph_.blocks();
 931  E :      BlockMap::const_iterator block_iter = blocks.begin();
 932  E :      for (; block_iter != blocks.end(); ++block_iter) {
 933  E :        const Block& block = block_iter->second;
 934  E :        if (block.type() != block_graph::BlockGraph::CODE_BLOCK)
 935  E :          continue;
 936  E :        if (block.name().compare(name) == 0)
 937  E :          return &block;
 938  E :      }
 939  i :      return NULL;
 940  E :    }
 941    :  
 942    :    int GetBlockFrequency(const IndexedFrequencyMap& frequencies,
 943  E :                          const Block* block) {
 944  E :      DCHECK(block != NULL);
 945    :      IndexedFrequencyMap::const_iterator entry =
 946  E :          frequencies.find(std::make_pair(block->addr(), 0));
 947  E :      if (entry == frequencies.end())
 948  i :        return 0;
 949  E :      return entry->second;
 950  E :    }
 951    :  
 952    :    void ExpectFunctionFrequency(const IndexedFrequencyMap& frequencies,
 953    :                                 const char* function_name,
 954  E :                                 int expected_frequency) {
 955  E :      DCHECK(function_name != NULL);
 956  E :      const Block* block = FindBlockWithName(function_name);
 957  E :      ASSERT_TRUE(block != NULL);
 958  E :      int exec_frequency = GetBlockFrequency(frequencies, block);
 959  E :      EXPECT_EQ(expected_frequency, exec_frequency);
 960  E :    }
 961    :  
 962  E :    void DecomposeImage() {
 963    :      // Decompose the DLL.
 964  E :      pe_image_.Init(input_dll_path_);
 965  E :      pe::Decomposer decomposer(pe_image_);
 966  E :      ASSERT_TRUE(decomposer.Decompose(&image_layout_));
 967  E :    }
 968    :  
 969  E :    void BBEntryCheckTestDll() {
 970  E :      Parser parser;
 971  E :      grinder::grinders::IndexedFrequencyDataGrinder grinder;
 972    :  
 973    :      // Initialize trace parser.
 974  E :      ASSERT_TRUE(parser.Init(&grinder));
 975  E :      grinder.SetParser(&parser);
 976    :  
 977    :      // Add generated traces to the parser.
 978  E :      QueueTraces(&parser);
 979    :  
 980    :      // Parse all traces.
 981  E :      ASSERT_TRUE(parser.Consume());
 982  E :      ASSERT_FALSE(parser.error_occurred());
 983  E :      ASSERT_TRUE(grinder.Grind());
 984    :  
 985    :      // Retrieve basic block count information.
 986  E :      const ModuleIndexedFrequencyMap& module_entry_count =
 987    :          grinder.frequency_data_map();
 988  E :      ASSERT_EQ(1u, module_entry_count.size());
 989    :  
 990    :      ModuleIndexedFrequencyMap::const_iterator entry_iter =
 991  E :          module_entry_count.begin();
 992  E :      const IndexedFrequencyInformation& info = entry_iter->second;
 993  E :      const IndexedFrequencyMap& entry_count = info.frequency_map;
 994    :  
 995    :      // Decompose the output image.
 996  E :      ASSERT_NO_FATAL_FAILURE(DecomposeImage());
 997    :  
 998    :      // Validate function entry counts.
 999  E :      ASSERT_NO_FATAL_FAILURE(
1000    :          ExpectFunctionFrequency(entry_count, "BBEntryCallOnce", 1));
1001  E :      ASSERT_NO_FATAL_FAILURE(
1002    :          ExpectFunctionFrequency(entry_count, "BBEntryCallTree", 1));
1003  E :      ASSERT_NO_FATAL_FAILURE(
1004    :          ExpectFunctionFrequency(entry_count, "BBEntryFunction1", 4));
1005  E :      ASSERT_NO_FATAL_FAILURE(
1006    :          ExpectFunctionFrequency(entry_count, "BBEntryFunction2", 2));
1007  E :      ASSERT_NO_FATAL_FAILURE(
1008    :          ExpectFunctionFrequency(entry_count, "BBEntryFunction3", 1));
1009  E :      ASSERT_NO_FATAL_FAILURE(
1010    :          ExpectFunctionFrequency(entry_count, "BBEntryCallRecursive", 1));
1011  E :      ASSERT_NO_FATAL_FAILURE(
1012    :          ExpectFunctionFrequency(entry_count, "BBEntryFunctionRecursive", 42));
1013  E :    }
1014    :  
1015  E :    void BranchCheckTestDll() {
1016  E :      Parser parser;
1017  E :      grinder::grinders::IndexedFrequencyDataGrinder grinder;
1018    :  
1019    :      // Initialize trace parser.
1020  E :      ASSERT_TRUE(parser.Init(&grinder));
1021  E :      grinder.SetParser(&parser);
1022    :  
1023    :      // Add generated traces to the parser.
1024  E :      QueueTraces(&parser);
1025    :  
1026    :      // Parse all traces.
1027  E :      ASSERT_TRUE(parser.Consume());
1028  E :      ASSERT_FALSE(parser.error_occurred());
1029  E :      ASSERT_TRUE(grinder.Grind());
1030    :  
1031    :      // Retrieve basic block count information.
1032  E :      const grinder::basic_block_util::ModuleIndexedFrequencyMap& module_map =
1033    :          grinder.frequency_data_map();
1034  E :      ASSERT_EQ(1u, module_map.size());
1035    :  
1036  E :      ModuleIndexedFrequencyMap::const_iterator entry_iter = module_map.begin();
1037  E :      const IndexedFrequencyInformation& information = entry_iter->second;
1038  E :      const IndexedFrequencyMap& frequency_map = information.frequency_map;
1039    :  
1040    :      // Decompose the output image.
1041  E :      ASSERT_NO_FATAL_FAILURE(DecomposeImage());
1042    :  
1043    :      // Validate function entry counts.
1044  E :      ASSERT_NO_FATAL_FAILURE(
1045    :          ExpectFunctionFrequency(frequency_map, "BBEntryCallOnce", 1));
1046  E :      ASSERT_NO_FATAL_FAILURE(
1047    :          ExpectFunctionFrequency(frequency_map, "BBEntryCallTree", 1));
1048  E :      ASSERT_NO_FATAL_FAILURE(
1049    :          ExpectFunctionFrequency(frequency_map, "BBEntryFunction1", 4));
1050  E :      ASSERT_NO_FATAL_FAILURE(
1051    :          ExpectFunctionFrequency(frequency_map, "BBEntryFunction2", 2));
1052  E :      ASSERT_NO_FATAL_FAILURE(
1053    :          ExpectFunctionFrequency(frequency_map, "BBEntryFunction3", 1));
1054  E :      ASSERT_NO_FATAL_FAILURE(
1055    :          ExpectFunctionFrequency(frequency_map, "BBEntryCallRecursive", 1));
1056  E :      ASSERT_NO_FATAL_FAILURE(
1057    :          ExpectFunctionFrequency(frequency_map, "BBEntryFunctionRecursive", 42));
1058  E :    }
1059    :  
1060  E :    bool GetLineInfoExecution(const SourceFileCoverageData* data, size_t line) {
1061  E :      DCHECK(data != NULL);
1062    :  
1063  E :      const LineExecutionCountMap& lines = data->line_execution_count_map;
1064  E :      LineExecutionCountMap::const_iterator look = lines.find(line);
1065  E :      if (look != lines.end()) {
1066  E :        if (look->second != 0)
1067  E :          return true;
1068    :      }
1069    :  
1070  E :      return false;
1071  E :    }
1072    :  
1073  E :    void CoverageInvokeTestDll() {
1074  E :      EXPECT_EQ(182, InvokeTestDllFunction(testing::kCoverage1));
1075  E :      EXPECT_EQ(182, InvokeTestDllFunction(testing::kCoverage2));
1076  E :      EXPECT_EQ(2, InvokeTestDllFunction(testing::kCoverage3));
1077  E :    }
1078    :  
1079  E :    void CoverageCheckTestDll() {
1080  E :      Parser parser;
1081  E :      grinder::grinders::CoverageGrinder grinder;
1082    :  
1083    :      // Initialize trace parser.
1084  E :      ASSERT_TRUE(parser.Init(&grinder));
1085  E :      grinder.SetParser(&parser);
1086    :  
1087    :      // Add generated traces to the parser.
1088  E :      QueueTraces(&parser);
1089    :  
1090    :      // Parse all traces.
1091  E :      ASSERT_TRUE(parser.Consume());
1092  E :      ASSERT_FALSE(parser.error_occurred());
1093  E :      ASSERT_TRUE(grinder.Grind());
1094    :  
1095    :      // Retrieve coverage information.
1096  E :      const grinder::CoverageData& coverage_data = grinder.coverage_data();
1097  E :      const SourceFileCoverageDataMap& files =
1098    :          coverage_data.source_file_coverage_data_map();
1099    :  
1100    :      // Find file "coverage_tests.cc".
1101  E :      SourceFileCoverageDataMap::const_iterator file = files.begin();
1102  E :      const SourceFileCoverageData* data = NULL;
1103  E :      for (; file != files.end(); ++file) {
1104  E :        if (base::EndsWith(file->first, "coverage_tests.cc",
1105    :                           base::CompareCase::SENSITIVE)) {
1106  E :          data = &file->second;
1107  E :          break;
1108    :        }
1109  E :      }
1110  E :      ASSERT_TRUE(data != NULL);
1111    :  
1112    :      // Validate function entry counts.
1113    :      // Function: coverage_func1.
1114  E :      EXPECT_TRUE(GetLineInfoExecution(data, 28));
1115  E :      EXPECT_TRUE(GetLineInfoExecution(data, 29));
1116    :  
1117    :      // Function: coverage_func2.
1118  E :      EXPECT_TRUE(GetLineInfoExecution(data, 35));
1119  E :      EXPECT_TRUE(GetLineInfoExecution(data, 36));
1120  E :      EXPECT_TRUE(GetLineInfoExecution(data, 37));
1121  E :      EXPECT_FALSE(GetLineInfoExecution(data, 40));
1122  E :      EXPECT_TRUE(GetLineInfoExecution(data, 42));
1123    :  
1124    :      // Function: coverage_func3.
1125  E :      EXPECT_TRUE(GetLineInfoExecution(data, 47));
1126  E :      EXPECT_FALSE(GetLineInfoExecution(data, 49));
1127  E :      EXPECT_FALSE(GetLineInfoExecution(data, 50));
1128  E :      EXPECT_TRUE(GetLineInfoExecution(data, 52));
1129  E :      EXPECT_TRUE(GetLineInfoExecution(data, 54));
1130  E :    }
1131    :  
1132    :    static bool ContainsString(const std::vector<std::wstring>& vec,
1133  E :                               const wchar_t* str) {
1134  E :      return std::find(vec.begin(), vec.end(), str) != vec.end();
1135  E :    }
1136    :  
1137  E :    void ProfileCheckTestDll(bool thunk_imports) {
1138  E :      Parser parser;
1139  E :      TestingProfileGrinder grinder;
1140    :  
1141    :      // Have the grinder aggregate all data to a single part.
1142  E :      grinder.set_thread_parts(false);
1143    :  
1144    :      // Initialize trace parser.
1145  E :      ASSERT_TRUE(parser.Init(&grinder));
1146  E :      grinder.SetParser(&parser);
1147    :  
1148    :      // Add generated traces to the parser.
1149  E :      QueueTraces(&parser);
1150    :  
1151    :      // Parse all traces.
1152  E :      ASSERT_TRUE(parser.Consume());
1153  E :      ASSERT_FALSE(parser.error_occurred());
1154  E :      ASSERT_TRUE(grinder.Grind());
1155    :  
1156  E :      const TestingProfileGrinder::ModuleInformationSet& modules =
1157    :          grinder.modules_;
1158  E :      TestingProfileGrinder::ModuleInformationSet::const_iterator mod_it;
1159  E :      std::vector<std::wstring> module_names;
1160  E :      for (mod_it = modules.begin(); mod_it != modules.end(); ++mod_it) {
1161  E :        base::FilePath image_name(mod_it->path);
1162  E :        module_names.push_back(image_name.BaseName().value());
1163  E :      }
1164    :  
1165  E :      EXPECT_TRUE(ContainsString(module_names,
1166    :                                 testing::kIntegrationTestsDllName));
1167    :      // If imports are thunked, we expect to find a module entry for the export
1168    :      // DLL - otherwise it shouldn't be in there at all.
1169  E :      if (thunk_imports) {
1170  E :        EXPECT_TRUE(ContainsString(module_names, L"export_dll.dll"));
1171  E :      } else {
1172  E :        EXPECT_FALSE(ContainsString(module_names, L"export_dll.dll"));
1173    :      }
1174    :  
1175    :      // Make sure at least one function we know of was hit.
1176  E :      ASSERT_EQ(1U, grinder.parts_.size());
1177  E :      const TestingProfileGrinder::PartData& data =
1178    :          grinder.parts_.begin()->second;
1179    :  
1180    :      TestingProfileGrinder::InvocationNodeMap::const_iterator node_it =
1181  E :          data.nodes_.begin();
1182  E :      for (; node_it != data.nodes_.end(); ++node_it) {
1183  E :        if (node_it->second.function.rva() == get_my_rva_)
1184  E :          return;
1185  E :      }
1186    :  
1187  i :      FAIL() << "Didn't find GetMyRVA function entry.";
1188  E :    }
1189    :  
1190    :    // Helper function to test the Asan symbolizer script.
1191    :    //
1192    :    // It starts by running a test with the '--minidump_on_failure' flag turned
1193    :    // on and then verify that the generated minidump can be symbolized correctly.
1194    :    //
1195    :    // @param test_id The test to run.
1196    :    // @param kind The expected bad access kind.
1197    :    // @param mode The expected bad access mode.
1198    :    // @param size The expected bad access size.
1199    :    // @param expect_corrupt_heap Indicates if we expect the heap to be corrupt.
1200    :    void AsanSymbolizerTest(testing::EndToEndTestId test_id,
1201    :                            const char* kind,
1202    :                            const char* mode,
1203    :                            size_t size,
1204  E :                            bool expect_corrupt_heap) {
1205  E :      ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1206  E :      ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1207    :  
1208    :      // Make sure that a minidump gets produced by the logger when a bug occurs.
1209  E :      std::unique_ptr<base::Environment> env(base::Environment::Create());
1210  E :      ASSERT_NE(env.get(), nullptr);
1211  E :      if (expect_corrupt_heap) {
1212  E :        env->SetVar(::common::kSyzyAsanOptionsEnvVar, "--minidump_on_failure");
1213  E :      } else {
1214  E :        env->SetVar(::common::kSyzyAsanOptionsEnvVar,
1215    :                    "--minidump_on_failure --no_check_heap_on_failure");
1216    :      }
1217  E :      std::string log;
1218    :  
1219    :      // Run the test.
1220  E :      OutOfProcessAsanErrorCheck(test_id, true, &log);
1221    :  
1222    :      // Look for the minidump path in the logger's output.
1223  E :      pcrecpp::RE re("A minidump has been written to (.*\\.dmp)\\.\\n?");
1224  E :      std::string minidump_path;
1225  E :      EXPECT_TRUE(re.PartialMatch(log, &minidump_path));
1226    :  
1227    :      // Run the symbolizer tester script to make sure that the minidump gets
1228    :      // symbolized correctly.
1229    :  
1230  E :      base::CommandLine cmd_line(
1231    :          ::testing::GetSrcRelativePath(L"third_party/python_26/python.exe"));
1232  E :      cmd_line.AppendArgPath(::testing::GetSrcRelativePath(
1233    :          L"syzygy/scripts/asan/minidump_symbolizer_tester.py"));
1234  E :      cmd_line.AppendArg(base::StringPrintf("--minidump=%s",
1235    :          minidump_path.c_str()));
1236  E :      cmd_line.AppendArg(base::StringPrintf("--bug-type=%s", kind));
1237  E :      cmd_line.AppendArg(base::StringPrintf("--access-mode=%s", mode));
1238  E :      cmd_line.AppendArg(base::StringPrintf("--access-size=%d", size));
1239  E :      if (expect_corrupt_heap)
1240  E :        cmd_line.AppendArg("--corrupt-heap");
1241    :  
1242  E :      base::LaunchOptions options;
1243  E :      options.inherit_handles = true;
1244  E :      base::Process process = base::LaunchProcess(cmd_line, options);
1245  E :      EXPECT_TRUE(process.IsValid());
1246    :  
1247  E :      int exit_code = 0;
1248  E :      EXPECT_TRUE(process.WaitForExit(&exit_code));
1249  E :      EXPECT_EQ(0u, exit_code);
1250    :  
1251    :      // Check if the minidump contains a valid protobuf.
1252  E :      poirot::MinidumpProcessor poirot_processor(
1253    :          base::FilePath::FromUTF8Unsafe(minidump_path));
1254  E :      EXPECT_TRUE(poirot_processor.ProcessDump());
1255    :  
1256  E :      env->UnSetVar(::common::kSyzyAsanOptionsEnvVar);
1257  E :    }
1258    :  
1259    :    // Stashes the current log-level before each test instance and restores it
1260    :    // after each test completes.
1261    :    testing::ScopedLogLevelSaver log_level_saver;
1262    :  
1263    :    // @name The application under test.
1264    :    // @{
1265    :    TestApp test_app_;
1266    :    TestApp::Implementation& test_impl_;
1267    :    base::FilePath temp_dir_;
1268    :    base::FilePath stdin_path_;
1269    :    base::FilePath stdout_path_;
1270    :    base::FilePath stderr_path_;
1271    :    // @}
1272    :  
1273    :    // @name Command-line, parameters and outputs.
1274    :    // @{
1275    :    base::CommandLine cmd_line_;
1276    :    base::FilePath input_dll_path_;
1277    :    base::FilePath output_dll_path_;
1278    :    base::FilePath traces_dir_;
1279    :    // @}
1280    :  
1281    :    // The test_dll module.
1282    :    testing::ScopedHMODULE module_;
1283    :  
1284    :    // Our call trace service process instance.
1285    :    testing::CallTraceService service_;
1286    :  
1287    :    // Decomposed image.
1288    :    pe::PEFile pe_image_;
1289    :    pe::ImageLayout image_layout_;
1290    :    block_graph::BlockGraph block_graph_;
1291    :    uint32_t get_my_rva_;
1292  E :  };
1293    :  typedef testing::StrictMock<LenientInstrumentAppIntegrationTest>
1294    :      InstrumentAppIntegrationTest;
1295    :  
1296    :  typedef std::map<std::string, size_t> FunctionOffsetMap;
1297    :  
1298    :  // A utility transform for extracting call site offsets from blocks.
1299    :  // Used by GetCallOffsets and ZebraBlockHeap tests.
1300    :  class ExtractCallTransform
1301    :      : public block_graph::BasicBlockSubGraphTransformInterface {
1302    :   public:
1303  E :    explicit ExtractCallTransform(FunctionOffsetMap* map) : map_(map) { }
1304  E :    virtual ~ExtractCallTransform() { }
1305  i :    virtual const char* name() const { return "ExtractCallTransform"; }
1306    :  
1307    :    virtual bool TransformBasicBlockSubGraph(
1308    :        const block_graph::TransformPolicyInterface* policy,
1309    :        block_graph::BlockGraph* block_graph,
1310  E :        block_graph::BasicBlockSubGraph* basic_block_subgraph) {
1311  E :      for (auto& desc : basic_block_subgraph->block_descriptions()) {
1312  E :        auto map_it = map_->find(desc.name);
1313  E :        if (map_it == map_->end())
1314  E :          continue;
1315    :  
1316    :        // Set this to effectively 'infinite' to start with.
1317  E :        map_it->second = static_cast<size_t>(-1);
1318    :  
1319  E :        for (auto& bb : desc.basic_block_order) {
1320    :          block_graph::BasicCodeBlock* bcb =
1321  E :              block_graph::BasicCodeBlock::Cast(bb);
1322  E :          if (bcb == nullptr)
1323  E :            continue;
1324    :  
1325  E :          size_t offset = bcb->offset();
1326  E :          for (auto& inst : bcb->instructions()) {
1327  E :            offset += inst.size();
1328  E :            if (inst.IsCall()) {
1329  E :              map_it->second = std::min(map_it->second, offset);
1330    :            }
1331  E :          }
1332  E :        }
1333  E :      }
1334    :  
1335  E :      return true;
1336  E :    }
1337    :  
1338    :   protected:
1339    :    FunctionOffsetMap* map_;
1340    :  };
1341    :  
1342    :  // Gets the offsets of the first call from each function named in |map|,
1343    :  // as found in the image at |image_path|. Updates the map with the offsets.
1344    :  void GetCallOffsets(const base::FilePath& image_path,
1345  E :                      FunctionOffsetMap* map) {
1346  E :    pe::PEFile pe_file;
1347  E :    ASSERT_TRUE(pe_file.Init(image_path));
1348  E :    block_graph::BlockGraph bg;
1349  E :    block_graph::BlockGraph::Block* header = NULL;
1350    :  
1351    :    // Decompose the image.
1352    :    {
1353  E :      pe::ImageLayout image_layout(&bg);
1354  E :      pe::Decomposer decomposer(pe_file);
1355  E :      ASSERT_TRUE(decomposer.Decompose(&image_layout));
1356  E :      header = image_layout.blocks.GetBlockByAddress(
1357    :          block_graph::BlockGraph::RelativeAddress(0));
1358  E :    }
1359    :  
1360    :    // Apply the Asan transform.
1361  E :    pe::PETransformPolicy policy;
1362    :    {
1363  E :      instrument::transforms::AsanTransform tx;
1364  E :      ASSERT_TRUE(block_graph::ApplyBlockGraphTransform(
1365  E :          &tx, &policy, &bg, header));
1366  E :    }
1367    :  
1368    :    // Apply our dummy transform which simply extracts call addresses.
1369    :    {
1370  E :      ExtractCallTransform bbtx(map);
1371  E :      block_graph::transforms::ChainedBasicBlockTransforms tx;
1372  E :      tx.AppendTransform(&bbtx);
1373  E :      ASSERT_TRUE(block_graph::ApplyBlockGraphTransform(
1374  E :          &tx, &policy, &bg, header));
1375  E :    }
1376  E :  }
1377    :  
1378  E :  void LenientInstrumentAppIntegrationTest::AsanZebraHeapTest(bool enabled) {
1379    :    // Find the offset of the call we want to instrument.
1380    :    static const char kTest1[] =
1381    :        "testing::AsanReadPageAllocationTrailerBeforeFree";
1382    :    static const char kTest2[] =
1383    :        "testing::AsanWritePageAllocationBodyAfterFree";
1384  E :    FunctionOffsetMap map({{kTest1, -1}, {kTest2, -1}});
1385  E :    ASSERT_NO_FATAL_FAILURE(GetCallOffsets(input_dll_path_, &map));
1386    :  
1387    :    // Create an allocation filter.
1388  E :    base::FilePath filter_path = temp_dir_.AppendASCII("allocation_filter.json");
1389  E :    std::string filter_contents = base::StringPrintf(
1390    :        "{\"hooks\":{\"%s\":[%d],\"%s\":[%d]}}",
1391    :        kTest1, map[kTest1], kTest2, map[kTest2]);
1392  E :    base::WriteFile(
1393    :        filter_path, filter_contents.c_str(), filter_contents.size());
1394    :  
1395    :    // Configure the transform and test the binary.
1396  E :    cmd_line_.AppendSwitchPath("allocation-filter-config-file", filter_path);
1397  E :    std::string rtl_options = "--no_check_heap_on_failure";
1398  E :    if (enabled)
1399  E :      rtl_options += " --enable_zebra_block_heap --enable_allocation_filter";
1400  E :    cmd_line_.AppendSwitchASCII("asan-rtl-options", rtl_options);
1401  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1402  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1403    :  
1404    :    // Run tests that are specific to the zebra block heap.
1405  E :    OutOfProcessAsanErrorCheckAndValidateLog(
1406    :        testing::kAsanReadPageAllocationTrailerBeforeFreeAllocation, enabled,
1407    :        kAsanAccessViolationLog, kAsanHeapBufferOverflow);
1408  E :    OutOfProcessAsanErrorCheckAndValidateLog(
1409    :        testing::kAsanWritePageAllocationBodyAfterFree, enabled,
1410    :        kAsanAccessViolationLog, kAsanHeapUseAfterFree);
1411  E :  }
1412    :  
1413    :  }  // namespace
1414    :  
1415  E :  TEST_F(InstrumentAppIntegrationTest, AsanEndToEnd) {
1416    :    // Disable the heap checking as this is implies touching all the shadow bytes
1417    :    // and this make those tests really slow.
1418  E :    cmd_line_.AppendSwitchASCII("asan-rtl-options", "--no_check_heap_on_failure");
1419  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1420  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1421  E :    ASSERT_NO_FATAL_FAILURE(AsanErrorCheckTestDll());
1422  E :    ASSERT_NO_FATAL_FAILURE(CheckTestDllImportsRedirected());
1423  E :  }
1424    :  
1425  E :  TEST_F(InstrumentAppIntegrationTest, AsanEndToEndNoLiveness) {
1426    :    // Disable the heap checking as this is implies touching all the shadow bytes
1427    :    // and this make those tests really slow.
1428  E :    cmd_line_.AppendSwitchASCII("asan-rtl-options", "--no_check_heap_on_failure");
1429  E :    cmd_line_.AppendSwitch("no-liveness-analysis");
1430  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1431  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1432  E :    ASSERT_NO_FATAL_FAILURE(AsanErrorCheckTestDll());
1433  E :  }
1434    :  
1435  E :  TEST_F(InstrumentAppIntegrationTest, AsanEndToEndNoRedundancyAnalysis) {
1436    :    // Disable the heap checking as this is implies touching all the shadow bytes
1437    :    // and this make those tests really slow.
1438  E :    cmd_line_.AppendSwitchASCII("asan-rtl-options", "--no_check_heap_on_failure");
1439  E :    cmd_line_.AppendSwitch("no-redundancy-analysis");
1440  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1441  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1442  E :    ASSERT_NO_FATAL_FAILURE(AsanErrorCheckTestDll());
1443  E :  }
1444    :  
1445  E :  TEST_F(InstrumentAppIntegrationTest, AsanEndToEndNoFunctionInterceptors) {
1446    :    // Disable the heap checking as this is implies touching all the shadow bytes
1447    :    // and this make those tests really slow.
1448  E :    cmd_line_.AppendSwitchASCII("asan-rtl-options", "--no_check_heap_on_failure");
1449  E :    cmd_line_.AppendSwitch("no-interceptors");
1450  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1451  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1452  E :    ASSERT_NO_FATAL_FAILURE(AsanErrorCheckTestDll());
1453  E :  }
1454    :  
1455  E :  TEST_F(InstrumentAppIntegrationTest, AsanEndToEndWithRtlOptions) {
1456  E :    cmd_line_.AppendSwitchASCII(
1457    :        "asan-rtl-options",
1458    :        "--quarantine_size=20000000 --quarantine_block_size=1000000 "
1459    :        "--no_check_heap_on_failure");
1460  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1461  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1462  E :    ASSERT_NO_FATAL_FAILURE(AsanErrorCheckTestDll());
1463    :  
1464    :    // Get the active runtime and validate its parameters.
1465  E :    agent::asan::AsanRuntime* runtime = GetActiveAsanRuntime();
1466  E :    ASSERT_TRUE(runtime != NULL);
1467  E :    ASSERT_EQ(20000000u, runtime->params().quarantine_size);
1468  E :    ASSERT_EQ(1000000u, runtime->params().quarantine_block_size);
1469  E :  }
1470    :  
1471  E :  TEST_F(InstrumentAppIntegrationTest,
1472  E :         AsanEndToEndWithRtlOptionsOverrideWithEnvironment) {
1473  E :    std::unique_ptr<base::Environment> env(base::Environment::Create());
1474  E :    ASSERT_NE(env.get(), nullptr);
1475  E :    env->SetVar(::common::kSyzyAsanOptionsEnvVar,
1476    :                "--quarantine_block_size=800000 --ignored_stack_ids=0x1 "
1477    :                "--no_check_heap_on_failure");
1478  E :    cmd_line_.AppendSwitchASCII(
1479    :        "asan-rtl-options",
1480    :        "--quarantine_size=20000000 --quarantine_block_size=1000000 "
1481    :        "--ignored_stack_ids=0x2");
1482  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1483  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1484  E :    ASSERT_NO_FATAL_FAILURE(AsanErrorCheckTestDll());
1485    :  
1486    :    // Get the active runtime and validate its parameters.
1487  E :    agent::asan::AsanRuntime* runtime = GetActiveAsanRuntime();
1488  E :    ASSERT_TRUE(runtime != NULL);
1489  E :    ASSERT_EQ(20000000u, runtime->params().quarantine_size);
1490  E :    ASSERT_EQ(800000u, runtime->params().quarantine_block_size);
1491  E :    ASSERT_THAT(runtime->params().ignored_stack_ids_set,
1492  E :                testing::ElementsAre(0x1, 0x2));
1493    :  
1494  E :    env->UnSetVar(::common::kSyzyAsanOptionsEnvVar);
1495  E :  }
1496    :  
1497  E :  TEST_F(InstrumentAppIntegrationTest, FullOptimizedAsanEndToEnd) {
1498    :    // Disable the heap checking as this implies touching all the shadow bytes
1499    :    // and this make these tests really slow.
1500  E :    cmd_line_.AppendSwitchASCII("asan-rtl-options", "--no_check_heap_on_failure");
1501  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1502  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1503  E :    ASSERT_NO_FATAL_FAILURE(AsanErrorCheckTestDll());
1504  E :    ASSERT_NO_FATAL_FAILURE(AsanErrorCheckInterceptedFunctions());
1505  E :  }
1506    :  
1507  E :  TEST_F(InstrumentAppIntegrationTest,
1508  E :         AsanInvalidAccessWithCorruptAllocatedBlockHeader) {
1509  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1510  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1511  E :    OutOfProcessAsanErrorCheckAndValidateLog(
1512    :        testing::kAsanInvalidAccessWithCorruptAllocatedBlockHeader, true,
1513    :        kAsanCorruptHeap, NULL);
1514  E :  }
1515    :  
1516  E :  TEST_F(InstrumentAppIntegrationTest,
1517  E :         AsanHeapCheckerCallsReportCrashWithProtobuf) {
1518    :    // Heap checker failures do get reported to ReportCrashWithProtobuf if it is
1519    :    // defined.
1520  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1521  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1522    :  
1523  E :    int exit_code = RunOutOfProcessFunction(
1524    :        L"report_crash_with_protobuf_harness.exe",
1525    :        testing::kAsanInvalidAccessWithCorruptAllocatedBlockHeader, true);
1526  E :    EXPECT_EQ(kExeReportCrashWithProtobufExitCode, exit_code);
1527  E :  }
1528    :  
1529  E :  TEST_F(InstrumentAppIntegrationTest, AsanOverflowCallsCrashForException) {
1530    :    // Asan-detected violations go through CrashForException if it is available.
1531  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1532  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1533    :    int exit_code =
1534  E :        RunOutOfProcessFunction(L"crash_for_exception_harness.exe",
1535    :                                testing::kAsanRead8BufferOverflow, true);
1536  E :    EXPECT_EQ(kExeCrashForExceptionExitCode, exit_code);
1537  E :  }
1538    :  
1539  E :  TEST_F(InstrumentAppIntegrationTest,
1540  E :         AsanOverflowCallsReportCrashWithProtobuf) {
1541    :    // Asan-detected violations go through ReportCrashWithProtobuf if it is
1542    :    // available.
1543  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1544  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1545    :    int exit_code =
1546  E :        RunOutOfProcessFunction(L"report_crash_with_protobuf_harness.exe",
1547    :                                testing::kAsanRead8BufferOverflow, true);
1548  E :    EXPECT_EQ(kExeReportCrashWithProtobufExitCode, exit_code);
1549  E :  }
1550    :  
1551  E :  TEST_F(InstrumentAppIntegrationTest,
1552  E :         AsanInvalidAccessWithCorruptAllocatedBlockTrailer) {
1553  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1554  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1555  E :    OutOfProcessAsanErrorCheckAndValidateLog(
1556    :        testing::kAsanInvalidAccessWithCorruptAllocatedBlockTrailer, true,
1557    :        kAsanCorruptHeap, NULL);
1558  E :  }
1559    :  
1560  E :  TEST_F(InstrumentAppIntegrationTest,
1561  E :         AsanInvalidAccessWithCorruptFreedBlock) {
1562  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1563  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1564  E :    OutOfProcessAsanErrorCheckAndValidateLog(
1565    :        testing::kAsanInvalidAccessWithCorruptFreedBlock, true, kAsanCorruptHeap,
1566    :        NULL);
1567  E :  }
1568    :  
1569  E :  TEST_F(InstrumentAppIntegrationTest, AsanCorruptBlockWithPageProtections) {
1570  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1571  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1572  E :    OutOfProcessAsanErrorCheckAndValidateLog(
1573    :        testing::kAsanCorruptBlockWithPageProtections, true,
1574    :        kAsanHeapUseAfterFree, kAsanCorruptHeap);
1575  E :  }
1576    :  
1577  E :  TEST_F(InstrumentAppIntegrationTest, SampledAllocationsAsanEndToEnd) {
1578  E :    cmd_line_.AppendSwitchASCII("asan-rtl-options",
1579    :                                "--allocation_guard_rate=0.5 "
1580    :                                "--no_check_heap_on_failure");
1581  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1582  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1583  E :    ASSERT_NO_FATAL_FAILURE(AsanErrorCheckSampledAllocations());
1584  E :  }
1585    :  
1586  E :  TEST_F(InstrumentAppIntegrationTest, AsanLargeBlockHeapEnabledTest) {
1587  E :    cmd_line_.AppendSwitchASCII("asan-rtl-options",
1588    :                                "--no_check_heap_on_failure "
1589    :                                "--quarantine_size=4000000 "
1590    :                                "--quarantine_block_size=2000000");
1591  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1592  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1593  E :    ASSERT_NO_FATAL_FAILURE(AsanLargeBlockHeapTests(true));
1594  E :  }
1595    :  
1596  E :  TEST_F(InstrumentAppIntegrationTest, AsanLargeBlockHeapDisabledTest) {
1597  E :    cmd_line_.AppendSwitchASCII("asan-rtl-options",
1598    :                                "--no_check_heap_on_failure "
1599    :                                "--disable_large_block_heap");
1600  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1601  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1602  E :    ASSERT_NO_FATAL_FAILURE(AsanLargeBlockHeapTests(false));
1603  E :  }
1604    :  
1605  E :  TEST_F(InstrumentAppIntegrationTest, AsanZebraHeapDisabledTest) {
1606  E :    AsanZebraHeapTest(false);
1607  E :  }
1608    :  
1609  E :  TEST_F(InstrumentAppIntegrationTest, AsanZebraHeapEnabledTest) {
1610  E :    AsanZebraHeapTest(true);
1611  E :  }
1612    :  
1613  E :  TEST_F(InstrumentAppIntegrationTest, AsanSymbolizerTestAsanBufferOverflow) {
1614  E :    AsanSymbolizerTest(testing::kAsanRead8BufferOverflow,
1615    :                       STRINGIFY(HEAP_BUFFER_OVERFLOW),
1616    :                       STRINGIFY(ASAN_READ_ACCESS),
1617    :                       1,
1618    :                       false);
1619  E :  }
1620    :  
1621  E :  TEST_F(InstrumentAppIntegrationTest, AsanSymbolizerTestAsanBufferUnderflow) {
1622  E :    AsanSymbolizerTest(testing::kAsanWrite32BufferUnderflow,
1623    :                       STRINGIFY(HEAP_BUFFER_UNDERFLOW),
1624    :                       STRINGIFY(ASAN_WRITE_ACCESS),
1625    :                       4,
1626    :                       false);
1627  E :  }
1628    :  
1629  E :  TEST_F(InstrumentAppIntegrationTest, AsanSymbolizerTestAsanUseAfterFree) {
1630  E :    AsanSymbolizerTest(testing::kAsanRead64UseAfterFree,
1631    :                       STRINGIFY(USE_AFTER_FREE),
1632    :                       STRINGIFY(ASAN_READ_ACCESS),
1633    :                       8,
1634    :                       false);
1635  E :  }
1636    :  
1637  E :  TEST_F(InstrumentAppIntegrationTest, AsanSymbolizerTestAsanCorruptBlock) {
1638  E :    AsanSymbolizerTest(testing::kAsanCorruptBlock,
1639    :                       STRINGIFY(CORRUPT_BLOCK),
1640    :                       STRINGIFY(ASAN_UNKNOWN_ACCESS),
1641    :                       0,
1642    :                       false);
1643  E :  }
1644    :  
1645  E :  TEST_F(InstrumentAppIntegrationTest,
1646  E :         AsanSymbolizerTestAsanCorruptBlockInQuarantine) {
1647  E :    AsanSymbolizerTest(testing::kAsanCorruptBlockInQuarantine,
1648    :                       STRINGIFY(CORRUPT_BLOCK),
1649    :                       STRINGIFY(ASAN_UNKNOWN_ACCESS),
1650    :                       0,
1651    :                       true);
1652  E :  }
1653    :  
1654    :  // These tests require corrupt heap checking to be enabled.
1655  E :  TEST_F(InstrumentAppIntegrationTest, AsanNearNullptrAccess) {
1656  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1657    :  
1658  E :    OutOfProcessAsanErrorCheckAndValidateLog(
1659    :        testing::kAsanNearNullptrAccessHeapCorruptionInstrumented, true,
1660    :        kAsanHandlingException, kAsanNearNullptrAccessHeapCorruption);
1661  E :    OutOfProcessAsanErrorCheckAndValidateLog(
1662    :        testing::kAsanNearNullptrAccessHeapCorruptionUninstrumented, true,
1663    :        kAsanHandlingException, kAsanNearNullptrAccessHeapCorruption);
1664  E :    OutOfProcessAsanErrorCheckAndValidateLog(
1665    :        testing::kAsanNearNullptrAccessNoHeapCorruptionInstrumented, true,
1666    :        kAsanHandlingException, kAsanNearNullptrAccessNoHeapCorruption);
1667  E :    OutOfProcessAsanErrorCheckAndValidateLog(
1668    :        testing::kAsanNearNullptrAccessNoHeapCorruptionUninstrumented, true,
1669    :        kAsanHandlingException, kAsanNearNullptrAccessNoHeapCorruption);
1670  E :    OutOfProcessAsanErrorCheckAndValidateLog(
1671    :        testing::kAsanNullptrAccessNoHeapCorruptionUninstrumented, true,
1672    :        kAsanHandlingException, kAsanNearNullptrAccessNoHeapCorruption);
1673  E :  }
1674    :  
1675  E :  TEST_F(InstrumentAppIntegrationTest, BBEntryEndToEnd) {
1676  E :    ASSERT_NO_FATAL_FAILURE(StartService());
1677  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("bbentry"));
1678  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1679  E :    ASSERT_NO_FATAL_FAILURE(BBEntryInvokeTestDll());
1680  E :    ASSERT_NO_FATAL_FAILURE(StopService());
1681  E :    ASSERT_NO_FATAL_FAILURE(BBEntryCheckTestDll());
1682  E :  }
1683    :  
1684  E :  TEST_F(InstrumentAppIntegrationTest, BranchEndToEnd) {
1685  E :    ASSERT_NO_FATAL_FAILURE(StartService());
1686  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("branch"));
1687  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1688  E :    ASSERT_NO_FATAL_FAILURE(BBEntryInvokeTestDll());
1689  E :    ASSERT_NO_FATAL_FAILURE(UnloadDll());
1690  E :    ASSERT_NO_FATAL_FAILURE(StopService());
1691  E :    ASSERT_NO_FATAL_FAILURE(BranchCheckTestDll());
1692  E :  }
1693    :  
1694  E :  TEST_F(InstrumentAppIntegrationTest, BranchWithBufferingEndToEnd) {
1695  E :    cmd_line_.AppendSwitch("buffering");
1696  E :    ASSERT_NO_FATAL_FAILURE(StartService());
1697  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("branch"));
1698  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1699  E :    ASSERT_NO_FATAL_FAILURE(BBEntryInvokeTestDll());
1700  E :    ASSERT_NO_FATAL_FAILURE(UnloadDll());
1701  E :    ASSERT_NO_FATAL_FAILURE(StopService());
1702  E :    ASSERT_NO_FATAL_FAILURE(BranchCheckTestDll());
1703  E :  }
1704    :  
1705  E :  TEST_F(InstrumentAppIntegrationTest, BranchWithSlotEndToEnd) {
1706  E :    cmd_line_.AppendSwitchASCII("fs-slot", "1");
1707  E :    ASSERT_NO_FATAL_FAILURE(StartService());
1708  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("branch"));
1709  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1710  E :    ASSERT_NO_FATAL_FAILURE(BBEntryInvokeTestDll());
1711  E :    ASSERT_NO_FATAL_FAILURE(UnloadDll());
1712  E :    ASSERT_NO_FATAL_FAILURE(StopService());
1713  E :    ASSERT_NO_FATAL_FAILURE(BranchCheckTestDll());
1714  E :  }
1715    :  
1716  E :  TEST_F(InstrumentAppIntegrationTest, BranchWithSlotAndBufferingEndToEnd) {
1717  E :    cmd_line_.AppendSwitch("buffering");
1718  E :    cmd_line_.AppendSwitchASCII("fs-slot", "1");
1719  E :    ASSERT_NO_FATAL_FAILURE(StartService());
1720  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("branch"));
1721  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1722  E :    ASSERT_NO_FATAL_FAILURE(BBEntryInvokeTestDll());
1723  E :    ASSERT_NO_FATAL_FAILURE(UnloadDll());
1724  E :    ASSERT_NO_FATAL_FAILURE(StopService());
1725  E :    ASSERT_NO_FATAL_FAILURE(BranchCheckTestDll());
1726  E :  }
1727    :  
1728  E :  TEST_F(InstrumentAppIntegrationTest, CallTraceEndToEnd) {
1729  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("calltrace"));
1730  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1731  E :  }
1732    :  
1733  E :  TEST_F(InstrumentAppIntegrationTest, CoverageEndToEnd) {
1734  E :    base::win::ScopedCOMInitializer scoped_com_initializer;
1735  E :    ASSERT_NO_FATAL_FAILURE(StartService());
1736  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("coverage"));
1737  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1738  E :    ASSERT_NO_FATAL_FAILURE(CoverageInvokeTestDll());
1739  E :    ASSERT_NO_FATAL_FAILURE(StopService());
1740  E :    ASSERT_NO_FATAL_FAILURE(CoverageCheckTestDll());
1741  E :  }
1742    :  
1743  E :  TEST_F(InstrumentAppIntegrationTest, BBEntryCoverageEndToEnd) {
1744    :    // Coverage grinder must be able to process traces produced by bbentry
1745    :    // instrumentation.
1746  E :    base::win::ScopedCOMInitializer scoped_com_initializer;
1747  E :    ASSERT_NO_FATAL_FAILURE(StartService());
1748  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("bbentry"));
1749  E :    ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1750  E :    ASSERT_NO_FATAL_FAILURE(CoverageInvokeTestDll());
1751  E :    ASSERT_NO_FATAL_FAILURE(StopService());
1752  E :    ASSERT_NO_FATAL_FAILURE(CoverageCheckTestDll());
1753  E :  }
1754    :  
1755  E :  TEST_F(InstrumentAppIntegrationTest, ProfileEndToEnd) {
1756  E :    ASSERT_NO_FATAL_FAILURE(StartService());
1757  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("profile"));
1758  E :    ASSERT_NO_FATAL_FAILURE(ProfileInvokeTestDll());
1759  E :    ASSERT_NO_FATAL_FAILURE(UnloadDll());
1760  E :    ASSERT_NO_FATAL_FAILURE(StopService());
1761  E :    ASSERT_NO_FATAL_FAILURE(ProfileCheckTestDll(false));
1762  E :  }
1763    :  
1764  E :  TEST_F(InstrumentAppIntegrationTest, ProfileWithImportsEndToEnd) {
1765  E :    cmd_line_.AppendSwitch("instrument-imports");
1766  E :    ASSERT_NO_FATAL_FAILURE(StartService());
1767  E :    ASSERT_NO_FATAL_FAILURE(EndToEndTest("profile"));
1768  E :    ASSERT_NO_FATAL_FAILURE(ProfileInvokeTestDll());
1769  E :    ASSERT_NO_FATAL_FAILURE(UnloadDll());
1770  E :    ASSERT_NO_FATAL_FAILURE(StopService());
1771  E :    ASSERT_NO_FATAL_FAILURE(ProfileCheckTestDll(true));
1772  E :  }
1773    :  
1774    :  }  // namespace integration_tests

Coverage information generated Fri Jul 29 11:00:21 2016.