diff options
author | siggi@chromium.org <siggi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-01 21:33:28 +0000 |
---|---|---|
committer | siggi@chromium.org <siggi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-01 21:33:28 +0000 |
commit | 9e95fd3e871e0bb43c08329e113965ea6d140837 (patch) | |
tree | acdc4eab0476fc20a0b633b63a539601928dd1ce /chrome/installer | |
parent | 7d0d57e4f016f17a951102ab8fc04273b9f15a7c (diff) | |
download | chromium_src-9e95fd3e871e0bb43c08329e113965ea6d140837.zip chromium_src-9e95fd3e871e0bb43c08329e113965ea6d140837.tar.gz chromium_src-9e95fd3e871e0bb43c08329e113965ea6d140837.tar.bz2 |
Tweak minidump flags to include a little more detail.
In release channel this adds PEB/TEB and the unloaded module list to crash dumps.
In dev/beta channel builds this additionally adds stack-referenced memory to crash dumps.
For full memory dumps, this adds capture of the PEB/TEB, unloaded module list and all handle information.
These minidump flags have been verified safe against the DbgHelp.dll version shipping with XP SP2 and later.
Move some code from platform_util to install_util to allow reusing it in the chrome exe project.
Add a test for the additional install_util code.
BUG=32441
TEST=Unittests in this change.
Review URL: http://codereview.chromium.org/659001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40300 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/installer')
-rw-r--r-- | chrome/installer/installer.gyp | 1 | ||||
-rw-r--r-- | chrome/installer/util/google_update_settings.cc | 25 | ||||
-rw-r--r-- | chrome/installer/util/google_update_settings.h | 5 | ||||
-rw-r--r-- | chrome/installer/util/google_update_settings_unittest.cc | 153 |
4 files changed, 184 insertions, 0 deletions
diff --git a/chrome/installer/installer.gyp b/chrome/installer/installer.gyp index 818817d..6d4a832 100644 --- a/chrome/installer/installer.gyp +++ b/chrome/installer/installer.gyp @@ -86,6 +86,7 @@ 'util/delete_reg_value_work_item_unittest.cc', 'util/delete_tree_work_item_unittest.cc', 'util/google_chrome_distribution_unittest.cc', + 'util/google_update_settings_unittest.cc', 'util/helper_unittest.cc', 'util/installer_util_unittests.rc', 'util/installer_util_unittests_resource.h', diff --git a/chrome/installer/util/google_update_settings.cc b/chrome/installer/util/google_update_settings.cc index a5298e5..2dabe50 100644 --- a/chrome/installer/util/google_update_settings.cc +++ b/chrome/installer/util/google_update_settings.cc @@ -143,3 +143,28 @@ bool GoogleUpdateSettings::ClearReferral() { return ClearGoogleUpdateStrKey(google_update::kRegReferralField); } +bool GoogleUpdateSettings::GetChromeChannel(std::wstring* channel) { + std::wstring update_branch; + if (!ReadGoogleUpdateStrKey(google_update::kRegApField, &update_branch)) { + *channel = L"unknown"; + return false; + } + + // Map to something pithy for human consumption. There are no rules as to + // what the ap string can contain, but generally it will contain a number + // followed by a dash followed by the branch name (and then some random + // suffix). We fall back on empty string in case we fail to parse. + // Only ever return "", "unknown", "dev" or "beta". + if (update_branch.find(L"-beta") != std::wstring::npos) + *channel = L"beta"; + else if (update_branch.find(L"-dev") != std::wstring::npos) + *channel = L"dev"; + else if (update_branch.empty()) + *channel = L""; + else + *channel = L"unknown"; + + return true; +} + + diff --git a/chrome/installer/util/google_update_settings.h b/chrome/installer/util/google_update_settings.h index 06adb44..3edfedf 100644 --- a/chrome/installer/util/google_update_settings.h +++ b/chrome/installer/util/google_update_settings.h @@ -78,6 +78,11 @@ class GoogleUpdateSettings { // true if this operation succeeded. static bool ClearReferral(); + // Return a human readable modifier for the version string, e.g. + // the channel (dev, beta, stable). Returns true if this operation succeeded, + // on success, channel contains one of "", "unknown", "dev" or "beta". + static bool GetChromeChannel(std::wstring* channel); + private: DISALLOW_IMPLICIT_CONSTRUCTORS(GoogleUpdateSettings); }; diff --git a/chrome/installer/util/google_update_settings_unittest.cc b/chrome/installer/util/google_update_settings_unittest.cc new file mode 100644 index 0000000..bb2e46c --- /dev/null +++ b/chrome/installer/util/google_update_settings_unittest.cc @@ -0,0 +1,153 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <windows.h> + +#include "base/registry.h" +#include "chrome/installer/util/browser_distribution.h" +#include "chrome/installer/util/google_update_settings.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { +const wchar_t* kHKCUReplacement = + L"Software\\Google\\InstallUtilUnittest\\HKCU"; +const wchar_t* kHKLMReplacement = + L"Software\\Google\\InstallUtilUnittest\\HKLM"; + +// This test fixture redirects the HKLM and HKCU registry hives for +// the duration of the test to make it independent of the machine +// and user settings. +class GoogleUpdateSettingsTest: public testing::Test { + protected: + virtual void SetUp() { + // Wipe the keys we redirect to. + // This gives us a stable run, even in the presence of previous + // crashes or failures. + LSTATUS err = SHDeleteKey(HKEY_CURRENT_USER, kHKCUReplacement); + EXPECT_TRUE(err == ERROR_SUCCESS || err == ERROR_FILE_NOT_FOUND); + err = SHDeleteKey(HKEY_CURRENT_USER, kHKLMReplacement); + EXPECT_TRUE(err == ERROR_SUCCESS || err == ERROR_FILE_NOT_FOUND); + + // Create the keys we're redirecting HKCU and HKLM to. + ASSERT_TRUE(hkcu_.Create(HKEY_CURRENT_USER, kHKCUReplacement)); + ASSERT_TRUE(hklm_.Create(HKEY_CURRENT_USER, kHKLMReplacement)); + + // And do the switcharoo. + ASSERT_EQ(ERROR_SUCCESS, + ::RegOverridePredefKey(HKEY_CURRENT_USER, hkcu_.Handle())); + ASSERT_EQ(ERROR_SUCCESS, + ::RegOverridePredefKey(HKEY_LOCAL_MACHINE, hklm_.Handle())); + } + + virtual void TearDown() { + // Undo the redirection. + EXPECT_EQ(ERROR_SUCCESS, ::RegOverridePredefKey(HKEY_CURRENT_USER, NULL)); + EXPECT_EQ(ERROR_SUCCESS, ::RegOverridePredefKey(HKEY_LOCAL_MACHINE, NULL)); + + // Close our handles and delete the temp keys we redirected to. + hkcu_.Close(); + hklm_.Close(); + EXPECT_EQ(ERROR_SUCCESS, SHDeleteKey(HKEY_CURRENT_USER, kHKCUReplacement)); + EXPECT_EQ(ERROR_SUCCESS, SHDeleteKey(HKEY_CURRENT_USER, kHKLMReplacement)); + } + + enum SystemUserInstall { + SYSTEM_INSTALL, + USER_INSTALL, + }; + + void SetApField(SystemUserInstall is_system, const wchar_t* value) { + HKEY root = is_system == SYSTEM_INSTALL ? + HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; + + RegKey update_key; + BrowserDistribution* dist = BrowserDistribution::GetDistribution(); + std::wstring path = dist->GetStateKey(); + ASSERT_TRUE(update_key.Create(root, path.c_str(), KEY_WRITE)); + ASSERT_TRUE(update_key.WriteValue(L"ap", value)); + } + + // Tests setting the ap= value to various combinations of values with + // prefixes and suffixes, while asserting on the correct channel value. + // Note that any non-empty ap= value that doesn't match ".*-{dev|beta}.*" + // will return the "unknown" channel. + void TestCurrentChromeChannelWithVariousApValues(SystemUserInstall install) { + static struct Expectations { + const wchar_t* ap_value; + const wchar_t* channel; + } expectations[] = { + { L"dev", L"unknown" }, + { L"-dev", L"dev" }, + { L"-developer", L"dev" }, + { L"beta", L"unknown" }, + { L"-beta", L"beta" }, + { L"-betamax", L"beta" }, + }; + bool is_system = install == SYSTEM_INSTALL; + const wchar_t* prefixes[] = { + L"", + L"prefix", + L"prefix-with-dash", + }; + const wchar_t* suffixes[] = { + L"", + L"suffix", + L"suffix-with-dash", + }; + + for (size_t i = 0; i < arraysize(prefixes); ++i) { + for (size_t j = 0; j < arraysize(expectations); ++j) { + for (size_t k = 0; k < arraysize(suffixes); ++k) { + std::wstring ap = prefixes[i]; + ap += expectations[j].ap_value; + ap += suffixes[k]; + const wchar_t* channel = expectations[j].channel; + + SetApField(install, ap.c_str()); + std::wstring ret_channel; + + EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannel(&ret_channel)); + EXPECT_STREQ(channel, ret_channel.c_str()) + << "Expecting channel \"" << channel + << "\" for ap=\"" << ap << "\""; + } + } + } + } + + RegKey hkcu_; + RegKey hklm_; +}; + +} // namespace + +// Verify that we return failure on no registration. +TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelAbsent) { + std::wstring channel; + EXPECT_FALSE(GoogleUpdateSettings::GetChromeChannel(&channel)); + EXPECT_STREQ(L"unknown", channel.c_str()); +} + +// Test an empty Ap key for system and user. +TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelEmptySystem) { + SetApField(SYSTEM_INSTALL, L""); + std::wstring channel; + EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannel(&channel)); + EXPECT_STREQ(L"", channel.c_str()); +} + +TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelEmptyUser) { + SetApField(USER_INSTALL, L""); + std::wstring channel; + EXPECT_TRUE(GoogleUpdateSettings::GetChromeChannel(&channel)); + EXPECT_STREQ(L"", channel.c_str()); +} + +TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelVariousApValuesSystem) { + TestCurrentChromeChannelWithVariousApValues(SYSTEM_INSTALL); +} + +TEST_F(GoogleUpdateSettingsTest, CurrentChromeChannelVariousApValuesUser) { + TestCurrentChromeChannelWithVariousApValues(USER_INSTALL); +} |