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 █
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
|