From ac01cd37708c561e3b5944c6ee5a53efa0c0cdc6 Mon Sep 17 00:00:00 2001 From: "dbaron%dbaron.org" Date: Fri, 6 Jan 2006 06:51:45 +0000 Subject: [PATCH] Add some PR_LOGging to help find leaks of large object graphs. b=320192 r=jst sr=darin git-svn-id: svn://10.0.0.236/trunk@187062 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/src/nsDocument.cpp | 44 ++++++++++++++++++++++ mozilla/docshell/base/nsDocShell.cpp | 49 +++++++++++++++++++++++-- mozilla/dom/src/base/nsGlobalWindow.cpp | 35 ++++++++++++++++++ 3 files changed, 124 insertions(+), 4 deletions(-) diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index 3d10933c526..8997df1a5f3 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -138,6 +138,16 @@ static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID); #include "nsDateTimeFormatCID.h" #include "nsIDateTimeFormat.h" +#ifdef MOZ_LOGGING +// so we can get logging even in release builds +#define FORCE_PR_LOG 1 +#endif +#include "prlog.h" + +#ifdef PR_LOGGING +static PRLogModuleInfo* gDocumentLeakPRLog; +#endif + static NS_DEFINE_CID(kCharsetAliasCID, NS_CHARSETALIAS_CID); static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID); @@ -677,10 +687,24 @@ nsDocument::nsDocument() : nsIDocument(), mVisible(PR_TRUE) { +#ifdef PR_LOGGING + if (!gDocumentLeakPRLog) + gDocumentLeakPRLog = PR_NewLogModule("DocumentLeak"); + + if (gDocumentLeakPRLog) + PR_LOG(gDocumentLeakPRLog, PR_LOG_DEBUG, + ("DOCUMENT %p created", this)); +#endif } nsDocument::~nsDocument() { +#ifdef PR_LOGGING + if (gDocumentLeakPRLog) + PR_LOG(gDocumentLeakPRLog, PR_LOG_DEBUG, + ("DOCUMENT %p destroyed", this)); +#endif + mInDestructor = PR_TRUE; CallUserDataHandler(nsIDOMUserDataHandler::NODE_DELETED, @@ -907,6 +931,15 @@ void nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup) { NS_PRECONDITION(aURI, "Null URI passed to ResetToURI"); + +#ifdef PR_LOGGING + if (gDocumentLeakPRLog && PR_LOG_TEST(gDocumentLeakPRLog, PR_LOG_DEBUG)) { + nsCAutoString spec; + aURI->GetSpec(spec); + PR_LogPrint("DOCUMENT %p ResetToURI %s", this, spec.get()); + } +#endif + mDocumentTitle.SetIsVoid(PR_TRUE); mPrincipal = nsnull; @@ -1110,6 +1143,17 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel, nsIStreamListener **aDocListener, PRBool aReset, nsIContentSink* aSink) { +#ifdef PR_LOGGING + if (gDocumentLeakPRLog && PR_LOG_TEST(gDocumentLeakPRLog, PR_LOG_DEBUG)) { + nsCOMPtr uri; + aChannel->GetURI(getter_AddRefs(uri)); + nsCAutoString spec; + if (uri) + uri->GetSpec(spec); + PR_LogPrint("DOCUMENT %p StartDocumentLoad %s", this, spec.get()); + } +#endif + if (aReset) { Reset(aChannel, aLoadGroup); } diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp index 5da2470ab14..b4539a3963c 100644 --- a/mozilla/docshell/base/nsDocShell.cpp +++ b/mozilla/docshell/base/nsDocShell.cpp @@ -40,6 +40,11 @@ * * ***** END LICENSE BLOCK ***** */ +#ifdef MOZ_LOGGING +// so we can get logging even in release builds (but only for some things) +#define FORCE_PR_LOG 1 +#endif + #include "nsIBrowserDOMWindow.h" #include "nsIComponentManager.h" #include "nsIContent.h" @@ -205,8 +210,11 @@ static PRBool gValidateOrigin = (PRBool)0xffffffff; #define NS_ERROR_DOCUMENT_IS_PRINTMODE NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GENERAL,2001) #ifdef PR_LOGGING +#ifdef DEBUG static PRLogModuleInfo* gDocShellLog; #endif +static PRLogModuleInfo* gDocShellLeakLog; +#endif //***************************************************************************** //*** nsDocShellFocusController @@ -278,8 +286,14 @@ nsDocShell::nsDocShell(): } #ifdef PR_LOGGING +#ifdef DEBUG if (! gDocShellLog) gDocShellLog = PR_NewLogModule("nsDocShell"); +#endif + if (nsnull == gDocShellLeakLog) + gDocShellLeakLog = PR_NewLogModule("nsDocShellLeak"); + if (gDocShellLeakLog) + PR_LOG(gDocShellLeakLog, PR_LOG_DEBUG, ("DOCSHELL %p created\n", this)); #endif } @@ -294,6 +308,11 @@ nsDocShell::~nsDocShell() if (--gDocShellCount == 0) { NS_IF_RELEASE(sURIFixup); } + +#ifdef PR_LOGGING + if (gDocShellLeakLog) + PR_LOG(gDocShellLeakLog, PR_LOG_DEBUG, ("DOCSHELL %p destroyed\n", this)); +#endif } nsresult @@ -633,7 +652,7 @@ nsDocShell::LoadURI(nsIURI * aURI, aLoadInfo->GetSendReferrer(&sendReferrer); } -#ifdef PR_LOGGING +#if defined(PR_LOGGING) && defined(DEBUG) if (PR_LOG_TEST(gDocShellLog, PR_LOG_DEBUG)) { nsCAutoString uristr; aURI->GetAsciiSpec(uristr); @@ -738,8 +757,10 @@ nsDocShell::LoadURI(nsIURI * aURI, } // !shEntry if (shEntry) { +#ifdef DEBUG PR_LOG(gDocShellLog, PR_LOG_DEBUG, ("nsDocShell[%p]: loading from session history", this)); +#endif rv = LoadHistoryEntry(shEntry, loadType); } @@ -1353,6 +1374,15 @@ PRBool nsDocShell::SetCurrentURI(nsIURI *aURI, nsIRequest *aRequest, PRBool aFireOnLocationChange) { +#ifdef PR_LOGGING + if (gDocShellLeakLog && PR_LOG_TEST(gDocShellLeakLog, PR_LOG_DEBUG)) { + nsCAutoString spec; + if (aURI) + aURI->GetSpec(spec); + PR_LogPrint("DOCSHELL %p SetCurrentURI %s\n", this, spec.get()); + } +#endif + // We don't want to send a location change when we're displaying an error // page, and we don't want to change our idea of "current URI" either if (mLoadType == LOAD_ERROR_PAGE) { @@ -3079,7 +3109,7 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL, const PRUnichar *aDescription, nsIChannel* aFailedChannel) { -#ifdef PR_LOGGING +#if defined(PR_LOGGING) && defined(DEBUG) if (PR_LOG_TEST(gDocShellLog, PR_LOG_DEBUG)) { nsCAutoString spec; aURI->GetSpec(spec); @@ -6199,6 +6229,15 @@ nsDocShell::InternalLoad(nsIURI * aURI, nsIRequest** aRequest) { nsresult rv = NS_OK; + +#ifdef PR_LOGGING + if (gDocShellLeakLog && PR_LOG_TEST(gDocShellLeakLog, PR_LOG_DEBUG)) { + nsCAutoString spec; + if (aURI) + aURI->GetSpec(spec); + PR_LogPrint("DOCSHELL %p InternalLoad %s\n", this, spec.get()); + } +#endif // Initialize aDocShell/aRequest if (aDocShell) { @@ -7235,7 +7274,7 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, PRBool aAddToGlobalHistory) { NS_ASSERTION(aURI, "uri is null"); -#ifdef PR_LOGGING +#if defined(PR_LOGGING) && defined(DEBUG) if (PR_LOG_TEST(gDocShellLog, PR_LOG_DEBUG)) { nsCAutoString spec; aURI->GetSpec(spec); @@ -7296,9 +7335,11 @@ nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, if (mCurrentURI) aURI->Equals(mCurrentURI, &equalUri); +#ifdef DEBUG PR_LOG(gDocShellLog, PR_LOG_DEBUG, (" shAvailable=%i updateHistory=%i equalURI=%i\n", shAvailable, updateHistory, equalUri)); +#endif /* If the url to be loaded is the same as the one already there, * and the original loadType is LOAD_NORMAL, LOAD_LINK, or @@ -7457,7 +7498,7 @@ nsresult nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel, nsISHEntry ** aNewEntry) { -#ifdef PR_LOGGING +#if defined(PR_LOGGING) && defined(DEBUG) if (PR_LOG_TEST(gDocShellLog, PR_LOG_DEBUG)) { nsCAutoString spec; aURI->GetSpec(spec); diff --git a/mozilla/dom/src/base/nsGlobalWindow.cpp b/mozilla/dom/src/base/nsGlobalWindow.cpp index d0e708eb3ca..75780064b1a 100644 --- a/mozilla/dom/src/base/nsGlobalWindow.cpp +++ b/mozilla/dom/src/base/nsGlobalWindow.cpp @@ -163,6 +163,16 @@ // belonging to the back-end like nsIContentPolicy #include "nsIPopupWindowManager.h" +#ifdef MOZ_LOGGING +// so we can get logging even in release builds +#define FORCE_PR_LOG 1 +#endif +#include "prlog.h" + +#ifdef PR_LOGGING +static PRLogModuleInfo* gDOMLeakPRLog; +#endif + nsIScriptSecurityManager *nsGlobalWindow::sSecMan = nsnull; nsIFactory *nsGlobalWindow::sComputedDOMStyleFactory = nsnull; @@ -323,6 +333,15 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) printf("++DOMWINDOW == %d\n", gRefCnt); #endif +#ifdef PR_LOGGING + if (!gDOMLeakPRLog) + gDOMLeakPRLog = PR_NewLogModule("DOMLeak"); + + if (gDOMLeakPRLog) + PR_LOG(gDOMLeakPRLog, PR_LOG_DEBUG, + ("DOMWINDOW %p created outer=%p", this, aOuterWindow)); +#endif + if (!sSecMan) { CallGetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &sSecMan); } @@ -337,6 +356,12 @@ nsGlobalWindow::~nsGlobalWindow() printf("--DOMWINDOW == %d\n", gRefCnt); #endif +#ifdef PR_LOGGING + if (gDOMLeakPRLog) + PR_LOG(gDOMLeakPRLog, PR_LOG_DEBUG, + ("DOMWINDOW %p destroyed", this)); +#endif + if (IsOuterWindow()) { // An outer window is destroyed with inner windows still possibly // alive, iterate through the inner windows and null out their @@ -818,6 +843,16 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument, { NS_WARN_IF_FALSE(mDocumentPrincipal == nsnull, "mDocumentPrincipal prematurely set!"); +#ifdef PR_LOGGING + if (IsInnerWindow() && aDocument && gDOMLeakPRLog && + PR_LOG_TEST(gDOMLeakPRLog, PR_LOG_DEBUG)) { + nsIURI *uri = aDocument->GetDocumentURI(); + nsCAutoString spec; + if (uri) + uri->GetSpec(spec); + PR_LogPrint("DOMWINDOW %p SetNewDocument %s", this, spec.get()); + } +#endif if (!aIsInternalCall && IsInnerWindow()) { if (!mOuterWindow) {