Coverage for /Syzygy/integration_tests/instrument_integration_test.cc

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

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