diff --git a/mozilla/suite/common/pref/pref-debug.xul b/mozilla/suite/common/pref/pref-debug.xul
index 9d827a51c1f..ed1591ccd42 100644
--- a/mozilla/suite/common/pref/pref-debug.xul
+++ b/mozilla/suite/common/pref/pref-debug.xul
@@ -144,9 +144,13 @@
&debugDisableXULCache.label;
+
+
+ &debugEnableXPCOMRefcntLog.label;
+
-
+
diff --git a/mozilla/suite/debugQA/content/pref-debug.xul b/mozilla/suite/debugQA/content/pref-debug.xul
index 9d827a51c1f..ed1591ccd42 100644
--- a/mozilla/suite/debugQA/content/pref-debug.xul
+++ b/mozilla/suite/debugQA/content/pref-debug.xul
@@ -144,9 +144,13 @@
&debugDisableXULCache.label;
+
+
+ &debugEnableXPCOMRefcntLog.label;
+
-
+
diff --git a/mozilla/suite/debugQA/locales/en-US/pref-debug.dtd b/mozilla/suite/debugQA/locales/en-US/pref-debug.dtd
index 5b2000749cb..94f207e43b7 100644
--- a/mozilla/suite/debugQA/locales/en-US/pref-debug.dtd
+++ b/mozilla/suite/debugQA/locales/en-US/pref-debug.dtd
@@ -23,5 +23,6 @@
-
+
+
diff --git a/mozilla/suite/locales/en-US/chrome/common/pref/pref-debug.dtd b/mozilla/suite/locales/en-US/chrome/common/pref/pref-debug.dtd
index 5b2000749cb..94f207e43b7 100644
--- a/mozilla/suite/locales/en-US/chrome/common/pref/pref-debug.dtd
+++ b/mozilla/suite/locales/en-US/chrome/common/pref/pref-debug.dtd
@@ -23,5 +23,6 @@
-
+
+
diff --git a/mozilla/xpcom/base/nsTraceRefcnt.cpp b/mozilla/xpcom/base/nsTraceRefcnt.cpp
index d3e08afff0b..e1643bee6f3 100644
--- a/mozilla/xpcom/base/nsTraceRefcnt.cpp
+++ b/mozilla/xpcom/base/nsTraceRefcnt.cpp
@@ -54,6 +54,9 @@
#ifdef NS_BUILD_REFCNT_LOGGING
#include "plhash.h"
#include
+#include "nsIPref.h"
+#include "nsIServiceManager.h"
+
#if defined(NS_MT_SUPPORTED)
#include "prlock.h"
@@ -76,6 +79,9 @@ static PRInt32 gNextSerialNumber;
static PRBool gLogging;
static PRBool gLogToLeaky;
static PRBool gLogLeaksOnly;
+static PRBool gEnableViaPref;
+static PRBool gRefcountPrefEnabled = PR_FALSE;
+static const char* kRefcountPref = "nglayout.debug.enable_xpcom_refcnt_log";
static void (*leakyLogAddRef)(void* p, int oldrc, int newrc);
static void (*leakyLogRelease)(void* p, int oldrc, int newrc);
@@ -86,6 +92,8 @@ static FILE *gRefcntsLog = nsnull;
static FILE *gAllocLog = nsnull;
static FILE *gLeakyLog = nsnull;
+static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
+
#define XPCOM_REFCNT_TRACK_BLOAT 0x1
#define XPCOM_REFCNT_LOG_ALL 0x2
#define XPCOM_REFCNT_LOG_SOME 0x4
@@ -572,6 +580,8 @@ static void InitTraceLog(void)
PL_CompareValues,
PL_CompareValues,
NULL, NULL);
+
+
}
const char* objects = getenv("XPCOM_MEM_LOG_OBJECTS");
@@ -612,15 +622,27 @@ static void InitTraceLog(void)
}
}
+
if (gBloatLog || gRefcntsLog || gAllocLog || gLeakyLog) {
gLogging = PR_TRUE;
}
+ const char* s = getenv("XPCOM_REFCNT_LOG_ENABLE_VIA_PREF");
+ if (s && strchr(s, '1') >= 0) {
+ gEnableViaPref = PR_TRUE;
+ if (gLogging)
+ printf("### XPCOM_REFCNT_LOG_ENABLE_VIA_PREF defined: Logging will be enabled based on the pref selected in the Debug pane\n");
+ }
+ else
+ gEnableViaPref = PR_FALSE;
+
+
#if defined(NS_MT_SUPPORTED)
gTraceLock = PR_NewLock();
#endif /* NS_MT_SUPPORTED */
}
+
#endif
#if defined(_WIN32) && defined(_M_IX86) // WIN32 x86 stack walking code
@@ -659,11 +681,13 @@ static SYMGETMODULEBASEPROC _SymGetModuleBase;
typedef BOOL (__stdcall *SYMGETSYMFROMADDRPROC)(HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL);
static SYMGETSYMFROMADDRPROC _SymGetSymFromAddr;
+typedef DWORD ( __stdcall *SYMLOADMODULE)(HANDLE, HANDLE, PSTR, PSTR, DWORD, DWORD);
+static SYMLOADMODULE _SymLoadModule;
static PRBool
-EnsureSymInitialized()
+EnsureImageHlpInitialized()
{
- PRBool gInitialized = PR_FALSE;
+ static PRBool gInitialized = PR_FALSE;
if (! gInitialized) {
HMODULE module = ::LoadLibrary("IMAGEHLP.DLL");
@@ -687,12 +711,27 @@ EnsureSymInitialized()
_SymGetSymFromAddr = (SYMGETSYMFROMADDRPROC)GetProcAddress(module, "SymGetSymFromAddr");
if (!_SymGetSymFromAddr) return PR_FALSE;
- gInitialized = _SymInitialize(GetCurrentProcess(), 0, TRUE);
+ _SymLoadModule = (SYMLOADMODULE)GetProcAddress(module, "SymLoadModule");
+ if (!_SymLoadModule) return PR_FALSE;
+
+ gInitialized = PR_TRUE;
}
return gInitialized;
-}
+}
+static PRBool
+EnsureSymInitialized()
+{
+ static PRBool gInitialized = PR_FALSE;
+
+ if (! gInitialized) {
+ if (! EnsureImageHlpInitialized())
+ return PR_FALSE;
+ gInitialized = _SymInitialize(GetCurrentProcess(), 0, TRUE);
+ }
+ return gInitialized;
+}
/**
* Walk the stack, translating PC's found into strings and recording the
* chain in aBuffer. For this to work properly, the dll's must be rebased
@@ -710,7 +749,6 @@ nsTraceRefcnt::WalkTheStack(FILE* aStream)
{
HANDLE myProcess = ::GetCurrentProcess();
HANDLE myThread = ::GetCurrentThread();
-
BOOL ok;
ok = EnsureSymInitialized();
@@ -762,8 +800,8 @@ nsTraceRefcnt::WalkTheStack(FILE* aStream)
0,
NULL
);
- fprintf(stdout, "### ERROR: WalkStack: %s", lpMsgBuf);
- fflush(stdout);
+ fprintf(aStream, "### ERROR: WalkStack: %s", lpMsgBuf);
+ fflush(aStream);
LocalFree( lpMsgBuf );
}
if (!ok || frame.AddrPC.Offset == 0)
@@ -981,6 +1019,30 @@ nsTraceRefcnt::DemangleSymbol(const char * aSymbol,
//----------------------------------------------------------------------
+
+static int PR_CALLBACK
+refcountPrefChanged(const char * newpref, void * data) {
+ nsresult rv = NS_OK;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv);
+ if (NS_SUCCEEDED(rv) && prefs) {
+ rv = prefs->GetBoolPref(kRefcountPref, &gRefcountPrefEnabled);
+ }
+ return rv;
+}
+
+NS_COM void
+nsTraceRefcnt::SetPrefServiceAvailability(PRBool avail)
+{
+#ifdef NS_BUILD_REFCNT_LOGGING
+ nsresult rv = NS_OK;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv);
+ if (NS_SUCCEEDED(rv) && prefs) {
+ prefs->GetBoolPref(kRefcountPref, &gRefcountPrefEnabled);
+ prefs->RegisterCallback(kRefcountPref, refcountPrefChanged, NULL);
+ }
+#endif
+}
+
NS_COM void
nsTraceRefcnt::LoadLibrarySymbols(const char* aLibraryName,
void* aLibrayHandle)
@@ -994,9 +1056,8 @@ nsTraceRefcnt::LoadLibrarySymbols(const char* aLibraryName,
fprintf(stdout, "### Loading symbols for %s\n", aLibraryName);
fflush(stdout);
- HANDLE myProcess = ::GetCurrentProcess();
-
- BOOL ok = SymInitialize(myProcess, ".;..\\lib", FALSE);
+ HANDLE myProcess = ::GetCurrentProcess();
+ BOOL ok = EnsureSymInitialized();
if (ok) {
const char* baseName = aLibraryName;
// just get the base name of the library if a full path was given:
@@ -1007,7 +1068,7 @@ nsTraceRefcnt::LoadLibrarySymbols(const char* aLibraryName,
break;
}
}
- DWORD baseAddr = SymLoadModule(myProcess,
+ DWORD baseAddr = _SymLoadModule(myProcess,
NULL,
(char*)baseName,
(char*)baseName,
@@ -1089,11 +1150,14 @@ nsTraceRefcnt::LogAddRef(void* aPtr,
if (gLogToLeaky) {
(*leakyLogAddRef)(aPtr, aRefCnt - 1, aRefCnt);
}
- else {
- // Can't use PR_LOG(), b/c it truncates the line
- fprintf(gRefcntsLog,
- "\n<%s> 0x%08X %d AddRef %d\n", aClazz, PRInt32(aPtr), serialno, aRefCnt);
- WalkTheStack(gRefcntsLog);
+ else {
+ if (!gEnableViaPref || (gEnableViaPref && gRefcountPrefEnabled)) {
+ // Can't use PR_LOG(), b/c it truncates the line
+ fprintf(gRefcntsLog,
+ "\n<%s> 0x%08X %d AddRef %d\n", aClazz, PRInt32(aPtr), serialno, aRefCnt);
+ WalkTheStack(gRefcntsLog);
+ fflush(gRefcntsLog);
+ }
}
}
#endif
@@ -1137,10 +1201,13 @@ nsTraceRefcnt::LogRelease(void* aPtr,
(*leakyLogRelease)(aPtr, aRefCnt + 1, aRefCnt);
}
else {
- // Can't use PR_LOG(), b/c it truncates the line
- fprintf(gRefcntsLog,
- "\n<%s> 0x%08X %d Release %d\n", aClazz, PRInt32(aPtr), serialno, aRefCnt);
- WalkTheStack(gRefcntsLog);
+ if (!gEnableViaPref || (gEnableViaPref && gRefcountPrefEnabled)) {
+ // Can't use PR_LOG(), b/c it truncates the line
+ fprintf(gRefcntsLog,
+ "\n<%s> 0x%08X %d Release %d\n", aClazz, PRInt32(aPtr), serialno, aRefCnt);
+ WalkTheStack(gRefcntsLog);
+ fflush(gRefcntsLog);
+ }
}
}
diff --git a/mozilla/xpcom/base/nsTraceRefcnt.h b/mozilla/xpcom/base/nsTraceRefcnt.h
index 579ddf5cfe2..b1343fdb545 100644
--- a/mozilla/xpcom/base/nsTraceRefcnt.h
+++ b/mozilla/xpcom/base/nsTraceRefcnt.h
@@ -198,6 +198,8 @@ public:
int aBufLen);
static NS_COM void WalkTheStack(FILE* aStream);
+
+ static NS_COM void SetPrefServiceAvailability(PRBool avail);
};
#endif /* nsTraceRefcnt_h___ */
diff --git a/mozilla/xpcom/base/nsTraceRefcntImpl.cpp b/mozilla/xpcom/base/nsTraceRefcntImpl.cpp
index d3e08afff0b..e1643bee6f3 100644
--- a/mozilla/xpcom/base/nsTraceRefcntImpl.cpp
+++ b/mozilla/xpcom/base/nsTraceRefcntImpl.cpp
@@ -54,6 +54,9 @@
#ifdef NS_BUILD_REFCNT_LOGGING
#include "plhash.h"
#include
+#include "nsIPref.h"
+#include "nsIServiceManager.h"
+
#if defined(NS_MT_SUPPORTED)
#include "prlock.h"
@@ -76,6 +79,9 @@ static PRInt32 gNextSerialNumber;
static PRBool gLogging;
static PRBool gLogToLeaky;
static PRBool gLogLeaksOnly;
+static PRBool gEnableViaPref;
+static PRBool gRefcountPrefEnabled = PR_FALSE;
+static const char* kRefcountPref = "nglayout.debug.enable_xpcom_refcnt_log";
static void (*leakyLogAddRef)(void* p, int oldrc, int newrc);
static void (*leakyLogRelease)(void* p, int oldrc, int newrc);
@@ -86,6 +92,8 @@ static FILE *gRefcntsLog = nsnull;
static FILE *gAllocLog = nsnull;
static FILE *gLeakyLog = nsnull;
+static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
+
#define XPCOM_REFCNT_TRACK_BLOAT 0x1
#define XPCOM_REFCNT_LOG_ALL 0x2
#define XPCOM_REFCNT_LOG_SOME 0x4
@@ -572,6 +580,8 @@ static void InitTraceLog(void)
PL_CompareValues,
PL_CompareValues,
NULL, NULL);
+
+
}
const char* objects = getenv("XPCOM_MEM_LOG_OBJECTS");
@@ -612,15 +622,27 @@ static void InitTraceLog(void)
}
}
+
if (gBloatLog || gRefcntsLog || gAllocLog || gLeakyLog) {
gLogging = PR_TRUE;
}
+ const char* s = getenv("XPCOM_REFCNT_LOG_ENABLE_VIA_PREF");
+ if (s && strchr(s, '1') >= 0) {
+ gEnableViaPref = PR_TRUE;
+ if (gLogging)
+ printf("### XPCOM_REFCNT_LOG_ENABLE_VIA_PREF defined: Logging will be enabled based on the pref selected in the Debug pane\n");
+ }
+ else
+ gEnableViaPref = PR_FALSE;
+
+
#if defined(NS_MT_SUPPORTED)
gTraceLock = PR_NewLock();
#endif /* NS_MT_SUPPORTED */
}
+
#endif
#if defined(_WIN32) && defined(_M_IX86) // WIN32 x86 stack walking code
@@ -659,11 +681,13 @@ static SYMGETMODULEBASEPROC _SymGetModuleBase;
typedef BOOL (__stdcall *SYMGETSYMFROMADDRPROC)(HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL);
static SYMGETSYMFROMADDRPROC _SymGetSymFromAddr;
+typedef DWORD ( __stdcall *SYMLOADMODULE)(HANDLE, HANDLE, PSTR, PSTR, DWORD, DWORD);
+static SYMLOADMODULE _SymLoadModule;
static PRBool
-EnsureSymInitialized()
+EnsureImageHlpInitialized()
{
- PRBool gInitialized = PR_FALSE;
+ static PRBool gInitialized = PR_FALSE;
if (! gInitialized) {
HMODULE module = ::LoadLibrary("IMAGEHLP.DLL");
@@ -687,12 +711,27 @@ EnsureSymInitialized()
_SymGetSymFromAddr = (SYMGETSYMFROMADDRPROC)GetProcAddress(module, "SymGetSymFromAddr");
if (!_SymGetSymFromAddr) return PR_FALSE;
- gInitialized = _SymInitialize(GetCurrentProcess(), 0, TRUE);
+ _SymLoadModule = (SYMLOADMODULE)GetProcAddress(module, "SymLoadModule");
+ if (!_SymLoadModule) return PR_FALSE;
+
+ gInitialized = PR_TRUE;
}
return gInitialized;
-}
+}
+static PRBool
+EnsureSymInitialized()
+{
+ static PRBool gInitialized = PR_FALSE;
+
+ if (! gInitialized) {
+ if (! EnsureImageHlpInitialized())
+ return PR_FALSE;
+ gInitialized = _SymInitialize(GetCurrentProcess(), 0, TRUE);
+ }
+ return gInitialized;
+}
/**
* Walk the stack, translating PC's found into strings and recording the
* chain in aBuffer. For this to work properly, the dll's must be rebased
@@ -710,7 +749,6 @@ nsTraceRefcnt::WalkTheStack(FILE* aStream)
{
HANDLE myProcess = ::GetCurrentProcess();
HANDLE myThread = ::GetCurrentThread();
-
BOOL ok;
ok = EnsureSymInitialized();
@@ -762,8 +800,8 @@ nsTraceRefcnt::WalkTheStack(FILE* aStream)
0,
NULL
);
- fprintf(stdout, "### ERROR: WalkStack: %s", lpMsgBuf);
- fflush(stdout);
+ fprintf(aStream, "### ERROR: WalkStack: %s", lpMsgBuf);
+ fflush(aStream);
LocalFree( lpMsgBuf );
}
if (!ok || frame.AddrPC.Offset == 0)
@@ -981,6 +1019,30 @@ nsTraceRefcnt::DemangleSymbol(const char * aSymbol,
//----------------------------------------------------------------------
+
+static int PR_CALLBACK
+refcountPrefChanged(const char * newpref, void * data) {
+ nsresult rv = NS_OK;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv);
+ if (NS_SUCCEEDED(rv) && prefs) {
+ rv = prefs->GetBoolPref(kRefcountPref, &gRefcountPrefEnabled);
+ }
+ return rv;
+}
+
+NS_COM void
+nsTraceRefcnt::SetPrefServiceAvailability(PRBool avail)
+{
+#ifdef NS_BUILD_REFCNT_LOGGING
+ nsresult rv = NS_OK;
+ NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &rv);
+ if (NS_SUCCEEDED(rv) && prefs) {
+ prefs->GetBoolPref(kRefcountPref, &gRefcountPrefEnabled);
+ prefs->RegisterCallback(kRefcountPref, refcountPrefChanged, NULL);
+ }
+#endif
+}
+
NS_COM void
nsTraceRefcnt::LoadLibrarySymbols(const char* aLibraryName,
void* aLibrayHandle)
@@ -994,9 +1056,8 @@ nsTraceRefcnt::LoadLibrarySymbols(const char* aLibraryName,
fprintf(stdout, "### Loading symbols for %s\n", aLibraryName);
fflush(stdout);
- HANDLE myProcess = ::GetCurrentProcess();
-
- BOOL ok = SymInitialize(myProcess, ".;..\\lib", FALSE);
+ HANDLE myProcess = ::GetCurrentProcess();
+ BOOL ok = EnsureSymInitialized();
if (ok) {
const char* baseName = aLibraryName;
// just get the base name of the library if a full path was given:
@@ -1007,7 +1068,7 @@ nsTraceRefcnt::LoadLibrarySymbols(const char* aLibraryName,
break;
}
}
- DWORD baseAddr = SymLoadModule(myProcess,
+ DWORD baseAddr = _SymLoadModule(myProcess,
NULL,
(char*)baseName,
(char*)baseName,
@@ -1089,11 +1150,14 @@ nsTraceRefcnt::LogAddRef(void* aPtr,
if (gLogToLeaky) {
(*leakyLogAddRef)(aPtr, aRefCnt - 1, aRefCnt);
}
- else {
- // Can't use PR_LOG(), b/c it truncates the line
- fprintf(gRefcntsLog,
- "\n<%s> 0x%08X %d AddRef %d\n", aClazz, PRInt32(aPtr), serialno, aRefCnt);
- WalkTheStack(gRefcntsLog);
+ else {
+ if (!gEnableViaPref || (gEnableViaPref && gRefcountPrefEnabled)) {
+ // Can't use PR_LOG(), b/c it truncates the line
+ fprintf(gRefcntsLog,
+ "\n<%s> 0x%08X %d AddRef %d\n", aClazz, PRInt32(aPtr), serialno, aRefCnt);
+ WalkTheStack(gRefcntsLog);
+ fflush(gRefcntsLog);
+ }
}
}
#endif
@@ -1137,10 +1201,13 @@ nsTraceRefcnt::LogRelease(void* aPtr,
(*leakyLogRelease)(aPtr, aRefCnt + 1, aRefCnt);
}
else {
- // Can't use PR_LOG(), b/c it truncates the line
- fprintf(gRefcntsLog,
- "\n<%s> 0x%08X %d Release %d\n", aClazz, PRInt32(aPtr), serialno, aRefCnt);
- WalkTheStack(gRefcntsLog);
+ if (!gEnableViaPref || (gEnableViaPref && gRefcountPrefEnabled)) {
+ // Can't use PR_LOG(), b/c it truncates the line
+ fprintf(gRefcntsLog,
+ "\n<%s> 0x%08X %d Release %d\n", aClazz, PRInt32(aPtr), serialno, aRefCnt);
+ WalkTheStack(gRefcntsLog);
+ fflush(gRefcntsLog);
+ }
}
}
diff --git a/mozilla/xpcom/base/nsTraceRefcntImpl.h b/mozilla/xpcom/base/nsTraceRefcntImpl.h
index 579ddf5cfe2..b1343fdb545 100644
--- a/mozilla/xpcom/base/nsTraceRefcntImpl.h
+++ b/mozilla/xpcom/base/nsTraceRefcntImpl.h
@@ -198,6 +198,8 @@ public:
int aBufLen);
static NS_COM void WalkTheStack(FILE* aStream);
+
+ static NS_COM void SetPrefServiceAvailability(PRBool avail);
};
#endif /* nsTraceRefcnt_h___ */
diff --git a/mozilla/xpfe/components/prefwindow/resources/content/pref-debug.xul b/mozilla/xpfe/components/prefwindow/resources/content/pref-debug.xul
index 9d827a51c1f..ed1591ccd42 100644
--- a/mozilla/xpfe/components/prefwindow/resources/content/pref-debug.xul
+++ b/mozilla/xpfe/components/prefwindow/resources/content/pref-debug.xul
@@ -144,9 +144,13 @@
&debugDisableXULCache.label;
+
+
+ &debugEnableXPCOMRefcntLog.label;
+
-
+
diff --git a/mozilla/xpfe/components/prefwindow/resources/locale/en-US/pref-debug.dtd b/mozilla/xpfe/components/prefwindow/resources/locale/en-US/pref-debug.dtd
index 5b2000749cb..94f207e43b7 100644
--- a/mozilla/xpfe/components/prefwindow/resources/locale/en-US/pref-debug.dtd
+++ b/mozilla/xpfe/components/prefwindow/resources/locale/en-US/pref-debug.dtd
@@ -23,5 +23,6 @@
-
+
+