| Index: chrome_frame/chrome_frame_reporting.cc
|
| diff --git a/chrome_frame/chrome_frame_reporting.cc b/chrome_frame/chrome_frame_reporting.cc
|
| index f9fa490d7427dbaf47e6f54caf834bf24866f400..b77d3be9e74a368462e1579ad355cb6a42044900 100644
|
| --- a/chrome_frame/chrome_frame_reporting.cc
|
| +++ b/chrome_frame/chrome_frame_reporting.cc
|
| @@ -4,15 +4,26 @@
|
|
|
| // Implementation of wrapper around common crash reporting.
|
|
|
| +#include "chrome_frame/chrome_frame_reporting.h"
|
| +
|
| +#include "base/basictypes.h"
|
| #include "base/file_util.h"
|
| #include "base/file_version_info.h"
|
| +#include "base/lazy_instance.h"
|
| #include "base/win/win_util.h"
|
| #include "chrome/installer/util/google_update_settings.h"
|
| #include "chrome/installer/util/install_util.h"
|
| -#include "chrome_frame/chrome_frame_reporting.h"
|
| +#include "chrome_frame/crash_reporting/crash_report.h"
|
| #include "chrome_frame/exception_barrier.h"
|
| #include "chrome_frame/utils.h"
|
|
|
| +extern "C" IMAGE_DOS_HEADER __ImageBase;
|
| +
|
| +namespace {
|
| +
|
| +base::LazyInstance<CrashReportingManager>::Leaky g_crash_reporting_manager =
|
| + LAZY_INSTANCE_INITIALIZER;
|
| +
|
| // Well known SID for the system principal.
|
| const wchar_t kSystemPrincipalSid[] = L"S-1-5-18";
|
| const wchar_t kChromePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices";
|
| @@ -45,15 +56,13 @@ google_breakpad::CustomClientInfo* GetCustomInfo(const wchar_t* dll_path) {
|
| return &custom_info;
|
| }
|
|
|
| -extern "C" IMAGE_DOS_HEADER __ImageBase;
|
| -
|
| bool InitializeCrashReporting() {
|
| // In headless mode we want crashes to be reported back.
|
| bool always_take_dump = IsHeadlessMode();
|
| // We want to use the Google Update crash reporting. We need to check if the
|
| // user allows it first.
|
| if (!always_take_dump && !GoogleUpdateSettings::GetCollectStatsConsent())
|
| - return true;
|
| + return true;
|
|
|
| // If we got here, we want to report crashes, so make sure all
|
| // ExceptionBarrierBase instances do so.
|
| @@ -61,17 +70,16 @@ bool InitializeCrashReporting() {
|
|
|
| // Get the alternate dump directory. We use the temp path.
|
| base::FilePath temp_directory;
|
| - if (!file_util::GetTempDir(&temp_directory) || temp_directory.empty()) {
|
| + if (!file_util::GetTempDir(&temp_directory) || temp_directory.empty())
|
| return false;
|
| - }
|
|
|
| wchar_t dll_path[MAX_PATH * 2] = {0};
|
| GetModuleFileName(reinterpret_cast<HMODULE>(&__ImageBase), dll_path,
|
| arraysize(dll_path));
|
|
|
| if (always_take_dump) {
|
| - return InitializeVectoredCrashReportingWithPipeName(true, kChromePipeName,
|
| - temp_directory.value(), GetCustomInfo(dll_path));
|
| + return InitializeVectoredCrashReportingWithPipeName(
|
| + true, kChromePipeName, temp_directory.value(), GetCustomInfo(dll_path));
|
| }
|
|
|
| // Build the pipe name. It can be either:
|
| @@ -79,18 +87,77 @@ bool InitializeCrashReporting() {
|
| // Per-user install: "NamedPipe\GoogleCrashServices\<user SID>"
|
| std::wstring user_sid;
|
| if (InstallUtil::IsPerUserInstall(dll_path)) {
|
| - if (!base::win::GetUserSidString(&user_sid)) {
|
| + if (!base::win::GetUserSidString(&user_sid))
|
| return false;
|
| - }
|
| } else {
|
| user_sid = kSystemPrincipalSid;
|
| }
|
|
|
| - return InitializeVectoredCrashReporting(false, user_sid.c_str(),
|
| - temp_directory.value(), GetCustomInfo(dll_path));
|
| + return InitializeVectoredCrashReporting(
|
| + false, user_sid.c_str(), temp_directory.value(), GetCustomInfo(dll_path));
|
| }
|
|
|
| bool ShutdownCrashReporting() {
|
| ExceptionBarrierConfig::set_enabled(false);
|
| return ShutdownVectoredCrashReporting();
|
| }
|
| +
|
| +} // namespace
|
| +
|
| +// static
|
| +void CrashReportingManager::Decommit() {
|
| + CrashReportingManager& instance = Get();
|
| + base::AutoLock auto_lock(instance.lock_);
|
| + instance.committed_ = false;
|
| + instance.ShutdownIfNotCommittedAndUnreferenced();
|
| +}
|
| +
|
| +CrashReportingManager::CrashReportingManager()
|
| + : ref_count_(0),
|
| + initialized_(false),
|
| + committed_(false) {}
|
| +
|
| +CrashReportingManager::~CrashReportingManager() {
|
| + // The one and only instance of this class is leaked.
|
| + NOTREACHED();
|
| +}
|
| +
|
| +// static
|
| +CrashReportingManager& CrashReportingManager::Get() {
|
| + return g_crash_reporting_manager.Get();
|
| +}
|
| +
|
| +void CrashReportingManager::AddRef() {
|
| + base::AutoLock auto_lock(lock_);
|
| + DCHECK_LT(ref_count_, kuint32max);
|
| + ++ref_count_;
|
| +
|
| + if (!initialized_) {
|
| + initialized_ = true;
|
| + InitializeCrashReporting();
|
| + }
|
| +}
|
| +
|
| +void CrashReportingManager::Release() {
|
| + base::AutoLock auto_lock(lock_);
|
| +
|
| + DCHECK_GT(ref_count_, 0U);
|
| + if (--ref_count_ == 0)
|
| + ShutdownIfNotCommittedAndUnreferenced();
|
| +}
|
| +
|
| +void CrashReportingManager::Commit() {
|
| + base::AutoLock auto_lock(lock_);
|
| + DCHECK_NE(ref_count_, 0U);
|
| + committed_ = true;
|
| +}
|
| +
|
| +// Shuts down crash reporting if no scoper has committed to keeping reporting
|
| +// alive and no scopers are currently active.
|
| +void CrashReportingManager::ShutdownIfNotCommittedAndUnreferenced() {
|
| + lock_.AssertAcquired();
|
| + if (initialized_ && !committed_ && ref_count_ == 0) {
|
| + initialized_ = false;
|
| + ShutdownCrashReporting();
|
| + }
|
| +}
|
|
|