Index: chrome_frame/chrome_tab.cc |
diff --git a/chrome_frame/chrome_tab.cc b/chrome_frame/chrome_tab.cc |
index 8b25a054daa7169bcf04aff5e838e1e385dde406..cea60f83a76593543b6d7ff308ed3fde34523476 100644 |
--- a/chrome_frame/chrome_tab.cc |
+++ b/chrome_frame/chrome_tab.cc |
@@ -11,6 +11,7 @@ |
#include <objbase.h> |
#include "base/at_exit.h" |
+#include "base/basictypes.h" |
#include "base/command_line.h" |
#include "base/file_util.h" |
#include "base/file_version_info.h" |
@@ -40,6 +41,7 @@ |
#include "chrome_frame/dll_redirector.h" |
#include "chrome_frame/exception_barrier.h" |
#include "chrome_frame/metrics_service.h" |
+#include "chrome_frame/pin_module.h" |
#include "chrome_frame/resource.h" |
#include "chrome_frame/utils.h" |
#include "googleurl/src/url_util.h" |
@@ -48,16 +50,6 @@ |
using base::win::RegKey; |
namespace { |
-// This function has the side effect of initializing an unprotected |
-// vector pointer inside GoogleUrl. If this is called during DLL loading, |
-// it has the effect of avoiding an initialization race on that pointer. |
-// TODO(siggi): fix GoogleUrl. |
-void InitGoogleUrl() { |
- static const char kDummyUrl[] = "http://www.google.com"; |
- |
- url_util::IsStandard(kDummyUrl, |
- url_parse::MakeRange(0, arraysize(kDummyUrl))); |
-} |
const wchar_t kInternetSettings[] = |
L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"; |
@@ -83,7 +75,7 @@ const wchar_t kChromeFrameHelperWindowName[] = |
L"ChromeFrameHelperWindowName"; |
// {0562BFC3-2550-45b4-BD8E-A310583D3A6F} |
-static const GUID kChromeFrameProvider = |
+const GUID kChromeFrameProvider = |
{ 0x562bfc3, 0x2550, 0x45b4, |
{ 0xbd, 0x8e, 0xa3, 0x10, 0x58, 0x3d, 0x3a, 0x6f } }; |
@@ -95,11 +87,22 @@ const wchar_t kChromeFramePrefix[] = L"chromeframe/"; |
// See comments in DllGetClassObject. |
LPFNGETCLASSOBJECT g_dll_get_class_object_redir_ptr = NULL; |
+// This function has the side effect of initializing an unprotected |
+// vector pointer inside GoogleUrl. If this is called during DLL loading, |
+// it has the effect of avoiding an initialization race on that pointer. |
+// TODO(siggi): fix GoogleUrl. |
+void InitGoogleUrl() { |
+ static const char kDummyUrl[] = "http://www.google.com"; |
+ |
+ url_util::IsStandard(kDummyUrl, |
+ url_parse::MakeRange(0, arraysize(kDummyUrl))); |
+} |
+ |
class ChromeTabModule : public CAtlDllModuleT<ChromeTabModule> { |
public: |
typedef CAtlDllModuleT<ChromeTabModule> ParentClass; |
- ChromeTabModule() : do_system_registration_(true) {} |
+ ChromeTabModule() : do_system_registration_(true), crash_reporting_(NULL) {} |
DECLARE_LIBID(LIBID_ChromeTabLib) |
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_CHROMETAB, |
@@ -189,8 +192,42 @@ class ChromeTabModule : public CAtlDllModuleT<ChromeTabModule> { |
return hr; |
} |
+ // The module is "locked" when an object takes a reference on it. The first |
+ // time it is locked, take a reference on crash reporting to bind its lifetime |
+ // to the module. |
+ virtual LONG Lock() throw() { |
+ LONG result = ParentClass::Lock(); |
+ if (result == 1) { |
+ DCHECK_EQ(crash_reporting_, |
+ static_cast<chrome_frame::ScopedCrashReporting*>(NULL)); |
+ crash_reporting_ = new chrome_frame::ScopedCrashReporting(); |
+ } |
+ return result; |
+ } |
+ |
+ // The module is "unlocked" when an object that had a reference on it is |
+ // destroyed. The last time it is unlocked, release the reference on crash |
+ // reporting. |
+ virtual LONG Unlock() throw() { |
+ LONG result = ParentClass::Unlock(); |
+ if (!result) { |
+ DCHECK_NE(crash_reporting_, |
+ static_cast<chrome_frame::ScopedCrashReporting*>(NULL)); |
+ delete crash_reporting_; |
+ crash_reporting_ = NULL; |
+ } |
+ return result; |
+ } |
+ |
// See comments in AddCommonRGSReplacements |
bool do_system_registration_; |
+ |
+ private: |
+ // A scoper created when the module is initially locked and destroyed when it |
+ // is finally unlocked. This is not a scoped_ptr since that could cause |
+ // reporting to shut down at exit, which would lead to problems with the |
+ // loader lock. |
+ chrome_frame::ScopedCrashReporting* crash_reporting_; |
}; |
ChromeTabModule _AtlModule; |
@@ -548,6 +585,11 @@ HRESULT SetOrDeleteMimeHandlerKey(bool set, HKEY root_key) { |
HRESULT_FROM_WIN32(result2); |
} |
+void OnPinModule() { |
+ // Pin crash reporting by leaking a reference. |
+ ignore_result(new chrome_frame::ScopedCrashReporting()); |
+} |
+ |
// Chrome Frame registration functions. |
//----------------------------------------------------------------------------- |
HRESULT RegisterSecuredMimeHandler(bool enable, bool is_system) { |
@@ -829,7 +871,6 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, |
g_exit_manager = new base::AtExitManager(); |
CommandLine::Init(0, NULL); |
- InitializeCrashReporting(); |
logging::InitLogging( |
NULL, |
logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, |
@@ -862,6 +903,10 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, |
// can only get called once. For Chrome Frame, that is here. |
g_field_trial_list = new base::FieldTrialList( |
new metrics::SHA1EntropyProvider(MetricsService::GetClientID())); |
+ |
+ // Set a callback so that crash reporting can be pinned when the module is |
+ // pinned. |
+ chrome_frame::SetPinModuleCallback(&OnPinModule); |
} else if (reason == DLL_PROCESS_DETACH) { |
delete g_field_trial_list; |
g_field_trial_list = NULL; |
@@ -874,8 +919,6 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, |
delete g_exit_manager; |
g_exit_manager = NULL; |
- |
- ShutdownCrashReporting(); |
} |
return _AtlModule.DllMain(reason, reserved); |
} |
@@ -887,6 +930,8 @@ STDAPI DllCanUnloadNow() { |
// Returns a class factory to create an object of the requested type |
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { |
+ chrome_frame::ScopedCrashReporting crash_reporting; |
+ |
// If we found another module present when we were loaded, then delegate to |
// that: |
if (g_dll_get_class_object_redir_ptr) { |
@@ -904,6 +949,7 @@ STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) { |
// DllRegisterServer - Adds entries to the system registry |
STDAPI DllRegisterServer() { |
+ chrome_frame::ScopedCrashReporting crash_reporting; |
uint16 flags = ACTIVEX | ACTIVEDOC | TYPELIB | GCF_PROTOCOL | |
BHO_CLSID | BHO_REGISTRATION; |
@@ -917,12 +963,14 @@ STDAPI DllRegisterServer() { |
// DllUnregisterServer - Removes entries from the system registry |
STDAPI DllUnregisterServer() { |
+ chrome_frame::ScopedCrashReporting crash_reporting; |
HRESULT hr = CustomRegistration(ALL, false, true); |
return hr; |
} |
// DllRegisterUserServer - Adds entries to the HKCU hive in the registry. |
STDAPI DllRegisterUserServer() { |
+ chrome_frame::ScopedCrashReporting crash_reporting; |
UINT flags = ACTIVEX | ACTIVEDOC | TYPELIB | GCF_PROTOCOL | |
BHO_CLSID | BHO_REGISTRATION; |
@@ -936,6 +984,7 @@ STDAPI DllRegisterUserServer() { |
// DllUnregisterUserServer - Removes entries from the HKCU hive in the registry. |
STDAPI DllUnregisterUserServer() { |
+ chrome_frame::ScopedCrashReporting crash_reporting; |
HRESULT hr = CustomRegistration(ALL, FALSE, false); |
return hr; |
} |