summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-11 20:35:09 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-11 20:35:09 +0000
commit27e469a6fb9942076a2cf27d36f071c31c63dd94 (patch)
tree93402e192bb2bc1868d7f79d6e8b41216fc04724
parent04a6bd3b96fa24767d02235d9df4c2211c4f5b90 (diff)
downloadchromium_src-27e469a6fb9942076a2cf27d36f071c31c63dd94.zip
chromium_src-27e469a6fb9942076a2cf27d36f071c31c63dd94.tar.gz
chromium_src-27e469a6fb9942076a2cf27d36f071c31c63dd94.tar.bz2
Prevent a crash and add debugging code for cases where things go wrong
when trying to unload a half-crashed extension. TEST=none BUG=30405 Review URL: http://codereview.chromium.org/523163 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35935 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/extension_process_manager.cc4
-rw-r--r--chrome/browser/extensions/extension_process_manager.h3
-rw-r--r--chrome/browser/extensions/extensions_service.cc17
3 files changed, 23 insertions, 1 deletions
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc
index 76e2a6e..3121d3c 100644
--- a/chrome/browser/extensions/extension_process_manager.cc
+++ b/chrome/browser/extensions/extension_process_manager.cc
@@ -194,6 +194,10 @@ SiteInstance* ExtensionProcessManager::GetSiteInstanceForURL(const GURL& url) {
return browsing_instance_->GetSiteInstanceForURL(url);
}
+bool ExtensionProcessManager::HasExtensionHost(ExtensionHost* host) const {
+ return all_hosts_.find(host) != all_hosts_.end();
+}
+
void ExtensionProcessManager::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
diff --git a/chrome/browser/extensions/extension_process_manager.h b/chrome/browser/extensions/extension_process_manager.h
index f399a0b..1cfec71 100644
--- a/chrome/browser/extensions/extension_process_manager.h
+++ b/chrome/browser/extensions/extension_process_manager.h
@@ -73,6 +73,9 @@ class ExtensionProcessManager : public NotificationObserver {
// Returns the process that the extension with the given ID is running in.
RenderProcessHost* GetExtensionProcess(const std::string& extension_id);
+ // Returns true if |host| is managed by this process manager.
+ bool HasExtensionHost(ExtensionHost* host) const;
+
// NotificationObserver:
virtual void Observe(NotificationType type,
const NotificationSource& source,
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index e64956a..dc0c0ae 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -529,6 +529,7 @@ void ExtensionsService::CheckForExternalUpdates() {
}
void ExtensionsService::UnloadExtension(const std::string& extension_id) {
+ // Make sure the extension gets deleted after we return from this function.
scoped_ptr<Extension> extension(
GetExtensionByIdInternal(extension_id, true, true));
@@ -879,10 +880,24 @@ void ExtensionsService::Observe(NotificationType type,
DCHECK_EQ(profile_, Source<Profile>(source).ptr());
ExtensionHost* host = Details<ExtensionHost>(details).ptr();
+ // TODO(phajdan.jr): Change to DCHECK after fixing http://crbug.com/30405.
+ CHECK(profile_->GetExtensionProcessManager()->HasExtensionHost(host));
+
+ // If we hit one of these assertions it means that the host's
+ // Extension pointer became invalid (http://crbug.com/30405).
+ // TODO(phajdan.jr): Remove excessive debugging after fixing bug 30405.
+ std::string extension_id(host->extension()->id());
+ CHECK(extension_id.length() == 32U);
+ Extension* extension = GetExtensionById(extension_id, true);
+ CHECK(extension == host->extension());
+ if (!extension) {
+ NOTREACHED();
+ return;
+ }
// Unload the entire extension. We want it to be in a consistent state:
// either fully working or not loaded at all, but never half-crashed.
- UnloadExtension(host->extension()->id());
+ UnloadExtension(extension_id);
break;
}