mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
r=harishd.
- The stack walking code now works on windows. We were initializing the symbol handler on each DLL load which was resetting its symbol tables. Now, we don't re-init the symbol handler repeatedly. - Added support for an environment variable, XPCOM_REFCNT_LOG_ENABLE_VIA_PREF. When this is set to 1, refcount logging is done based on whether the "Enable XPCOM refcount log" pref in the Debug pane is set. If this is not set, refcount logging is not affected by the pref.
This commit is contained in:
parent
27260bfcaa
commit
a03bdd0283
@ -144,9 +144,13 @@
|
||||
<html:label for="pref:0:bool:nglayout.debug.disable_xul_cache" accesskey="n" tabindex="0">
|
||||
&debugDisableXULCache.label;
|
||||
</html:label>
|
||||
<html:input type="checkbox" id="pref:0:bool:nglayout.debug.enable_xpcom_refcnt_log" />
|
||||
<html:label for="pref:0:bool:nglayout.debug.enable_xpcom_refcnt_log" accesskey="n" tabindex="0">
|
||||
<html:a href="http://www.mozilla.org/performance/refcnt-balancer.html">&debugEnableXPCOMRefcntLog.label;</html:a>
|
||||
</html:label>
|
||||
</html:div>
|
||||
</html:fieldset>
|
||||
</box>
|
||||
</box>
|
||||
</html:form>
|
||||
|
||||
</html:div>
|
||||
|
@ -144,9 +144,13 @@
|
||||
<html:label for="pref:0:bool:nglayout.debug.disable_xul_cache" accesskey="n" tabindex="0">
|
||||
&debugDisableXULCache.label;
|
||||
</html:label>
|
||||
<html:input type="checkbox" id="pref:0:bool:nglayout.debug.enable_xpcom_refcnt_log" />
|
||||
<html:label for="pref:0:bool:nglayout.debug.enable_xpcom_refcnt_log" accesskey="n" tabindex="0">
|
||||
<html:a href="http://www.mozilla.org/performance/refcnt-balancer.html">&debugEnableXPCOMRefcntLog.label;</html:a>
|
||||
</html:label>
|
||||
</html:div>
|
||||
</html:fieldset>
|
||||
</box>
|
||||
</box>
|
||||
</html:form>
|
||||
|
||||
</html:div>
|
||||
|
@ -23,5 +23,6 @@
|
||||
<!ENTITY debugCrossingEventDumping.label "Crossing Event Dumping">
|
||||
|
||||
<!-- Miscelleneous -->
|
||||
<!ENTITY debugMiscellaneous.label "Miscelleneous">
|
||||
<!ENTITY debugMiscellaneous.label "Miscellaneous">
|
||||
<!ENTITY debugDisableXULCache.label "Disable XUL Cache">
|
||||
<!ENTITY debugEnableXPCOMRefcntLog.label "Enable XPCOM Refcount Log">
|
||||
|
@ -23,5 +23,6 @@
|
||||
<!ENTITY debugCrossingEventDumping.label "Crossing Event Dumping">
|
||||
|
||||
<!-- Miscelleneous -->
|
||||
<!ENTITY debugMiscellaneous.label "Miscelleneous">
|
||||
<!ENTITY debugMiscellaneous.label "Miscellaneous">
|
||||
<!ENTITY debugDisableXULCache.label "Disable XUL Cache">
|
||||
<!ENTITY debugEnableXPCOMRefcntLog.label "Enable XPCOM Refcount Log">
|
||||
|
@ -54,6 +54,9 @@
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
#include "plhash.h"
|
||||
#include <math.h>
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,6 +198,8 @@ public:
|
||||
int aBufLen);
|
||||
|
||||
static NS_COM void WalkTheStack(FILE* aStream);
|
||||
|
||||
static NS_COM void SetPrefServiceAvailability(PRBool avail);
|
||||
};
|
||||
|
||||
#endif /* nsTraceRefcnt_h___ */
|
||||
|
@ -54,6 +54,9 @@
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
#include "plhash.h"
|
||||
#include <math.h>
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,6 +198,8 @@ public:
|
||||
int aBufLen);
|
||||
|
||||
static NS_COM void WalkTheStack(FILE* aStream);
|
||||
|
||||
static NS_COM void SetPrefServiceAvailability(PRBool avail);
|
||||
};
|
||||
|
||||
#endif /* nsTraceRefcnt_h___ */
|
||||
|
@ -144,9 +144,13 @@
|
||||
<html:label for="pref:0:bool:nglayout.debug.disable_xul_cache" accesskey="n" tabindex="0">
|
||||
&debugDisableXULCache.label;
|
||||
</html:label>
|
||||
<html:input type="checkbox" id="pref:0:bool:nglayout.debug.enable_xpcom_refcnt_log" />
|
||||
<html:label for="pref:0:bool:nglayout.debug.enable_xpcom_refcnt_log" accesskey="n" tabindex="0">
|
||||
<html:a href="http://www.mozilla.org/performance/refcnt-balancer.html">&debugEnableXPCOMRefcntLog.label;</html:a>
|
||||
</html:label>
|
||||
</html:div>
|
||||
</html:fieldset>
|
||||
</box>
|
||||
</box>
|
||||
</html:form>
|
||||
|
||||
</html:div>
|
||||
|
@ -23,5 +23,6 @@
|
||||
<!ENTITY debugCrossingEventDumping.label "Crossing Event Dumping">
|
||||
|
||||
<!-- Miscelleneous -->
|
||||
<!ENTITY debugMiscellaneous.label "Miscelleneous">
|
||||
<!ENTITY debugMiscellaneous.label "Miscellaneous">
|
||||
<!ENTITY debugDisableXULCache.label "Disable XUL Cache">
|
||||
<!ENTITY debugEnableXPCOMRefcntLog.label "Enable XPCOM Refcount Log">
|
||||
|
Loading…
Reference in New Issue
Block a user