Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Side by Side Diff: syzygy/agent/asan/runtime.cc

Issue 1992773002: [SyzyAsan] Enable Crashpad reporter as a 50/50 experiment. (Closed) Base URL: https://github.com/google/syzygy.git@master
Patch Set: Fix broken unittest. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « syzygy/agent/asan/runtime.h ('k') | syzygy/agent/asan/runtime_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 Google Inc. All Rights Reserved. 1 // Copyright 2012 Google Inc. All Rights Reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with 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 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 60
61 namespace agent { 61 namespace agent {
62 namespace asan { 62 namespace asan {
63 63
64 namespace { 64 namespace {
65 65
66 using agent::asan::AsanLogger; 66 using agent::asan::AsanLogger;
67 using agent::asan::StackCaptureCache; 67 using agent::asan::StackCaptureCache;
68 using agent::asan::WindowsHeapAdapter; 68 using agent::asan::WindowsHeapAdapter;
69 69
70 enum CrashReporterType {
71 kDefaultCrashReporterType,
72 kBreakpadCrashReporterType,
73 kKaskoCrashReporterType,
74 kCrashpadCrashReporterType,
75 };
76
70 // A custom exception code we use to indicate that the exception originated 77 // A custom exception code we use to indicate that the exception originated
71 // from Asan, and shouldn't be processed again by our unhandled exception 78 // from Asan, and shouldn't be processed again by our unhandled exception
72 // handler. This value has been created according to the rules here: 79 // handler. This value has been created according to the rules here:
73 // http://msdn.microsoft.com/en-us/library/windows/hardware/ff543026(v=vs.85).as px 80 // http://msdn.microsoft.com/en-us/library/windows/hardware/ff543026(v=vs.85).as px
74 // See winerror.h for more details. 81 // See winerror.h for more details.
75 static const DWORD kAsanFacility = 0x68B; // No more than 11 bits. 82 static const DWORD kAsanFacility = 0x68B; // No more than 11 bits.
76 static const DWORD kAsanStatus = 0x5AD0; // No more than 16 bits. 83 static const DWORD kAsanStatus = 0x5AD0; // No more than 16 bits.
77 static const DWORD kAsanException = 84 static const DWORD kAsanException =
78 (3 << 30) | // Severity = error. 85 (3 << 30) | // Severity = error.
79 (1 << 29) | // Customer defined code (not defined by MS). 86 (1 << 29) | // Customer defined code (not defined by MS).
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 ->WriteCorruptHeapInfo(corrupt_ranges, size, buffer, error_info); \ 387 ->WriteCorruptHeapInfo(corrupt_ranges, size, buffer, error_info); \
381 } \ 388 } \
382 } 389 }
383 390
384 void LaunchMessageBox(const base::StringPiece& message) { 391 void LaunchMessageBox(const base::StringPiece& message) {
385 // TODO(chrisha): Consider making this close itself with a timeout to prevent 392 // TODO(chrisha): Consider making this close itself with a timeout to prevent
386 // hangs on the waterfall. 393 // hangs on the waterfall.
387 ::MessageBoxA(nullptr, message.data(), nullptr, MB_OK | MB_ICONEXCLAMATION); 394 ::MessageBoxA(nullptr, message.data(), nullptr, MB_OK | MB_ICONEXCLAMATION);
388 } 395 }
389 396
390 std::unique_ptr<ReporterInterface> CreateCrashReporter(AsanLogger* logger) { 397 // Gets the preferred crash reporter type from the environment. This will
398 // override experiments or command-lines, and is largely meant for local
399 // testing.
400 CrashReporterType GetCrashReporterTypeFromEnvironment(
401 AsanLogger* logger) {
402 DCHECK_NE(static_cast<AsanLogger*>(nullptr), logger);
391 std::unique_ptr<ReporterInterface> reporter; 403 std::unique_ptr<ReporterInterface> reporter;
392 404
393 // First try to grab the preferred crash reporter, overridden by the
394 // environment.
395 std::unique_ptr<base::Environment> env(base::Environment::Create()); 405 std::unique_ptr<base::Environment> env(base::Environment::Create());
396 std::string reporter_name; 406 std::string reporter_name;
397 if (env->GetVar("SYZYASAN_CRASH_REPORTER", &reporter_name)) { 407 static const char kSyzyAsanCrashReporterEnv[] =
398 if (reporter_name == "crashpad") 408 "SYZYASAN_CRASH_REPORTER";
399 reporter.reset(reporters::CrashpadReporter::Create().release()); 409 if (!env->GetVar(kSyzyAsanCrashReporterEnv, &reporter_name))
400 else if (reporter_name == "kasko") 410 return kDefaultCrashReporterType;
401 reporter.reset(reporters::KaskoReporter::Create().release());
402 else if (reporter_name == "breakpad")
403 reporter.reset(reporters::BreakpadReporter::Create().release());
404 411
405 if (reporter.get() != nullptr) { 412 CrashReporterType type = kDefaultCrashReporterType;
406 logger->Write(base::StringPrintf( 413 if (reporter_name == "crashpad") {
407 "Using requested \"%s\" crash reporter.", reporter_name)); 414 type = kCrashpadCrashReporterType;
408 return reporter; 415 } else if (reporter_name == "kasko") {
409 } else { 416 type = kKaskoCrashReporterType;
410 logger->Write(base::StringPrintf( 417 } else if (reporter_name == "breakpad") {
411 "Unable to create requested \"%s\" crash reporter.", reporter_name)); 418 type = kBreakpadCrashReporterType;
412 }
413 } 419 }
414 420
415 // No crash reporter was explicitly specified, or it was unable to be 421 if (type != kDefaultCrashReporterType) {
416 // initialized. Try all of them, starting with the most recent. 422 logger->Write(base::StringPrintf("Encountered %s=\"%s\".",
423 kSyzyAsanCrashReporterEnv, reporter_name.c_str()));
424 } else {
425 logger->Write(base::StringPrintf("Ignoring %s=\"%s\".",
426 kSyzyAsanCrashReporterEnv, reporter_name.c_str()));
427 }
417 428
418 // Don't try grabbing a Crashpad reporter by default, as we're not yet 429 return type;
419 // ready to ship this. 430 }
420 // TODO(chrisha): Add Crashpad support behind a feature flag. 431
432 // Attempts to create a crash reporter, starting with the most modern.
433 std::unique_ptr<ReporterInterface> CreateCrashReporterWithTypeHint(
434 AsanLogger* logger, CrashReporterType reporter_type) {
435 std::unique_ptr<ReporterInterface> reporter;
436
437 // Crashpad is not yet enabled by default.
438 if (reporter_type == kCrashpadCrashReporterType)
439 reporter.reset(reporters::CrashpadReporter::Create().release());
421 440
422 // Try to initialize a Kasko crash reporter. 441 // Try to initialize a Kasko crash reporter.
423 if (reporter.get() == nullptr) 442 if (reporter.get() == nullptr &&
443 (reporter_type == kKaskoCrashReporterType ||
444 reporter_type == kDefaultCrashReporterType)) {
424 reporter.reset(reporters::KaskoReporter::Create().release()); 445 reporter.reset(reporters::KaskoReporter::Create().release());
446 }
425 447
426 // If that failed then try to initialize a Breakpad reporter. 448 // If that failed then try to initialize a Breakpad reporter.
427 if (reporter.get() == nullptr) 449 if (reporter.get() == nullptr &&
450 (reporter_type == kBreakpadCrashReporterType ||
451 reporter_type == kDefaultCrashReporterType)) {
428 reporter.reset(reporters::BreakpadReporter::Create().release()); 452 reporter.reset(reporters::BreakpadReporter::Create().release());
453 }
429 454
430 return reporter; 455 return reporter;
431 } 456 }
432 457
433 } // namespace 458 } // namespace
434 459
435 base::Lock AsanRuntime::lock_; 460 base::Lock AsanRuntime::lock_;
436 AsanRuntime* AsanRuntime::runtime_ = NULL; 461 AsanRuntime* AsanRuntime::runtime_ = NULL;
437 LPTOP_LEVEL_EXCEPTION_FILTER AsanRuntime::previous_uef_ = NULL; 462 LPTOP_LEVEL_EXCEPTION_FILTER AsanRuntime::previous_uef_ = NULL;
438 bool AsanRuntime::uef_installed_ = false; 463 bool AsanRuntime::uef_installed_ = false;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 if (!SetUpMemoryNotifier()) 501 if (!SetUpMemoryNotifier())
477 return false; 502 return false;
478 if (!SetUpLogger()) 503 if (!SetUpLogger())
479 return false; 504 return false;
480 if (!SetUpStackCache()) 505 if (!SetUpStackCache())
481 return false; 506 return false;
482 if (!SetUpHeapManager()) 507 if (!SetUpHeapManager())
483 return false; 508 return false;
484 WindowsHeapAdapter::SetUp(heap_manager_.get()); 509 WindowsHeapAdapter::SetUp(heap_manager_.get());
485 510
511 // Determine the preferred crash reporter type, as specified in the
512 // environment. If this isn't present it defaults to
513 // kDefaultCrashReporterType, in which case experiments or command-line flags
514 // may specify the crash reporter to use.
515 CrashReporterType crash_reporter_type =
516 GetCrashReporterTypeFromEnvironment(logger());
517
486 if (params_.feature_randomization) { 518 if (params_.feature_randomization) {
487 AsanFeatureSet feature_set = GenerateRandomFeatureSet(); 519 AsanFeatureSet feature_set = GenerateRandomFeatureSet();
488 PropagateFeatureSet(feature_set); 520 PropagateFeatureSet(feature_set);
521
522 // If no specific crash reporter has been specified, then allow the
523 // experiment to specify it.
524 if (crash_reporter_type == kDefaultCrashReporterType &&
525 (feature_set & ASAN_FEATURE_ENABLE_CRASHPAD) != 0) {
526 crash_reporter_type = kCrashpadCrashReporterType;
527 }
489 } 528 }
490 529
491 // Propagates the flags values to the different modules. 530 // Propagates the flags values to the different modules.
492 PropagateParams(); 531 PropagateParams();
493 532
494 // The name 'disable_breakpad_reporting' is legacy; this actually means to 533 // The name 'disable_breakpad_reporting' is legacy; this actually means to
495 // disable all external crash reporting integration. 534 // disable all external crash reporting integration.
496 if (!params_.disable_breakpad_reporting) 535 if (!params_.disable_breakpad_reporting) {
497 crash_reporter_.reset(CreateCrashReporter(logger()).release()); 536 // This will create the crash reporter with a preference for creating a
537 // reporter of the hinted type. If such a reporter isn't available, it will
538 // fall back to trying to create the most 'modern' reporter available.
539 crash_reporter_.reset(CreateCrashReporterWithTypeHint(
540 logger(), crash_reporter_type).release());
541 }
498 542
499 // Set up the appropriate error handler depending on whether or not 543 // Set up the appropriate error handler depending on whether or not
500 // we successfully found a crash reporter. 544 // we successfully initialized a crash reporter.
501 if (crash_reporter_.get() != nullptr) { 545 if (crash_reporter_.get() != nullptr) {
502 logger_->Write(base::StringPrintf( 546 logger_->Write(base::StringPrintf(
503 "SyzyASAN: Using %s for error reporting.", 547 "SyzyASAN: Using %s for error reporting.",
504 crash_reporter_->GetName())); 548 crash_reporter_->GetName()));
505 SetErrorCallBack(base::Bind(&CrashReporterErrorHandler)); 549 SetErrorCallBack(base::Bind(&CrashReporterErrorHandler));
506 } else { 550 } else {
507 logger_->Write("SyzyASAN: Using default error reporting handler."); 551 logger_->Write("SyzyASAN: Using default error reporting handler.");
508 SetErrorCallBack(base::Bind(&DefaultErrorHandler)); 552 SetErrorCallBack(base::Bind(&DefaultErrorHandler));
509 } 553 }
510 554
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 } 998 }
955 999
956 // Print the Windbg information to display the free stack if present. 1000 // Print the Windbg information to display the free stack if present.
957 if (error_info->block_info.free_stack_size != NULL) { 1001 if (error_info->block_info.free_stack_size != NULL) {
958 AsanDbgMessage(L"Free stack trace:"); 1002 AsanDbgMessage(L"Free stack trace:");
959 AsanDbgCmd(L"dps %p l%d", error_info->block_info.free_stack, 1003 AsanDbgCmd(L"dps %p l%d", error_info->block_info.free_stack,
960 error_info->block_info.free_stack_size); 1004 error_info->block_info.free_stack_size);
961 } 1005 }
962 } 1006 }
963 1007
1008 // static
964 AsanFeatureSet AsanRuntime::GenerateRandomFeatureSet() { 1009 AsanFeatureSet AsanRuntime::GenerateRandomFeatureSet() {
965 AsanFeatureSet enabled_features = 1010 AsanFeatureSet enabled_features =
966 static_cast<AsanFeatureSet>(base::RandGenerator(ASAN_FEATURE_MAX)); 1011 static_cast<AsanFeatureSet>(base::RandGenerator(ASAN_FEATURE_MAX));
967 DCHECK_LT(enabled_features, ASAN_FEATURE_MAX); 1012 DCHECK_LT(enabled_features, ASAN_FEATURE_MAX);
968 enabled_features &= kAsanValidFeatures; 1013 enabled_features &= kAsanValidFeatures;
969 return enabled_features; 1014 return enabled_features;
970 } 1015 }
971 1016
972 void AsanRuntime::PropagateFeatureSet(AsanFeatureSet feature_set) { 1017 void AsanRuntime::PropagateFeatureSet(AsanFeatureSet feature_set) {
973 DCHECK_EQ(0U, feature_set & ~kAsanValidFeatures); 1018 DCHECK_EQ(0U, feature_set & ~kAsanValidFeatures);
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
1192 DCHECK(heap_manager_); 1237 DCHECK(heap_manager_);
1193 heap_manager_->DisableDeferredFreeThread(); 1238 heap_manager_->DisableDeferredFreeThread();
1194 } 1239 }
1195 1240
1196 AsanFeatureSet AsanRuntime::GetEnabledFeatureSet() { 1241 AsanFeatureSet AsanRuntime::GetEnabledFeatureSet() {
1197 AsanFeatureSet enabled_features = static_cast<AsanFeatureSet>(0U); 1242 AsanFeatureSet enabled_features = static_cast<AsanFeatureSet>(0U);
1198 if (heap_manager_->enable_page_protections_) 1243 if (heap_manager_->enable_page_protections_)
1199 enabled_features |= ASAN_FEATURE_ENABLE_PAGE_PROTECTIONS; 1244 enabled_features |= ASAN_FEATURE_ENABLE_PAGE_PROTECTIONS;
1200 if (params_.enable_large_block_heap) 1245 if (params_.enable_large_block_heap)
1201 enabled_features |= ASAN_FEATURE_ENABLE_LARGE_BLOCK_HEAP; 1246 enabled_features |= ASAN_FEATURE_ENABLE_LARGE_BLOCK_HEAP;
1247 if (crash_reporter_.get() != nullptr &&
1248 crash_reporter_->GetName() == reporters::CrashpadReporter::kName) {
1249 enabled_features |= ASAN_FEATURE_ENABLE_CRASHPAD;
1250 }
1202 1251
1203 return enabled_features; 1252 return enabled_features;
1204 } 1253 }
1205 1254
1206 } // namespace asan 1255 } // namespace asan
1207 } // namespace agent 1256 } // namespace agent
OLDNEW
« no previous file with comments | « syzygy/agent/asan/runtime.h ('k') | syzygy/agent/asan/runtime_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698