Commit f0d440cf authored by Scott Violet's avatar Scott Violet Committed by Commit Bot

speculative fix for crash in PrerenderManager::GetPrerenderContents()

The stack indicates PrerenderManager::PeriodicCleanup() is being
called. PeriodicCleanup() is deleting a PrerenderContents. Deleting the
PrerenderContents is triggering a call PrerenderManager::GetPrerenderContents().

My suspicion is PeriodicCleanup() is calling clear() on a vector. The vector
contains std::unique_ptr<PrerenderContents>. It would appear the implementation
of vector::clear() destroys the entries, and *then* resets the size.
This means during destruction PrerenderManager::GetPrerenderContents() is
iterating over the vector that now contains deleted objects and we get a crash.

BUG=850489
TEST=none

Change-Id: I8472c577bfd583105abaebe32cec2d39b6fbcca1
Reviewed-on: https://chromium-review.googlesource.com/1091189Reviewed-by: default avatarDavid Roger <droger@chromium.org>
Reviewed-by: default avatarMatthew Cary <mattcary@chromium.org>
Commit-Queue: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565632}
parent 02a03062
...@@ -318,7 +318,7 @@ bool PrerenderManager::MaybeUsePrerenderedPage(const GURL& url, ...@@ -318,7 +318,7 @@ bool PrerenderManager::MaybeUsePrerenderedPage(const GURL& url,
} }
DeleteOldEntries(); DeleteOldEntries();
to_delete_prerenders_.clear(); DeleteToDeletePrerenders();
// First, try to find prerender data with the correct session storage // First, try to find prerender data with the correct session storage
// namespace. // namespace.
...@@ -946,7 +946,7 @@ void PrerenderManager::PeriodicCleanup() { ...@@ -946,7 +946,7 @@ void PrerenderManager::PeriodicCleanup() {
if (active_prerenders_.empty()) if (active_prerenders_.empty())
StopSchedulingPeriodicCleanups(); StopSchedulingPeriodicCleanups();
to_delete_prerenders_.clear(); DeleteToDeletePrerenders();
CleanUpOldNavigations(&prefetches_, base::TimeDelta::FromMinutes(30)); CleanUpOldNavigations(&prefetches_, base::TimeDelta::FromMinutes(30));
...@@ -985,6 +985,18 @@ void PrerenderManager::DeleteOldEntries() { ...@@ -985,6 +985,18 @@ void PrerenderManager::DeleteOldEntries() {
} }
} }
void PrerenderManager::DeleteToDeletePrerenders() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Delete the items one by one (after removing from the vector) as deleting
// the WebContents may trigger a call to GetPrerenderContents(), which
// iterates over |to_delete_prerenders_|.
while (!to_delete_prerenders_.empty()) {
std::unique_ptr<PrerenderData> prerender_data =
std::move(to_delete_prerenders_.back());
to_delete_prerenders_.pop_back();
}
}
base::Time PrerenderManager::GetCurrentTime() const { base::Time PrerenderManager::GetCurrentTime() const {
return base::Time::Now(); return base::Time::Now();
} }
...@@ -1159,7 +1171,7 @@ void PrerenderManager::DestroyAllContents(FinalStatus final_status) { ...@@ -1159,7 +1171,7 @@ void PrerenderManager::DestroyAllContents(FinalStatus final_status) {
PrerenderContents* contents = active_prerenders_.front()->contents(); PrerenderContents* contents = active_prerenders_.front()->contents();
contents->Destroy(final_status); contents->Destroy(final_status);
} }
to_delete_prerenders_.clear(); DeleteToDeletePrerenders();
} }
void PrerenderManager::RecordFinalStatusWithoutCreatingPrerenderContents( void PrerenderManager::RecordFinalStatusWithoutCreatingPrerenderContents(
......
...@@ -469,6 +469,8 @@ class PrerenderManager : public content::NotificationObserver, ...@@ -469,6 +469,8 @@ class PrerenderManager : public content::NotificationObserver,
void DeleteOldEntries(); void DeleteOldEntries();
void DeleteToDeletePrerenders();
// Virtual so unit tests can override this. // Virtual so unit tests can override this.
virtual std::unique_ptr<PrerenderContents> CreatePrerenderContents( virtual std::unique_ptr<PrerenderContents> CreatePrerenderContents(
const GURL& url, const GURL& url,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment