Coverage for /Syzygy/integration_tests/instrument_integration_test.cc

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

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