diff options
author | mad@chromium.org <mad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-15 21:49:22 +0000 |
---|---|---|
committer | mad@chromium.org <mad@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-15 21:49:22 +0000 |
commit | 53556e1b386f14de94d97351e47774b97c0ed753 (patch) | |
tree | 28af40eb2fad4715b62b7a9d6947cb2690a8d447 | |
parent | f08e47dbfce4823386bef263924be4836d7d8f86 (diff) | |
download | chromium_src-53556e1b386f14de94d97351e47774b97c0ed753.zip chromium_src-53556e1b386f14de94d97351e47774b97c0ed753.tar.gz chromium_src-53556e1b386f14de94d97351e47774b97c0ed753.tar.bz2 |
Committing for Steven who got LGTM from here:
http://codereview.chromium.org/264068
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/276050
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29196 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome_frame/chrome_frame.gyp | 8 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_reporting.cc | 68 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_reporting.h | 23 | ||||
-rw-r--r-- | chrome_frame/chrome_launcher.cc | 1 | ||||
-rw-r--r-- | chrome_frame/chrome_tab.cc | 4 | ||||
-rw-r--r-- | chrome_frame/crash_report.cc | 144 | ||||
-rw-r--r-- | chrome_frame/crash_report.h | 13 | ||||
-rw-r--r-- | chrome_frame/crash_reporting/crash_report.cc | 101 | ||||
-rw-r--r-- | chrome_frame/crash_reporting/crash_report.h | 21 | ||||
-rw-r--r-- | chrome_frame/crash_reporting/crash_reporting.gyp | 42 | ||||
-rw-r--r-- | chrome_frame/crash_reporting/vectored_handler-impl.h (renamed from chrome_frame/vectored_handler-impl.h) | 212 | ||||
-rw-r--r-- | chrome_frame/crash_reporting/vectored_handler.h (renamed from chrome_frame/vectored_handler.h) | 174 | ||||
-rw-r--r-- | chrome_frame/test/chrome_frame_unittests.cc | 2 |
13 files changed, 455 insertions, 358 deletions
diff --git a/chrome_frame/chrome_frame.gyp b/chrome_frame/chrome_frame.gyp index 31e0064..a84b874 100644 --- a/chrome_frame/chrome_frame.gyp +++ b/chrome_frame/chrome_frame.gyp @@ -616,6 +616,8 @@ 'chrome_frame_activex.rgs',
'chrome_frame_npapi.rgs',
'chrome_frame_npapi_entrypoints.cc',
+ 'chrome_frame_reporting.cc',
+ 'chrome_frame_reporting.h',
'chrome_protocol.cc',
'chrome_protocol.h',
'chrome_protocol.rgs',
@@ -632,8 +634,6 @@ 'com_message_event.h',
'com_type_info_holder.cc',
'com_type_info_holder.h',
- 'crash_report.cc',
- 'crash_report.h',
'ff_30_privilege_check.cc',
'ff_privilege_check.h',
'find_dialog.cc',
@@ -654,8 +654,6 @@ 'urlmon_url_request.h',
'urlmon_upload_data_stream.cc',
'urlmon_upload_data_stream.h',
- 'vectored_handler-impl.h',
- 'vectored_handler.h',
'vtable_patch_manager.cc',
'vtable_patch_manager.h',
'chrome_frame_histograms.h',
@@ -686,6 +684,8 @@ # Installer
'../chrome/installer/installer.gyp:installer_util',
'../google_update/google_update.gyp:google_update',
+ # Crash Reporting
+ 'crash_reporting/crash_reporting.gyp:crash_report',
],
'msvs_settings': {
'VCLinkerTool': {
diff --git a/chrome_frame/chrome_frame_reporting.cc b/chrome_frame/chrome_frame_reporting.cc new file mode 100644 index 0000000..c2cc282 --- /dev/null +++ b/chrome_frame/chrome_frame_reporting.cc @@ -0,0 +1,68 @@ +// Copyright (c) 2009 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. + +// Implementation of wrapper around common crash reporting. + +#include "base/file_util.h" +#include "base/logging.h" +#include "base/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" + +// Well known SID for the system principal. +const wchar_t kSystemPrincipalSid[] = L"S-1-5-18"; + +// Returns the custom info structure based on the dll in parameter and the +// process type. +google_breakpad::CustomClientInfo* GetCustomInfo() { + // TODO(joshia): Grab these based on build. + static google_breakpad::CustomInfoEntry ver_entry(L"ver", L"0.1.0.0"); + static google_breakpad::CustomInfoEntry prod_entry(L"prod", L"ChromeFrame"); + static google_breakpad::CustomInfoEntry plat_entry(L"plat", L"Win32"); + static google_breakpad::CustomInfoEntry type_entry(L"ptype", L"chrome_frame"); + static google_breakpad::CustomInfoEntry entries[] = { + ver_entry, prod_entry, plat_entry, type_entry }; + static google_breakpad::CustomClientInfo custom_info = { + entries, arraysize(entries) }; + return &custom_info; +} + +extern "C" IMAGE_DOS_HEADER __ImageBase; + +bool InitializeCrashReporting() { + // We want to use the Google Update crash reporting. We need to check if the + // user allows it first. + if (!GoogleUpdateSettings::GetCollectStatsConsent()) + return true; + + // Build the pipe name. It can be either: + // System-wide install: "NamedPipe\GoogleCrashServices\S-1-5-18" + // Per-user install: "NamedPipe\GoogleCrashServices\<user SID>" + wchar_t dll_path[MAX_PATH * 2] = {0}; + GetModuleFileName(reinterpret_cast<HMODULE>(&__ImageBase), dll_path, + arraysize(dll_path)); + + std::wstring user_sid; + if (InstallUtil::IsPerUserInstall(dll_path)) { + if (!win_util::GetUserSidString(&user_sid)) { + return false; + } + } else { + user_sid = kSystemPrincipalSid; + } + + // Get the alternate dump directory. We use the temp path. + FilePath temp_directory; + if (!file_util::GetTempDir(&temp_directory) || temp_directory.empty()) { + return false; + } + + return InitializeVectoredCrashReporting(false, user_sid.c_str(), + temp_directory.value(), GetCustomInfo()); +} + +bool ShutdownCrashReporting() { + return ShutdownVectoredCrashReporting(); +} diff --git a/chrome_frame/chrome_frame_reporting.h b/chrome_frame/chrome_frame_reporting.h new file mode 100644 index 0000000..94bfbdc --- /dev/null +++ b/chrome_frame/chrome_frame_reporting.h @@ -0,0 +1,23 @@ +// Copyright (c) 2009 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. + +// A wrapper around common crash reporting code to manage reporting for Chrome +// Frame. + +#ifndef CHROME_FRAME_CHROME_FRAME_REPORTING_H_ +#define CHROME_FRAME_CHROME_FRAME_REPORTING_H_ + +#include "chrome_frame/crash_reporting/crash_report.h" + +extern const wchar_t kSystemPrincipalSid[]; + +// Intialize crash reporting for Chrome Frame. Specific parameters here include +// using the temp directory for dumps, determining if the install is system +// wide or user specific, and customized client info. +bool InitializeCrashReporting(); + +// Shut down crash reporting for Chrome Frame. +bool ShutdownCrashReporting(); + +#endif // CHROME_FRAME_CHROME_FRAME_REPORTING_H_ diff --git a/chrome_frame/chrome_launcher.cc b/chrome_frame/chrome_launcher.cc index b9af23d..3ac0cc5 100644 --- a/chrome_frame/chrome_launcher.cc +++ b/chrome_frame/chrome_launcher.cc @@ -12,7 +12,6 @@ #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_switches.h" #include "chrome_frame/chrome_frame_automation.h" -#include "chrome_frame/crash_report.h" namespace chrome_launcher { diff --git a/chrome_frame/chrome_tab.cc b/chrome_frame/chrome_tab.cc index 601ef06..dab6aac 100644 --- a/chrome_frame/chrome_tab.cc +++ b/chrome_frame/chrome_tab.cc @@ -18,8 +18,8 @@ #include "grit/chrome_frame_resources.h" #include "chrome_frame/bho.h" #include "chrome_frame/chrome_frame_automation.h" +#include "chrome_frame/chrome_frame_reporting.h" #include "chrome_frame/chrome_launcher.h" -#include "chrome_frame/crash_report.h" #include "chrome_frame/resource.h" #include "chrome_frame/utils.h" @@ -124,7 +124,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, ATL::CTrace::s_trace.ChangeCategory(atlTraceRegistrar, 0, ATLTRACESTATUS_DISABLED); #endif - InitializeCrashReporting(false, false); + InitializeCrashReporting(); g_exit_manager = new base::AtExitManager(); CommandLine::Init(0, NULL); logging::InitLogging(NULL, logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, diff --git a/chrome_frame/crash_report.cc b/chrome_frame/crash_report.cc deleted file mode 100644 index 5a67316..0000000 --- a/chrome_frame/crash_report.cc +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2009 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.
-
-// crash_report.cc : Implementation crash reporting.
-#include "chrome_frame/crash_report.h"
-
-#include "base/file_util.h"
-#include "base/logging.h"
-#include "base/win_util.h"
-#include "breakpad/src/client/windows/handler/exception_handler.h"
-#include "chrome/installer/util/google_update_settings.h"
-#include "chrome/installer/util/install_util.h"
-#include "chrome_frame/vectored_handler.h"
-#include "chrome_frame/vectored_handler-impl.h"
-
-namespace {
-// TODO(joshia): factor out common code with chrome used for crash reporting
-const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\";
-const wchar_t kChromePipeName[] = L"\\\\.\\pipe\\ChromeCrashServices";
-// Well known SID for the system principal.
-const wchar_t kSystemPrincipalSid[] = L"S-1-5-18";
-google_breakpad::ExceptionHandler* g_breakpad = NULL;
-
-// Returns the custom info structure based on the dll in parameter and the
-// process type.
-google_breakpad::CustomClientInfo* GetCustomInfo() {
- // TODO(joshia): Grab these based on build.
- static google_breakpad::CustomInfoEntry ver_entry(L"ver", L"0.1.0.0");
- static google_breakpad::CustomInfoEntry prod_entry(L"prod", L"ChromeFrame");
- static google_breakpad::CustomInfoEntry plat_entry(L"plat", L"Win32");
- static google_breakpad::CustomInfoEntry type_entry(L"ptype", L"chrome_frame");
- static google_breakpad::CustomInfoEntry entries[] = {
- ver_entry, prod_entry, plat_entry, type_entry };
- static google_breakpad::CustomClientInfo custom_info = {
- entries, arraysize(entries) };
- return &custom_info;
-}
-
-__declspec(naked)
-static EXCEPTION_REGISTRATION_RECORD* InternalRtlpGetExceptionList() {
- __asm {
- mov eax, fs:0
- ret
- }
-}
-} // end of namespace
-
-// Class which methods simply forwards to Win32 API and uses breakpad to write
-// a minidump. Used as template (external interface) of VectoredHandlerT<E>.
-class Win32VEHTraits : public VEHTraitsBase {
- public:
- static inline void* Register(PVECTORED_EXCEPTION_HANDLER func,
- const void* module_start, const void* module_end) {
- VEHTraitsBase::SetModule(module_start, module_end);
- return ::AddVectoredExceptionHandler(1, func);
- }
-
- static inline ULONG Unregister(void* handle) {
- return ::RemoveVectoredExceptionHandler(handle);
- }
-
- static inline bool WriteDump(EXCEPTION_POINTERS* p) {
- return g_breakpad->WriteMinidumpForException(p);
- }
-
- static inline EXCEPTION_REGISTRATION_RECORD* RtlpGetExceptionList() {
- return InternalRtlpGetExceptionList();
- }
-
- static inline WORD RtlCaptureStackBackTrace(DWORD FramesToSkip,
- DWORD FramesToCapture, void** BackTrace, DWORD* BackTraceHash) {
- return ::RtlCaptureStackBackTrace(FramesToSkip, FramesToCapture,
- BackTrace, BackTraceHash);
- }
-};
-
-extern "C" IMAGE_DOS_HEADER __ImageBase;
-bool InitializeCrashReporting(bool use_crash_service, bool full_dump) {
- if (g_breakpad)
- return true;
-
- std::wstring pipe_name;
- if (use_crash_service) {
- // Crash reporting is done by crash_service.exe.
- pipe_name = kChromePipeName;
- } else {
- // We want to use the Google Update crash reporting. We need to check if the
- // user allows it first.
- if (!GoogleUpdateSettings::GetCollectStatsConsent())
- return true;
-
- // Build the pipe name. It can be either:
- // System-wide install: "NamedPipe\GoogleCrashServices\S-1-5-18"
- // Per-user install: "NamedPipe\GoogleCrashServices\<user SID>"
- wchar_t dll_path[MAX_PATH * 2] = {0};
- GetModuleFileName(reinterpret_cast<HMODULE>(&__ImageBase), dll_path,
- arraysize(dll_path));
-
- std::wstring user_sid;
- if (InstallUtil::IsPerUserInstall(dll_path)) {
- if (!win_util::GetUserSidString(&user_sid)) {
- return false;
- }
- } else {
- user_sid = kSystemPrincipalSid;
- }
-
- pipe_name = kGoogleUpdatePipeName;
- pipe_name += user_sid;
- }
-
- // Get the alternate dump directory. We use the temp path.
- FilePath temp_directory;
- if (!file_util::GetTempDir(&temp_directory) || temp_directory.empty()) {
- return false;
- }
-
- MINIDUMP_TYPE dump_type = full_dump ? MiniDumpWithFullMemory : MiniDumpNormal;
- g_breakpad = new google_breakpad::ExceptionHandler(
- temp_directory.value(), NULL, NULL, NULL,
- google_breakpad::ExceptionHandler::HANDLER_INVALID_PARAMETER |
- google_breakpad::ExceptionHandler::HANDLER_PURECALL, dump_type,
- pipe_name.c_str(), GetCustomInfo());
-
- if (g_breakpad) {
- // Find current module boundaries.
- const void* start = &__ImageBase;
- const char* s = reinterpret_cast<const char*>(start);
- const IMAGE_NT_HEADERS32* nt = reinterpret_cast<const IMAGE_NT_HEADERS32*>
- (s + __ImageBase.e_lfanew);
- const void* end = s + nt->OptionalHeader.SizeOfImage;
- VectoredHandler::Register(start, end);
- }
-
- return g_breakpad != NULL;
-}
-
-bool ShutdownCrashReporting() {
- VectoredHandler::Unregister();
- delete g_breakpad;
- g_breakpad = NULL;
- return true;
-}
diff --git a/chrome_frame/crash_report.h b/chrome_frame/crash_report.h deleted file mode 100644 index 3758e33..0000000 --- a/chrome_frame/crash_report.h +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2009 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.
-
-// crash_report.h : Declarations for crash reporting.
-
-#ifndef CHROME_FRAME_CRASH_REPORT_H_
-#define CHROME_FRAME_CRASH_REPORT_H_
-
-bool InitializeCrashReporting(bool use_crash_service, bool full_dump);
-bool ShutdownCrashReporting();
-
-#endif // CHROME_FRAME_CRASH_REPORT_H_
diff --git a/chrome_frame/crash_reporting/crash_report.cc b/chrome_frame/crash_reporting/crash_report.cc new file mode 100644 index 0000000..1c594c5 --- /dev/null +++ b/chrome_frame/crash_reporting/crash_report.cc @@ -0,0 +1,101 @@ +// Copyright (c) 2009 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. + +// crash_report.cc : Implementation crash reporting. +#include "chrome_frame/crash_reporting/crash_report.h" + +#include "base/basictypes.h" +#include "base/logging.h" +#include "breakpad/src/client/windows/handler/exception_handler.h" +#include "chrome_frame/crash_reporting/vectored_handler.h" +#include "chrome_frame/crash_reporting/vectored_handler-impl.h" + +namespace { +// TODO(joshia): factor out common code with chrome used for crash reporting +const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\"; +google_breakpad::ExceptionHandler* g_breakpad = NULL; + +__declspec(naked) +static EXCEPTION_REGISTRATION_RECORD* InternalRtlpGetExceptionList() { + __asm { + mov eax, fs:0 + ret + } +} +} // end of namespace + +// Class which methods simply forwards to Win32 API and uses breakpad to write +// a minidump. Used as template (external interface) of VectoredHandlerT<E>. +class Win32VEHTraits : public VEHTraitsBase { + public: + static inline void* Register(PVECTORED_EXCEPTION_HANDLER func, + const void* module_start, const void* module_end) { + VEHTraitsBase::SetModule(module_start, module_end); + return ::AddVectoredExceptionHandler(1, func); + } + + static inline ULONG Unregister(void* handle) { + return ::RemoveVectoredExceptionHandler(handle); + } + + static inline bool WriteDump(EXCEPTION_POINTERS* p) { + return g_breakpad->WriteMinidumpForException(p); + } + + static inline EXCEPTION_REGISTRATION_RECORD* RtlpGetExceptionList() { + return InternalRtlpGetExceptionList(); + } + + static inline WORD RtlCaptureStackBackTrace(DWORD FramesToSkip, + DWORD FramesToCapture, void** BackTrace, DWORD* BackTraceHash) { + return ::RtlCaptureStackBackTrace(FramesToSkip, FramesToCapture, + BackTrace, BackTraceHash); + } +}; + +extern "C" IMAGE_DOS_HEADER __ImageBase; + +bool InitializeVectoredCrashReporting( + bool full_dump, + const wchar_t* user_sid, + const std::wstring& dump_path, + google_breakpad::CustomClientInfo* client_info) { + DCHECK(user_sid); + DCHECK(client_info); + if (g_breakpad) + return true; + + std::wstring pipe_name(kGoogleUpdatePipeName); + pipe_name += user_sid; + + if (dump_path.empty()) { + return false; + } + + MINIDUMP_TYPE dump_type = full_dump ? MiniDumpWithFullMemory : MiniDumpNormal; + g_breakpad = new google_breakpad::ExceptionHandler( + dump_path, NULL, NULL, NULL, + google_breakpad::ExceptionHandler::HANDLER_INVALID_PARAMETER | + google_breakpad::ExceptionHandler::HANDLER_PURECALL, dump_type, + pipe_name.c_str(), client_info); + + if (g_breakpad) { + // Find current module boundaries. + const void* start = &__ImageBase; + const char* s = reinterpret_cast<const char*>(start); + const IMAGE_NT_HEADERS32* nt = reinterpret_cast<const IMAGE_NT_HEADERS32*> + (s + __ImageBase.e_lfanew); + const void* end = s + nt->OptionalHeader.SizeOfImage; + VectoredHandler::Register(start, end); + } + + return g_breakpad != NULL; +} + +bool ShutdownVectoredCrashReporting() { + VectoredHandler::Unregister(); + delete g_breakpad; + g_breakpad = NULL; + return true; +} diff --git a/chrome_frame/crash_reporting/crash_report.h b/chrome_frame/crash_reporting/crash_report.h new file mode 100644 index 0000000..0bcc89b --- /dev/null +++ b/chrome_frame/crash_reporting/crash_report.h @@ -0,0 +1,21 @@ +// Copyright (c) 2009 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. + +// crash_report.h : Declarations for crash reporting. + +#ifndef CHROME_FRAME_CRASH_REPORTING_CRASH_REPORT_H_ +#define CHROME_FRAME_CRASH_REPORTING_CRASH_REPORT_H_ + +#include <string> + +#include "breakpad/src/client/windows/handler/exception_handler.h" + +bool InitializeVectoredCrashReporting( + bool full_dump, + const wchar_t* user_sid, + const std::wstring& dump_path, + google_breakpad::CustomClientInfo* client_info); +bool ShutdownVectoredCrashReporting(); + +#endif // CHROME_FRAME_CRASH_REPORTING_CRASH_REPORT_H_ diff --git a/chrome_frame/crash_reporting/crash_reporting.gyp b/chrome_frame/crash_reporting/crash_reporting.gyp new file mode 100644 index 0000000..14c0156 --- /dev/null +++ b/chrome_frame/crash_reporting/crash_reporting.gyp @@ -0,0 +1,42 @@ +# Copyright (c) 2009 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. + +{ + 'includes': [ + '../../build/common.gypi', + ], + 'target_defaults': { + 'include_dirs': [ + # all our own includes are relative to src/ + '../..', + ], + }, + 'targets': [ + { + 'target_name': 'crash_report', + 'type': 'static_library', + 'sources': [ + 'crash_report.cc', + 'crash_report.h', + 'vectored_handler-impl.h', + 'vectored_handler.h', + ], + 'conditions': [ + ['OS=="win"', { + 'dependencies': [ + '../../breakpad/breakpad.gyp:breakpad_handler', + ], + }], + ], + }, + ], +} + +# vim: shiftwidth=2:et:ai:tabstop=2 + +# Local Variables: +# tab-width:2 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/chrome_frame/vectored_handler-impl.h b/chrome_frame/crash_reporting/vectored_handler-impl.h index f850641..5487f0a 100644 --- a/chrome_frame/vectored_handler-impl.h +++ b/chrome_frame/crash_reporting/vectored_handler-impl.h @@ -1,106 +1,106 @@ -// Copyright (c) 2009 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.
-
-#ifndef CHROME_FRAME_VECTORED_HANDLER_IMPL_H_
-#define CHROME_FRAME_VECTORED_HANDLER_IMPL_H_
-#include "chrome_frame/vectored_handler.h"
-
-#if defined(_M_IX86)
-typedef struct _EXCEPTION_REGISTRATION_RECORD {
- struct _EXCEPTION_REGISTRATION_RECORD* Next;
- PVOID Handler;
-} EXCEPTION_REGISTRATION_RECORD;
-#define EXCEPTION_CHAIN_END ((struct _EXCEPTION_REGISTRATION_RECORD*)-1)
-#else
-#error only x86 is supported for now.
-#endif
-
-
-// VEH handler flags settings.
-// These are grabbed from winnt.h for PocketPC.
-// Only EXCEPTION_NONCONTINUABLE in defined in "regular" winnt.h
-// #define EXCEPTION_NONCONTINUABLE 0x1 // Noncontinuable exception
-#define EXCEPTION_UNWINDING 0x2 // Unwind is in progress
-#define EXCEPTION_EXIT_UNWIND 0x4 // Exit unwind is in progress
-#define EXCEPTION_STACK_INVALID 0x8 // Stack out of limits or unaligned
-#define EXCEPTION_NESTED_CALL 0x10 // Nested exception handler call
-#define EXCEPTION_TARGET_UNWIND 0x20 // Target unwind in progress
-#define EXCEPTION_COLLIDED_UNWIND 0x40 // Collided exception handler call
-
-#define EXCEPTION_UNWIND (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND | \
- EXCEPTION_TARGET_UNWIND | EXCEPTION_COLLIDED_UNWIND)
-
-#define IS_UNWINDING(Flag) (((Flag) & EXCEPTION_UNWIND) != 0)
-#define IS_DISPATCHING(Flag) (((Flag) & EXCEPTION_UNWIND) == 0)
-#define IS_TARGET_UNWIND(Flag) ((Flag) & EXCEPTION_TARGET_UNWIND)
-// End of grabbed section
-
-template <class E>
-LONG WINAPI VectoredHandlerT<E>::VectoredHandler(
- EXCEPTION_POINTERS* exceptionInfo) {
- // TODO(stoyan): Consider reentrancy
- const DWORD exceptionCode = exceptionInfo->ExceptionRecord->ExceptionCode;
-
- // Not interested in non-error exceptions. In this category falls exceptions
- // like:
- // 0x40010006 - OutputDebugStringA. Seen when no debugger is attached
- // (otherwise debugger swallows the exception and prints
- // the string).
- // 0x406D1388 - DebuggerProbe. Used by debug CRT - for example see source
- // code of isatty(). Used to name a thread as well.
- // RPC_E_DISCONNECTED and Co. - COM IPC non-fatal warnings
- // STATUS_BREAKPOINT and Co. - Debugger related breakpoints
-
- if ((exceptionCode & ERROR_SEVERITY_ERROR) != ERROR_SEVERITY_ERROR) {
- return ExceptionContinueSearch;
- }
-
- ++VectoredHandlerT<E>::g_exceptions_seen;
-
- // TODO(stoyan): Check whether exception address is inbetween
- // [IsBadReadPtr, IsBadReadPtr + 0xXX]
-
- const DWORD exceptionFlags = exceptionInfo->ExceptionRecord->ExceptionFlags;
- // I don't think VEH is called on unwind. Just to be safe.
- if (IS_DISPATCHING(exceptionFlags)) {
- if (ModuleHasInstalledSEHFilter())
- return ExceptionContinueSearch;
-
- if (E::IsOurModule(exceptionInfo->ExceptionRecord->ExceptionAddress)) {
- E::WriteDump(exceptionInfo);
- return ExceptionContinueSearch;
- }
-
- // See whether our module is somewhere in the call stack.
- void* back_trace[max_back_trace] = {0};
- // Skip RtlCaptureStackBackTrace and VectoredHandler itself.
- DWORD captured = E::RtlCaptureStackBackTrace(2, max_back_trace - 2,
- &back_trace[0], NULL);
- for (DWORD i = 0; i < captured; ++i) {
- if (E::IsOurModule(back_trace[i])) {
- E::WriteDump(exceptionInfo);
- return ExceptionContinueSearch;
- }
- }
- }
-
- return ExceptionContinueSearch;
-}
-
-template <class E>
-BOOL VectoredHandlerT<E>::ModuleHasInstalledSEHFilter() {
- EXCEPTION_REGISTRATION_RECORD* RegistrationFrame = E::RtlpGetExceptionList();
- // TODO(stoyan): Add the stack limits check and some sanity checks like
- // decreasing addresses of registration records
- while (RegistrationFrame != EXCEPTION_CHAIN_END) {
- if (E::IsOurModule(RegistrationFrame->Handler)) {
- return TRUE;
- }
-
- RegistrationFrame = RegistrationFrame->Next;
- }
-
- return FALSE;
-}
-#endif // CHROME_FRAME_VECTORED_HANDLER_IMPL_H_
+// Copyright (c) 2009 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. + +#ifndef CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_IMPL_H_ +#define CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_IMPL_H_ +#include "chrome_frame/crash_reporting/vectored_handler.h" + +#if defined(_M_IX86) +typedef struct _EXCEPTION_REGISTRATION_RECORD { + struct _EXCEPTION_REGISTRATION_RECORD* Next; + PVOID Handler; +} EXCEPTION_REGISTRATION_RECORD; +#define EXCEPTION_CHAIN_END ((struct _EXCEPTION_REGISTRATION_RECORD*)-1) +#else +#error only x86 is supported for now. +#endif + + +// VEH handler flags settings. +// These are grabbed from winnt.h for PocketPC. +// Only EXCEPTION_NONCONTINUABLE in defined in "regular" winnt.h +// #define EXCEPTION_NONCONTINUABLE 0x1 // Noncontinuable exception +#define EXCEPTION_UNWINDING 0x2 // Unwind is in progress +#define EXCEPTION_EXIT_UNWIND 0x4 // Exit unwind is in progress +#define EXCEPTION_STACK_INVALID 0x8 // Stack out of limits or unaligned +#define EXCEPTION_NESTED_CALL 0x10 // Nested exception handler call +#define EXCEPTION_TARGET_UNWIND 0x20 // Target unwind in progress +#define EXCEPTION_COLLIDED_UNWIND 0x40 // Collided exception handler call + +#define EXCEPTION_UNWIND (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND | \ + EXCEPTION_TARGET_UNWIND | EXCEPTION_COLLIDED_UNWIND) + +#define IS_UNWINDING(Flag) (((Flag) & EXCEPTION_UNWIND) != 0) +#define IS_DISPATCHING(Flag) (((Flag) & EXCEPTION_UNWIND) == 0) +#define IS_TARGET_UNWIND(Flag) ((Flag) & EXCEPTION_TARGET_UNWIND) +// End of grabbed section + +template <class E> +LONG WINAPI VectoredHandlerT<E>::VectoredHandler( + EXCEPTION_POINTERS* exceptionInfo) { + // TODO(stoyan): Consider reentrancy + const DWORD exceptionCode = exceptionInfo->ExceptionRecord->ExceptionCode; + + // Not interested in non-error exceptions. In this category falls exceptions + // like: + // 0x40010006 - OutputDebugStringA. Seen when no debugger is attached + // (otherwise debugger swallows the exception and prints + // the string). + // 0x406D1388 - DebuggerProbe. Used by debug CRT - for example see source + // code of isatty(). Used to name a thread as well. + // RPC_E_DISCONNECTED and Co. - COM IPC non-fatal warnings + // STATUS_BREAKPOINT and Co. - Debugger related breakpoints + + if ((exceptionCode & ERROR_SEVERITY_ERROR) != ERROR_SEVERITY_ERROR) { + return ExceptionContinueSearch; + } + + ++VectoredHandlerT<E>::g_exceptions_seen; + + // TODO(stoyan): Check whether exception address is inbetween + // [IsBadReadPtr, IsBadReadPtr + 0xXX] + + const DWORD exceptionFlags = exceptionInfo->ExceptionRecord->ExceptionFlags; + // I don't think VEH is called on unwind. Just to be safe. + if (IS_DISPATCHING(exceptionFlags)) { + if (ModuleHasInstalledSEHFilter()) + return ExceptionContinueSearch; + + if (E::IsOurModule(exceptionInfo->ExceptionRecord->ExceptionAddress)) { + E::WriteDump(exceptionInfo); + return ExceptionContinueSearch; + } + + // See whether our module is somewhere in the call stack. + void* back_trace[max_back_trace] = {0}; + // Skip RtlCaptureStackBackTrace and VectoredHandler itself. + DWORD captured = E::RtlCaptureStackBackTrace(2, max_back_trace - 2, + &back_trace[0], NULL); + for (DWORD i = 0; i < captured; ++i) { + if (E::IsOurModule(back_trace[i])) { + E::WriteDump(exceptionInfo); + return ExceptionContinueSearch; + } + } + } + + return ExceptionContinueSearch; +} + +template <class E> +BOOL VectoredHandlerT<E>::ModuleHasInstalledSEHFilter() { + EXCEPTION_REGISTRATION_RECORD* RegistrationFrame = E::RtlpGetExceptionList(); + // TODO(stoyan): Add the stack limits check and some sanity checks like + // decreasing addresses of registration records + while (RegistrationFrame != EXCEPTION_CHAIN_END) { + if (E::IsOurModule(RegistrationFrame->Handler)) { + return TRUE; + } + + RegistrationFrame = RegistrationFrame->Next; + } + + return FALSE; +} +#endif // CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_IMPL_H_ diff --git a/chrome_frame/vectored_handler.h b/chrome_frame/crash_reporting/vectored_handler.h index 7351b6c..f3e08b0 100644 --- a/chrome_frame/vectored_handler.h +++ b/chrome_frame/crash_reporting/vectored_handler.h @@ -1,87 +1,87 @@ -// Copyright (c) 2009 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.
-
-#ifndef CHROME_FRAME_VECTORED_HANDLER_H_
-#define CHROME_FRAME_VECTORED_HANDLER_H_
-
-// Base class for VectoredHandlerT just to hold some members (independent of
-// template parameter)
-class VectoredHandlerBase {
- public:
- // For RtlCaptureStackBackTrace MSDN says:
- // Windows Server 2003 and Windows XP: The sum of the FramesToSkip and
- // FramesToCapture parameters must be less than 64.
- // In practice (on XPSP2) it has to be less than 63, hence leaving us with
- // max back trace of 62.
- static const DWORD max_back_trace = 62;
- static unsigned long g_exceptions_seen;
- protected:
- static void* g_handler;
-};
-
-DECLSPEC_SELECTANY void* VectoredHandlerBase::g_handler;
-DECLSPEC_SELECTANY unsigned long VectoredHandlerBase::g_exceptions_seen;
-
-// The E class is supposed to provide external/API functions. Using template
-// make testability easier. It shall confirm the following concept/archetype:
-// void* Register(PVECTORED_EXCEPTION_HANDLER,
-// const void* module_start, const void* module_end)
-// Registers Vectored Exception Handler, non-unittest implementation shall call
-// ::AddVectoredExceptionHandler Win32 API
-// ULONG Unregister(void*) - ::RemoveVectoredExceptionHandler Win32 API
-// int IsOurModule(const void* address) -
-// void WriteDump(EXCEPTION_POINTERS*) -
-// WORD RtlCaptureStackBackTrace(..) - same as Win32 API
-// EXCEPTION_REGISTRATION_RECORD* RtlpGetExceptionList() - same as Win32 API
-// You may want to derive own External class by deriving from
-// VEHExternalBase helper (see below).
-// Create dump policy:
-// 1. Scan SEH chain, if there is a handler/filter that belongs to our
-// module - assume we expect this one and hence do nothing here.
-// 2. If the address of the exception is in our module - create dump.
-// 3. If our module is in somewhere in callstack - create dump.
-template <class E>
-class VectoredHandlerT : public VectoredHandlerBase {
- public:
- static void* Register(const void* module_start, const void* module_end) {
- g_exceptions_seen = 0;
- g_handler = E::Register(&VectoredHandler, module_start, module_end);
- return g_handler;
- }
-
- static ULONG Unregister() {
- if (g_handler)
- return E::Unregister(g_handler);
- return 0;
- }
-
- static LONG WINAPI VectoredHandler(EXCEPTION_POINTERS* exceptionInfo);
- private:
- static BOOL ModuleHasInstalledSEHFilter();
-};
-
-// Handy class supposed to act as a base class for classes used as template
-// parameter of VectoredHandlerT<E>
-class VEHTraitsBase {
- public:
- static const void* g_module_start;
- static const void* g_module_end;
-
- static inline int IsOurModule(const void* address) {
- return (g_module_start <= address && address < g_module_end);
- }
-
- static inline void SetModule(const void* module_start,
- const void* module_end) {
- g_module_start = module_start;
- g_module_end = module_end;
- }
-};
-
-DECLSPEC_SELECTANY const void* VEHTraitsBase::g_module_start;
-DECLSPEC_SELECTANY const void* VEHTraitsBase::g_module_end;
-
-class Win32VEHTraits;
-typedef class VectoredHandlerT<Win32VEHTraits> VectoredHandler;
-#endif // CHROME_FRAME_VECTORED_HANDLER_H_
+// Copyright (c) 2009 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. + +#ifndef CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_ +#define CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_ + +// Base class for VectoredHandlerT just to hold some members (independent of +// template parameter) +class VectoredHandlerBase { + public: + // For RtlCaptureStackBackTrace MSDN says: + // Windows Server 2003 and Windows XP: The sum of the FramesToSkip and + // FramesToCapture parameters must be less than 64. + // In practice (on XPSP2) it has to be less than 63, hence leaving us with + // max back trace of 62. + static const DWORD max_back_trace = 62; + static unsigned long g_exceptions_seen; + protected: + static void* g_handler; +}; + +DECLSPEC_SELECTANY void* VectoredHandlerBase::g_handler; +DECLSPEC_SELECTANY unsigned long VectoredHandlerBase::g_exceptions_seen; + +// The E class is supposed to provide external/API functions. Using template +// make testability easier. It shall confirm the following concept/archetype: +// void* Register(PVECTORED_EXCEPTION_HANDLER, +// const void* module_start, const void* module_end) +// Registers Vectored Exception Handler, non-unittest implementation shall call +// ::AddVectoredExceptionHandler Win32 API +// ULONG Unregister(void*) - ::RemoveVectoredExceptionHandler Win32 API +// int IsOurModule(const void* address) - +// void WriteDump(EXCEPTION_POINTERS*) - +// WORD RtlCaptureStackBackTrace(..) - same as Win32 API +// EXCEPTION_REGISTRATION_RECORD* RtlpGetExceptionList() - same as Win32 API +// You may want to derive own External class by deriving from +// VEHExternalBase helper (see below). +// Create dump policy: +// 1. Scan SEH chain, if there is a handler/filter that belongs to our +// module - assume we expect this one and hence do nothing here. +// 2. If the address of the exception is in our module - create dump. +// 3. If our module is in somewhere in callstack - create dump. +template <class E> +class VectoredHandlerT : public VectoredHandlerBase { + public: + static void* Register(const void* module_start, const void* module_end) { + g_exceptions_seen = 0; + g_handler = E::Register(&VectoredHandler, module_start, module_end); + return g_handler; + } + + static ULONG Unregister() { + if (g_handler) + return E::Unregister(g_handler); + return 0; + } + + static LONG WINAPI VectoredHandler(EXCEPTION_POINTERS* exceptionInfo); + private: + static BOOL ModuleHasInstalledSEHFilter(); +}; + +// Handy class supposed to act as a base class for classes used as template +// parameter of VectoredHandlerT<E> +class VEHTraitsBase { + public: + static const void* g_module_start; + static const void* g_module_end; + + static inline int IsOurModule(const void* address) { + return (g_module_start <= address && address < g_module_end); + } + + static inline void SetModule(const void* module_start, + const void* module_end) { + g_module_start = module_start; + g_module_end = module_end; + } +}; + +DECLSPEC_SELECTANY const void* VEHTraitsBase::g_module_start; +DECLSPEC_SELECTANY const void* VEHTraitsBase::g_module_end; + +class Win32VEHTraits; +typedef class VectoredHandlerT<Win32VEHTraits> VectoredHandler; +#endif // CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_ diff --git a/chrome_frame/test/chrome_frame_unittests.cc b/chrome_frame/test/chrome_frame_unittests.cc index 206c6d6..8e1ad92 100644 --- a/chrome_frame/test/chrome_frame_unittests.cc +++ b/chrome_frame/test/chrome_frame_unittests.cc @@ -22,11 +22,11 @@ #include "chrome_frame/test/chrome_frame_unittests.h" #include "chrome_frame/chrome_frame_automation.h" #include "chrome_frame/chrome_frame_delegate.h" +#include "chrome_frame/crash_reporting/vectored_handler-impl.h" #include "chrome_frame/test/chrome_frame_test_utils.h" #include "chrome_frame/test/helper_gmock.h" #include "chrome_frame/test_utils.h" #include "chrome_frame/utils.h" -#include "chrome_frame/vectored_handler-impl.h" #include "chrome/installer/util/install_util.h" #include "chrome/installer/util/helper.h" |