diff options
author | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-26 23:38:18 +0000 |
---|---|---|
committer | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-26 23:38:18 +0000 |
commit | 0e3a385d57bb5f0080e930b37fb8c6f14408cafb (patch) | |
tree | b50d9d3a38564f250866157e5157268defb7b786 /chrome | |
parent | f90a0fb4d44ae9d3fca4adf05b76f187c09840f6 (diff) | |
download | chromium_src-0e3a385d57bb5f0080e930b37fb8c6f14408cafb.zip chromium_src-0e3a385d57bb5f0080e930b37fb8c6f14408cafb.tar.gz chromium_src-0e3a385d57bb5f0080e930b37fb8c6f14408cafb.tar.bz2 |
Profiles: When built in debug mode, NOTREACHED() after a Profile is shutdown if it is accessed.
BUG=77155
TEST=These extra NOTREACHED() don't trigger.
Review URL: http://codereview.chromium.org/7074019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@86929 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/profiles/profile.cc | 4 | ||||
-rw-r--r-- | chrome/browser/profiles/profile_dependency_manager.cc | 20 | ||||
-rw-r--r-- | chrome/browser/profiles/profile_dependency_manager.h | 24 | ||||
-rw-r--r-- | chrome/browser/profiles/profile_impl.cc | 5 | ||||
-rw-r--r-- | chrome/browser/profiles/profile_keyed_service_factory.cc | 8 | ||||
-rw-r--r-- | chrome/test/testing_profile.cc | 4 |
6 files changed, 65 insertions, 0 deletions
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index 85bbef2..4f882cb 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc @@ -200,6 +200,10 @@ class OffTheRecordProfileImpl : public Profile, prefs_(real_profile->GetOffTheRecordPrefs()), ALLOW_THIS_IN_INITIALIZER_LIST(io_data_(this)), start_time_(Time::Now()) { +#ifndef NDEBUG + ProfileDependencyManager::GetInstance()->ProfileNowExists(this); +#endif + extension_process_manager_.reset(ExtensionProcessManager::Create(this)); BrowserList::AddObserver(this); diff --git a/chrome/browser/profiles/profile_dependency_manager.cc b/chrome/browser/profiles/profile_dependency_manager.cc index 590a5b3..e6479ad 100644 --- a/chrome/browser/profiles/profile_dependency_manager.cc +++ b/chrome/browser/profiles/profile_dependency_manager.cc @@ -55,12 +55,32 @@ void ProfileDependencyManager::DestroyProfileServices(Profile* profile) { (*it)->ProfileShutdown(profile); } +#ifndef NDEBUG + // The profile is now dead to the rest of the program. + dead_profile_pointers_.insert(profile); +#endif + for (std::vector<ProfileKeyedServiceFactory*>::const_iterator it = destruction_order_.begin(); it != destruction_order_.end(); ++it) { (*it)->ProfileDestroyed(profile); } } +#ifndef NDEBUG +void ProfileDependencyManager::ProfileNowExists(Profile* profile) { + dead_profile_pointers_.erase(profile); +} + +void ProfileDependencyManager::AssertProfileWasntDestroyed(Profile* profile) { + if (dead_profile_pointers_.find(profile) != dead_profile_pointers_.end()) { + NOTREACHED() << "Attempted to access a Profile that was ShutDown(). This " + << "is most likely a heap smasher in progress. After " + << "ProfileKeyedService::Shutdown() completes, your service " + << "MUST NOT refer to depended Profile services again."; + } +} +#endif + // static ProfileDependencyManager* ProfileDependencyManager::GetInstance() { return Singleton<ProfileDependencyManager>::get(); diff --git a/chrome/browser/profiles/profile_dependency_manager.h b/chrome/browser/profiles/profile_dependency_manager.h index 09fd381..b477bb7 100644 --- a/chrome/browser/profiles/profile_dependency_manager.h +++ b/chrome/browser/profiles/profile_dependency_manager.h @@ -10,6 +10,10 @@ #include "base/memory/singleton.h" +#ifndef NDEBUG +#include <set> +#endif + class Profile; class ProfileKeyedServiceFactory; @@ -39,6 +43,18 @@ class ProfileDependencyManager { // replaced in many tests. void DestroyProfileServices(Profile* profile); +#ifndef NDEBUG + // Unmark |profile| as dead. This exists because of unit tests, which will + // often have similar stack structures. 0xWhatever might be created, go out + // of scope, and then a new Profile object might be created at 0xWhatever. + void ProfileNowExists(Profile* profile); + + // Debugging assertion called as part of GetServiceForProfile in debug + // mode. This will NOTREACHED() whenever the user is trying to access a stale + // Profile*. + void AssertProfileWasntDestroyed(Profile* profile); +#endif + static ProfileDependencyManager* GetInstance(); private: @@ -60,6 +76,14 @@ class ProfileDependencyManager { EdgeMap edges_; std::vector<ProfileKeyedServiceFactory*> destruction_order_; + +#ifndef NDEBUG + // A list of profile objects that have gone through the Shutdown() + // phase. These pointers are most likely invalid, but we keep track of their + // locations in memory so we can nicely assert if we're asked to do anything + // with them. + std::set<Profile*> dead_profile_pointers_; +#endif }; #endif // CHROME_BROWSER_PROFILES_PROFILE_DEPENDENCY_MANAGER_H_ diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 5d8b6ad..c36d91d 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -294,6 +294,11 @@ ProfileImpl::ProfileImpl(const FilePath& path, delegate_(delegate) { DCHECK(!path.empty()) << "Using an empty path will attempt to write " << "profile files to the root directory!"; + +#ifndef NDEBUG + ProfileDependencyManager::GetInstance()->ProfileNowExists(this); +#endif + create_session_service_timer_.Start( TimeDelta::FromMilliseconds(kCreateSessionServiceDelayMS), this, &ProfileImpl::EnsureSessionServiceCreated); diff --git a/chrome/browser/profiles/profile_keyed_service_factory.cc b/chrome/browser/profiles/profile_keyed_service_factory.cc index 8515714..2a1af3d 100644 --- a/chrome/browser/profiles/profile_keyed_service_factory.cc +++ b/chrome/browser/profiles/profile_keyed_service_factory.cc @@ -25,10 +25,18 @@ ProfileKeyedServiceFactory::~ProfileKeyedServiceFactory() { ProfileKeyedService* ProfileKeyedServiceFactory::GetServiceForProfile( Profile* profile, bool create) { +#ifndef NDEBUG + dependency_manager_->AssertProfileWasntDestroyed(profile); +#endif + // Possibly handle Incognito mode. if (profile->IsOffTheRecord()) { if (ServiceRedirectedInIncognito()) { profile = profile->GetOriginalProfile(); + +#ifndef NDEBUG + dependency_manager_->AssertProfileWasntDestroyed(profile); +#endif } else if (ServiceHasOwnInstanceInIncognito()) { // No-op; the pointers are already set correctly. } else { diff --git a/chrome/test/testing_profile.cc b/chrome/test/testing_profile.cc index 0ae4404..3604f9d 100644 --- a/chrome/test/testing_profile.cc +++ b/chrome/test/testing_profile.cc @@ -128,6 +128,10 @@ TestingProfile::TestingProfile() incognito_(false), last_session_exited_cleanly_(true), profile_dependency_manager_(ProfileDependencyManager::GetInstance()) { +#ifndef NDEBUG + profile_dependency_manager_->ProfileNowExists(this); +#endif + if (!temp_dir_.CreateUniqueTempDir()) { LOG(ERROR) << "Failed to create unique temporary directory."; |