summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-19 21:02:58 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-19 21:02:58 +0000
commit79dc62e3412845f97c91db5792d0049783e4c7c3 (patch)
tree567c2b2cba1c881a7cbcf1eb0103c944ea409ff2
parentf5cdaff1456dfd7a5ad2240115285010a32f7fc1 (diff)
downloadchromium_src-79dc62e3412845f97c91db5792d0049783e4c7c3.zip
chromium_src-79dc62e3412845f97c91db5792d0049783e4c7c3.tar.gz
chromium_src-79dc62e3412845f97c91db5792d0049783e4c7c3.tar.bz2
Fix memory leaks when a renderer crashes and the user refreshes. Also fix memory leak every time a renderer process goes away.
Review URL: http://codereview.chromium.org/115492 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16415 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/child_process_security_policy.cc6
-rw-r--r--chrome/browser/child_process_security_policy.h4
-rw-r--r--chrome/browser/child_process_security_policy_unittest.cc45
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc3
-rw-r--r--chrome/browser/renderer_host/render_process_host.cc4
-rw-r--r--chrome/browser/renderer_host/web_cache_manager.cc3
6 files changed, 55 insertions, 10 deletions
diff --git a/chrome/browser/child_process_security_policy.cc b/chrome/browser/child_process_security_policy.cc
index f853c10..6a408bb1 100644
--- a/chrome/browser/child_process_security_policy.cc
+++ b/chrome/browser/child_process_security_policy.cc
@@ -118,10 +118,8 @@ void ChildProcessSecurityPolicy::Add(int renderer_id) {
void ChildProcessSecurityPolicy::Remove(int renderer_id) {
AutoLock lock(lock_);
- if (security_state_.count(renderer_id) != 1) {
- NOTREACHED() << "Remove renderers at most once.";
- return;
- }
+ if (!security_state_.count(renderer_id))
+ return; // May be called multiple times.
delete security_state_[renderer_id];
security_state_.erase(renderer_id);
diff --git a/chrome/browser/child_process_security_policy.h b/chrome/browser/child_process_security_policy.h
index 9b675cf..ae1eb41 100644
--- a/chrome/browser/child_process_security_policy.h
+++ b/chrome/browser/child_process_security_policy.h
@@ -13,6 +13,7 @@
#include "base/file_path.h"
#include "base/lock.h"
#include "base/singleton.h"
+#include "testing/gtest/include/gtest/gtest_prod.h"
class FilePath;
class GURL;
@@ -93,6 +94,9 @@ class ChildProcessSecurityPolicy {
bool HasDOMUIBindings(int renderer_id);
private:
+ friend class ChildProcessSecurityPolicyInProcessBrowserTest;
+ FRIEND_TEST(ChildProcessSecurityPolicyInProcessBrowserTest, NoLeak);
+
class SecurityState;
typedef std::set<std::string> SchemeSet;
diff --git a/chrome/browser/child_process_security_policy_unittest.cc b/chrome/browser/child_process_security_policy_unittest.cc
index 88f1e33..fed3a1f 100644
--- a/chrome/browser/child_process_security_policy_unittest.cc
+++ b/chrome/browser/child_process_security_policy_unittest.cc
@@ -6,8 +6,15 @@
#include "base/basictypes.h"
#include "base/file_path.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/child_process_security_policy.h"
+#include "chrome/browser/renderer_host/render_process_host.h"
+#include "chrome/common/chrome_paths.h"
#include "chrome/common/url_constants.h"
+#include "chrome/test/in_process_browser_test.h"
+#include "chrome/test/ui_test_utils.h"
+#include "net/base/net_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_job.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -266,3 +273,41 @@ TEST_F(ChildProcessSecurityPolicyTest, RemoveRace) {
EXPECT_FALSE(p->CanUploadFile(kRendererID, file));
EXPECT_FALSE(p->HasDOMUIBindings(kRendererID));
}
+
+class ChildProcessSecurityPolicyInProcessBrowserTest
+ : public InProcessBrowserTest {
+ public:
+ virtual void SetUp() {
+ EXPECT_EQ(
+ ChildProcessSecurityPolicy::GetInstance()->security_state_.size(), 0);
+ InProcessBrowserTest::SetUp();
+ }
+
+ virtual void TearDown() {
+ EXPECT_EQ(
+ ChildProcessSecurityPolicy::GetInstance()->security_state_.size(), 0);
+ InProcessBrowserTest::TearDown();
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(ChildProcessSecurityPolicyInProcessBrowserTest, NoLeak) {
+ FilePath path;
+ PathService::Get(chrome::DIR_TEST_DATA, &path);
+ path = path.Append(FilePath::FromWStringHack(L"google"));
+ path = path.Append(FilePath::FromWStringHack(L"google.html"));
+ GURL url = net::FilePathToFileURL(path);
+
+ ui_test_utils::NavigateToURL(browser(), url);
+ EXPECT_EQ(
+ ChildProcessSecurityPolicy::GetInstance()->security_state_.size(), 1);
+
+ TabContents* tab = browser()->GetTabContentsAt(0);
+ ASSERT_TRUE(tab != NULL);
+ base::KillProcess(
+ tab->process()->process().handle(), base::PROCESS_END_KILLED_BY_USER,
+ true);
+
+ tab->controller().Reload(true);
+ EXPECT_EQ(
+ ChildProcessSecurityPolicy::GetInstance()->security_state_.size(), 1);
+}
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index e1c9bd9..e8b608d 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -687,6 +687,9 @@ void BrowserRenderProcessHost::OnChannelError() {
if (child_exited)
process_.Close();
+ WebCacheManager::GetInstance()->Remove(pid());
+ ChildProcessSecurityPolicy::GetInstance()->Remove(pid());
+
channel_.reset();
// This process should detach all the listeners, causing the object to be
diff --git a/chrome/browser/renderer_host/render_process_host.cc b/chrome/browser/renderer_host/render_process_host.cc
index e70596743..349f8e2 100644
--- a/chrome/browser/renderer_host/render_process_host.cc
+++ b/chrome/browser/renderer_host/render_process_host.cc
@@ -90,10 +90,8 @@ void RenderProcessHost::Release(int listener_id) {
NotificationService::current()->Notify(
NotificationType::RENDERER_PROCESS_TERMINATED,
Source<RenderProcessHost>(this), NotificationService::NoDetails());
- if (pid_ >= 0) {
+ if (pid_ >= 0)
all_hosts.Remove(pid_);
- pid_ = -1;
- }
MessageLoop::current()->DeleteSoon(FROM_HERE, this);
}
}
diff --git a/chrome/browser/renderer_host/web_cache_manager.cc b/chrome/browser/renderer_host/web_cache_manager.cc
index 91b740e..4615e2b 100644
--- a/chrome/browser/renderer_host/web_cache_manager.cc
+++ b/chrome/browser/renderer_host/web_cache_manager.cc
@@ -85,9 +85,6 @@ void WebCacheManager::Add(int renderer_id) {
}
void WebCacheManager::Remove(int renderer_id) {
- DCHECK(active_renderers_.count(renderer_id) > 0 ||
- inactive_renderers_.count(renderer_id) > 0);
-
// Erase all knowledge of this renderer
active_renderers_.erase(renderer_id);
inactive_renderers_.erase(renderer_id);