OLD | NEW |
---|---|
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 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
380 ->WriteCorruptHeapInfo(corrupt_ranges, size, buffer, error_info); \ | 380 ->WriteCorruptHeapInfo(corrupt_ranges, size, buffer, error_info); \ |
381 } \ | 381 } \ |
382 } | 382 } |
383 | 383 |
384 void LaunchMessageBox(const base::StringPiece& message) { | 384 void LaunchMessageBox(const base::StringPiece& message) { |
385 // TODO(chrisha): Consider making this close itself with a timeout to prevent | 385 // TODO(chrisha): Consider making this close itself with a timeout to prevent |
386 // hangs on the waterfall. | 386 // hangs on the waterfall. |
387 ::MessageBoxA(nullptr, message.data(), nullptr, MB_OK | MB_ICONEXCLAMATION); | 387 ::MessageBoxA(nullptr, message.data(), nullptr, MB_OK | MB_ICONEXCLAMATION); |
388 } | 388 } |
389 | 389 |
390 // Creates a crash reporter from the environment, if such an override is | |
391 // configured. | |
392 std::unique_ptr<ReporterInterface> CreateCrashReporterFromEnvironment( | |
Sigurður Ásgeirsson
2016/05/19 20:25:58
MaybeCreate?
chrisha
2016/05/31 20:45:15
Acknowledged.
| |
393 AsanLogger* logger) { | |
394 DCHECK_NE(static_cast<AsanLogger*>(nullptr), logger); | |
395 std::unique_ptr<ReporterInterface> reporter; | |
396 | |
397 std::unique_ptr<base::Environment> env(base::Environment::Create()); | |
398 std::string reporter_name; | |
399 if (!env->GetVar("SYZYASAN_CRASH_REPORTER", &reporter_name)) | |
400 return reporter; | |
401 | |
402 if (reporter_name == "crashpad") { | |
403 reporter.reset(reporters::CrashpadReporter::Create().release()); | |
404 } else if (reporter_name == "kasko") { | |
405 reporter.reset(reporters::KaskoReporter::Create().release()); | |
406 } else if (reporter_name == "breakpad") { | |
407 reporter.reset(reporters::BreakpadReporter::Create().release()); | |
408 } | |
409 | |
410 if (reporter.get() != nullptr) { | |
411 logger->Write(base::StringPrintf( | |
412 "Using requested \"%s\" crash reporter.", reporter_name.c_str())); | |
413 return reporter; | |
414 } else { | |
415 logger->Write(base::StringPrintf( | |
416 "Unable to create requested \"%s\" crash reporter.", | |
417 reporter_name.c_str())); | |
418 } | |
419 | |
420 return reporter; | |
421 } | |
422 | |
423 // Attempts to create a crash reporter, starting with the most modern. | |
390 std::unique_ptr<ReporterInterface> CreateCrashReporter(AsanLogger* logger) { | 424 std::unique_ptr<ReporterInterface> CreateCrashReporter(AsanLogger* logger) { |
391 std::unique_ptr<ReporterInterface> reporter; | 425 std::unique_ptr<ReporterInterface> reporter; |
392 | 426 |
393 // First try to grab the preferred crash reporter, overridden by the | 427 // Crashpad integration is not yet enabled by default. |
394 // environment. | |
395 std::unique_ptr<base::Environment> env(base::Environment::Create()); | |
396 std::string reporter_name; | |
397 if (env->GetVar("SYZYASAN_CRASH_REPORTER", &reporter_name)) { | |
398 if (reporter_name == "crashpad") | |
399 reporter.reset(reporters::CrashpadReporter::Create().release()); | |
400 else if (reporter_name == "kasko") | |
401 reporter.reset(reporters::KaskoReporter::Create().release()); | |
402 else if (reporter_name == "breakpad") | |
403 reporter.reset(reporters::BreakpadReporter::Create().release()); | |
404 | |
405 if (reporter.get() != nullptr) { | |
406 logger->Write(base::StringPrintf( | |
407 "Using requested \"%s\" crash reporter.", reporter_name)); | |
408 return reporter; | |
409 } else { | |
410 logger->Write(base::StringPrintf( | |
411 "Unable to create requested \"%s\" crash reporter.", reporter_name)); | |
412 } | |
413 } | |
414 | |
415 // No crash reporter was explicitly specified, or it was unable to be | |
416 // initialized. Try all of them, starting with the most recent. | |
417 | |
418 // Don't try grabbing a Crashpad reporter by default, as we're not yet | |
419 // ready to ship this. | |
420 // TODO(chrisha): Add Crashpad support behind a feature flag. | |
421 | 428 |
422 // Try to initialize a Kasko crash reporter. | 429 // Try to initialize a Kasko crash reporter. |
423 if (reporter.get() == nullptr) | 430 if (reporter.get() == nullptr) |
Sigurður Ásgeirsson
2016/05/19 20:25:58
this is a noop
chrisha
2016/05/31 20:45:15
Acknowledged.
| |
424 reporter.reset(reporters::KaskoReporter::Create().release()); | 431 reporter.reset(reporters::KaskoReporter::Create().release()); |
425 | 432 |
426 // If that failed then try to initialize a Breakpad reporter. | 433 // If that failed then try to initialize a Breakpad reporter. |
427 if (reporter.get() == nullptr) | 434 if (reporter.get() == nullptr) |
428 reporter.reset(reporters::BreakpadReporter::Create().release()); | 435 reporter.reset(reporters::BreakpadReporter::Create().release()); |
429 | 436 |
430 return reporter; | 437 return reporter; |
431 } | 438 } |
432 | 439 |
433 } // namespace | 440 } // namespace |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
476 if (!SetUpMemoryNotifier()) | 483 if (!SetUpMemoryNotifier()) |
477 return false; | 484 return false; |
478 if (!SetUpLogger()) | 485 if (!SetUpLogger()) |
479 return false; | 486 return false; |
480 if (!SetUpStackCache()) | 487 if (!SetUpStackCache()) |
481 return false; | 488 return false; |
482 if (!SetUpHeapManager()) | 489 if (!SetUpHeapManager()) |
483 return false; | 490 return false; |
484 WindowsHeapAdapter::SetUp(heap_manager_.get()); | 491 WindowsHeapAdapter::SetUp(heap_manager_.get()); |
485 | 492 |
493 // If the environment overrides randomized features or parameters then use | |
494 // it to initialize a crash reporter. | |
495 crash_reporter_.reset( | |
496 CreateCrashReporterFromEnvironment(logger()).release()); | |
497 | |
486 if (params_.feature_randomization) { | 498 if (params_.feature_randomization) { |
487 AsanFeatureSet feature_set = GenerateRandomFeatureSet(); | 499 AsanFeatureSet feature_set = GenerateRandomFeatureSet(); |
500 // If none is yet created, this call may potentially create a crash | |
501 // handler. | |
488 PropagateFeatureSet(feature_set); | 502 PropagateFeatureSet(feature_set); |
Sigurður Ásgeirsson
2016/05/19 20:25:58
I don't follow the logic in this file at all - the
chrisha
2016/05/19 20:31:31
I agree, it's scattered and messy. I really don't
Sigurður Ásgeirsson
2016/05/20 14:00:17
Filed https://github.com/google/syzygy/issues/45 a
| |
489 } | 503 } |
490 | 504 |
491 // Propagates the flags values to the different modules. | 505 // Propagates the flags values to the different modules. If none is yet |
506 // created, this call may potentially create a crash handler. | |
492 PropagateParams(); | 507 PropagateParams(); |
493 | 508 |
494 // The name 'disable_breakpad_reporting' is legacy; this actually means to | |
495 // disable all external crash reporting integration. | |
496 if (!params_.disable_breakpad_reporting) | |
497 crash_reporter_.reset(CreateCrashReporter(logger()).release()); | |
498 | |
499 // Set up the appropriate error handler depending on whether or not | 509 // Set up the appropriate error handler depending on whether or not |
500 // we successfully found a crash reporter. | 510 // we successfully initialized a crash reporter. |
501 if (crash_reporter_.get() != nullptr) { | 511 if (crash_reporter_.get() != nullptr) { |
502 logger_->Write(base::StringPrintf( | 512 logger_->Write(base::StringPrintf( |
503 "SyzyASAN: Using %s for error reporting.", | 513 "SyzyASAN: Using %s for error reporting.", |
504 crash_reporter_->GetName())); | 514 crash_reporter_->GetName())); |
505 SetErrorCallBack(base::Bind(&CrashReporterErrorHandler)); | 515 SetErrorCallBack(base::Bind(&CrashReporterErrorHandler)); |
506 } else { | 516 } else { |
507 logger_->Write("SyzyASAN: Using default error reporting handler."); | 517 logger_->Write("SyzyASAN: Using default error reporting handler."); |
508 SetErrorCallBack(base::Bind(&DefaultErrorHandler)); | 518 SetErrorCallBack(base::Bind(&DefaultErrorHandler)); |
509 } | 519 } |
510 | 520 |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
807 // Push the configured parameter values to the appropriate endpoints. | 817 // Push the configured parameter values to the appropriate endpoints. |
808 heap_manager_->set_parameters(params_); | 818 heap_manager_->set_parameters(params_); |
809 StackCaptureCache::set_compression_reporting_period(params_.reporting_period); | 819 StackCaptureCache::set_compression_reporting_period(params_.reporting_period); |
810 common::StackCapture::set_bottom_frames_to_skip( | 820 common::StackCapture::set_bottom_frames_to_skip( |
811 params_.bottom_frames_to_skip); | 821 params_.bottom_frames_to_skip); |
812 stack_cache_->set_max_num_frames(params_.max_num_frames); | 822 stack_cache_->set_max_num_frames(params_.max_num_frames); |
813 // ignored_stack_ids is used locally by AsanRuntime. | 823 // ignored_stack_ids is used locally by AsanRuntime. |
814 logger_->set_log_as_text(params_.log_as_text); | 824 logger_->set_log_as_text(params_.log_as_text); |
815 // exit_on_failure is used locally by AsanRuntime. | 825 // exit_on_failure is used locally by AsanRuntime. |
816 logger_->set_minidump_on_failure(params_.minidump_on_failure); | 826 logger_->set_minidump_on_failure(params_.minidump_on_failure); |
827 | |
828 // The name 'disable_breakpad_reporting' is legacy; this actually means to | |
829 // disable all external crash reporting integration. | |
830 if (!params_.disable_breakpad_reporting && crash_reporter_.get() == nullptr) | |
831 crash_reporter_.reset(CreateCrashReporter(logger()).release()); | |
817 } | 832 } |
818 | 833 |
819 size_t AsanRuntime::CalculateCorruptHeapInfoSize( | 834 size_t AsanRuntime::CalculateCorruptHeapInfoSize( |
820 const HeapChecker::CorruptRangesVector& corrupt_ranges) { | 835 const HeapChecker::CorruptRangesVector& corrupt_ranges) { |
821 size_t n = corrupt_ranges.size() * | 836 size_t n = corrupt_ranges.size() * |
822 (sizeof(AsanCorruptBlockRange) + sizeof(AsanBlockInfo)); | 837 (sizeof(AsanCorruptBlockRange) + sizeof(AsanBlockInfo)); |
823 return n; | 838 return n; |
824 } | 839 } |
825 | 840 |
826 void AsanRuntime::WriteCorruptHeapInfo( | 841 void AsanRuntime::WriteCorruptHeapInfo( |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
954 } | 969 } |
955 | 970 |
956 // Print the Windbg information to display the free stack if present. | 971 // Print the Windbg information to display the free stack if present. |
957 if (error_info->block_info.free_stack_size != NULL) { | 972 if (error_info->block_info.free_stack_size != NULL) { |
958 AsanDbgMessage(L"Free stack trace:"); | 973 AsanDbgMessage(L"Free stack trace:"); |
959 AsanDbgCmd(L"dps %p l%d", error_info->block_info.free_stack, | 974 AsanDbgCmd(L"dps %p l%d", error_info->block_info.free_stack, |
960 error_info->block_info.free_stack_size); | 975 error_info->block_info.free_stack_size); |
961 } | 976 } |
962 } | 977 } |
963 | 978 |
979 // static | |
964 AsanFeatureSet AsanRuntime::GenerateRandomFeatureSet() { | 980 AsanFeatureSet AsanRuntime::GenerateRandomFeatureSet() { |
965 AsanFeatureSet enabled_features = | 981 AsanFeatureSet enabled_features = |
966 static_cast<AsanFeatureSet>(base::RandGenerator(ASAN_FEATURE_MAX)); | 982 static_cast<AsanFeatureSet>(base::RandGenerator(ASAN_FEATURE_MAX)); |
967 DCHECK_LT(enabled_features, ASAN_FEATURE_MAX); | 983 DCHECK_LT(enabled_features, ASAN_FEATURE_MAX); |
968 enabled_features &= kAsanValidFeatures; | 984 enabled_features &= kAsanValidFeatures; |
969 return enabled_features; | 985 return enabled_features; |
970 } | 986 } |
971 | 987 |
972 void AsanRuntime::PropagateFeatureSet(AsanFeatureSet feature_set) { | 988 void AsanRuntime::PropagateFeatureSet(AsanFeatureSet feature_set) { |
973 DCHECK_EQ(0U, feature_set & ~kAsanValidFeatures); | 989 DCHECK_EQ(0U, feature_set & ~kAsanValidFeatures); |
974 heap_manager_->enable_page_protections_ = | 990 heap_manager_->enable_page_protections_ = |
975 (feature_set & ASAN_FEATURE_ENABLE_PAGE_PROTECTIONS) != 0; | 991 (feature_set & ASAN_FEATURE_ENABLE_PAGE_PROTECTIONS) != 0; |
976 params_.enable_large_block_heap = | 992 params_.enable_large_block_heap = |
977 (feature_set & ASAN_FEATURE_ENABLE_LARGE_BLOCK_HEAP) != 0; | 993 (feature_set & ASAN_FEATURE_ENABLE_LARGE_BLOCK_HEAP) != 0; |
994 if ((feature_set & ASAN_FEATURE_ENABLE_CRASHPAD) != 0 && | |
995 crash_reporter_.get() == nullptr) { | |
996 crash_reporter_.reset(reporters::CrashpadReporter::Create().release()); | |
997 } | |
978 } | 998 } |
979 | 999 |
980 void AsanRuntime::GetBadAccessInformation(AsanErrorInfo* error_info) { | 1000 void AsanRuntime::GetBadAccessInformation(AsanErrorInfo* error_info) { |
981 base::AutoLock lock(lock_); | 1001 base::AutoLock lock(lock_); |
982 | 1002 |
983 // Checks if this is an access to an internal structure or if it's an access | 1003 // Checks if this is an access to an internal structure or if it's an access |
984 // in the upper region of the memory (over the 2 GB limit). | 1004 // in the upper region of the memory (over the 2 GB limit). |
985 if ((reinterpret_cast<size_t>(error_info->location) & (1 << 31)) != 0 || | 1005 if ((reinterpret_cast<size_t>(error_info->location) & (1 << 31)) != 0 || |
986 shadow()->GetShadowMarkerForAddress(error_info->location) == | 1006 shadow()->GetShadowMarkerForAddress(error_info->location) == |
987 kAsanMemoryMarker) { | 1007 kAsanMemoryMarker) { |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1192 DCHECK(heap_manager_); | 1212 DCHECK(heap_manager_); |
1193 heap_manager_->DisableDeferredFreeThread(); | 1213 heap_manager_->DisableDeferredFreeThread(); |
1194 } | 1214 } |
1195 | 1215 |
1196 AsanFeatureSet AsanRuntime::GetEnabledFeatureSet() { | 1216 AsanFeatureSet AsanRuntime::GetEnabledFeatureSet() { |
1197 AsanFeatureSet enabled_features = static_cast<AsanFeatureSet>(0U); | 1217 AsanFeatureSet enabled_features = static_cast<AsanFeatureSet>(0U); |
1198 if (heap_manager_->enable_page_protections_) | 1218 if (heap_manager_->enable_page_protections_) |
1199 enabled_features |= ASAN_FEATURE_ENABLE_PAGE_PROTECTIONS; | 1219 enabled_features |= ASAN_FEATURE_ENABLE_PAGE_PROTECTIONS; |
1200 if (params_.enable_large_block_heap) | 1220 if (params_.enable_large_block_heap) |
1201 enabled_features |= ASAN_FEATURE_ENABLE_LARGE_BLOCK_HEAP; | 1221 enabled_features |= ASAN_FEATURE_ENABLE_LARGE_BLOCK_HEAP; |
1222 if (crash_reporter_->GetName() == reporters::CrashpadReporter::kName) | |
1223 enabled_features |= ASAN_FEATURE_ENABLE_CRASHPAD; | |
Sigurður Ásgeirsson
2016/05/20 14:00:17
Given I can't follow the code above, I'm not convi
chrisha
2016/05/31 20:45:15
Breakpad can't really happen unless manually overr
| |
1202 | 1224 |
1203 return enabled_features; | 1225 return enabled_features; |
1204 } | 1226 } |
1205 | 1227 |
1206 } // namespace asan | 1228 } // namespace asan |
1207 } // namespace agent | 1229 } // namespace agent |
OLD | NEW |