Chromium Code Reviews| 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 |