Fix the use of dynamic_cast for nsCOMPtr logging so it doesn't appear in a macro. b=61243

Implement (without enabling, yet) assertions to warn about static constructors.  b=62006
Partly fix warnings about MOZ_DECL_CTOR_COUNTER on Mac builds by removing extra semicolon.  b=60145
Start to fix the longstanding leaks of nsTraceRefcnt's own hashtables.
r=waterson@netscape.com  sr=brendan@mozilla.org
This commit is contained in:
dbaron%fas.harvard.edu 2000-12-23 16:43:32 +00:00
Родитель 2ff6dea99f
Коммит c9b346ca28
6 изменённых файлов: 221 добавлений и 37 удалений

Просмотреть файл

@ -18,7 +18,7 @@
* Rights Reserved.
*
* Contributor(s):
* L. David Baron (dbaron@fas.harvard.edu)
* L. David Baron <dbaron@fas.harvard.edu>
*/
#include "nsISupports.h"
@ -114,6 +114,7 @@ static FILE *gRefcntsLog = nsnull;
static FILE *gAllocLog = nsnull;
static FILE *gLeakyLog = nsnull;
static FILE *gCOMPtrLog = nsnull;
static PRBool gActivityIsLegal = PR_FALSE;
#define XPCOM_REFCNT_TRACK_BLOAT 0x1
#define XPCOM_REFCNT_LOG_ALL 0x2
@ -1520,6 +1521,58 @@ nsTraceRefcnt::LoadLibrarySymbols(const char* aLibraryName,
//----------------------------------------------------------------------
NS_COM void
nsTraceRefcnt::Startup()
{
#ifdef NS_BUILD_REFCNT_LOGGING
SetActivityIsLegal(PR_TRUE);
#endif
}
NS_COM void
nsTraceRefcnt::Shutdown()
{
#ifdef NS_BUILD_REFCNT_LOGGING
if (gBloatView) {
PL_HashTableDestroy(gBloatView);
gBloatView = nsnull;
}
if (gTypesToLog) {
PL_HashTableDestroy(gTypesToLog);
gTypesToLog = nsnull;
}
if (gObjectsToLog) {
PL_HashTableDestroy(gObjectsToLog);
gObjectsToLog = nsnull;
}
if (gSerialNumbers) {
PL_HashTableDestroy(gSerialNumbers);
gSerialNumbers = nsnull;
}
SetActivityIsLegal(PR_FALSE);
#endif
}
NS_COM void
nsTraceRefcnt::SetActivityIsLegal(PRBool aLegal)
{
#ifdef NS_BUILD_REFCNT_LOGGING
gActivityIsLegal = aLegal;
#endif
}
#ifdef DEBUG_dbaron
// I hope to turn this on for everybody once we hit it a little less.
#define ASSERT_ACTIVITY_IS_LEGAL \
NS_WARN_IF_FALSE(gActivityIsLegal, \
"XPCOM objects created/destroyed from static ctor/dtor")
#else
#define ASSERT_ACTIVITY_IS_LEGAL
#endif
/*
For consistency, and ease of munging the output, the following record format will be used:
@ -1533,6 +1586,7 @@ nsTraceRefcnt::LogAddRef(void* aPtr,
PRUint32 classSize)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
if (!gInitialized)
InitTraceLog();
if (gLogging) {
@ -1595,6 +1649,7 @@ nsTraceRefcnt::LogRelease(void* aPtr,
const char* aClazz)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
if (!gInitialized)
InitTraceLog();
if (gLogging) {
@ -1663,6 +1718,7 @@ nsTraceRefcnt::LogAddRefCall(void* aPtr,
int aLine)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
#ifdef NS_LOSING_ARCHITECTURE
if (!gInitialized)
InitTraceLog();
@ -1687,6 +1743,7 @@ nsTraceRefcnt::LogReleaseCall(void* aPtr,
int aLine)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
#ifdef NS_LOSING_ARCHITECTURE
if (!gInitialized)
InitTraceLog();
@ -1713,6 +1770,7 @@ nsTraceRefcnt::LogNewXPCOM(void* aPtr,
int aLine)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
#ifdef NS_LOSING_ARCHITECTURE
if (!gInitialized)
InitTraceLog();
@ -1736,6 +1794,7 @@ nsTraceRefcnt::LogDeleteXPCOM(void* aPtr,
int aLine)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
#ifdef NS_LOSING_ARCHITECTURE
if (!gInitialized)
InitTraceLog();
@ -1759,6 +1818,7 @@ nsTraceRefcnt::LogCtor(void* aPtr,
PRUint32 aInstanceSize)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
if (!gInitialized)
InitTraceLog();
@ -1799,6 +1859,7 @@ nsTraceRefcnt::LogDtor(void* aPtr, const char* aType,
PRUint32 aInstanceSize)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
if (!gInitialized)
InitTraceLog();
@ -1838,16 +1899,19 @@ nsTraceRefcnt::LogDtor(void* aPtr, const char* aType,
NS_COM void
nsTraceRefcnt::LogAddCOMPtr(void* aCOMPtr,
void* aObject)
nsISupports* aObject)
{
#ifdef NS_BUILD_REFCNT_LOGGING
#if defined(NS_BUILD_REFCNT_LOGGING) && defined(HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR)
// Get the most-derived object.
void *object = dynamic_cast<void *>(aObject);
// This is a very indirect way of finding out what the class is
// of the object being logged. If we're logging a specific type,
// then
if (!gTypesToLog || !gSerialNumbers) {
return;
}
PRInt32 serialno = GetSerialNumber(aObject, PR_FALSE);
PRInt32 serialno = GetSerialNumber(object, PR_FALSE);
if (serialno == 0) {
return;
}
@ -1857,7 +1921,7 @@ nsTraceRefcnt::LogAddCOMPtr(void* aCOMPtr,
if (gLogging) {
LOCK_TRACELOG();
PRInt32* count = GetCOMPtrCount(aObject);
PRInt32* count = GetCOMPtrCount(object);
if(count)
(*count)++;
@ -1866,7 +1930,7 @@ nsTraceRefcnt::LogAddCOMPtr(void* aCOMPtr,
if (gCOMPtrLog && loggingThisObject) {
fprintf(gCOMPtrLog, "\n<?> 0x%08X %d nsCOMPtrAddRef %d 0x%08X\n",
PRInt32(aObject), serialno, count?(*count):-1, PRInt32(aCOMPtr));
PRInt32(object), serialno, count?(*count):-1, PRInt32(aCOMPtr));
WalkTheStack(gCOMPtrLog);
}
#endif
@ -1878,16 +1942,19 @@ nsTraceRefcnt::LogAddCOMPtr(void* aCOMPtr,
NS_COM void
nsTraceRefcnt::LogReleaseCOMPtr(void* aCOMPtr,
void* aObject)
nsISupports* aObject)
{
#ifdef NS_BUILD_REFCNT_LOGGING
#if defined(NS_BUILD_REFCNT_LOGGING) && defined(HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR)
// Get the most-derived object.
void *object = dynamic_cast<void *>(aObject);
// This is a very indirect way of finding out what the class is
// of the object being logged. If we're logging a specific type,
// then
if (!gTypesToLog || !gSerialNumbers) {
return;
}
PRInt32 serialno = GetSerialNumber(aObject, PR_FALSE);
PRInt32 serialno = GetSerialNumber(object, PR_FALSE);
if (serialno == 0) {
return;
}
@ -1897,7 +1964,7 @@ nsTraceRefcnt::LogReleaseCOMPtr(void* aCOMPtr,
if (gLogging) {
LOCK_TRACELOG();
PRInt32* count = GetCOMPtrCount(aObject);
PRInt32* count = GetCOMPtrCount(object);
if(count)
(*count)--;
@ -1906,7 +1973,7 @@ nsTraceRefcnt::LogReleaseCOMPtr(void* aCOMPtr,
if (gCOMPtrLog && loggingThisObject) {
fprintf(gCOMPtrLog, "\n<?> 0x%08X %d nsCOMPtrRelease %d 0x%08X\n",
PRInt32(aObject), serialno, count?(*count):-1, PRInt32(aCOMPtr));
PRInt32(object), serialno, count?(*count):-1, PRInt32(aCOMPtr));
WalkTheStack(gCOMPtrLog);
}
#endif

Просмотреть файл

@ -18,6 +18,7 @@
* Rights Reserved.
*
* Contributor(s):
* L. David Baron <dbaron@fas.harvard.edu>
*/
#ifndef nsTraceRefcnt_h___
#define nsTraceRefcnt_h___
@ -26,6 +27,8 @@
#include <stdio.h>
class nsISupports;
// Normaly, the implementation of NS_LOG_ADDREF and NS_LOG_RELEASE
// will use a stack crawl to determine who called Addref/Release on an
// xpcom object. If your platform can't implement a stack crawling
@ -82,7 +85,7 @@
#endif
#define MOZ_DECL_CTOR_COUNTER(_type);
#define MOZ_DECL_CTOR_COUNTER(_type)
#define MOZ_COUNT_CTOR(_type) \
PR_BEGIN_MACRO \
@ -98,13 +101,14 @@ PR_END_MACRO
// set for non-autoconf platforms)
// nsCOMPtr.h allows these macros to be defined by clients
// a dynamic_cast to void* gives the most derived object
// These logging functions require dynamic_cast<void *>, so we don't
// define these macros if we don't have dynamic_cast.
#define NSCAP_LOG_ASSIGNMENT(_c, _p) \
if ((_p)) nsTraceRefcnt::LogAddCOMPtr((_c),dynamic_cast<void *>(NS_STATIC_CAST(nsISupports*,_p)))
if ((_p)) nsTraceRefcnt::LogAddCOMPtr((_c),NS_STATIC_CAST(nsISupports*,_p))
#define NSCAP_RELEASE(_c, _p); \
if ((_p)) { \
nsTraceRefcnt::LogReleaseCOMPtr((_c),dynamic_cast<void *>(NS_STATIC_CAST(nsISupports*,_p))); \
nsTraceRefcnt::LogReleaseCOMPtr((_c),NS_STATIC_CAST(nsISupports*,_p)); \
NS_RELEASE(_p); \
}
@ -118,7 +122,7 @@ PR_END_MACRO
#define NS_LOG_DELETE_XPCOM(_p,_file,_line)
#define NS_LOG_ADDREF_CALL(_p,_rc,_file,_line) _rc
#define NS_LOG_RELEASE_CALL(_p,_rc,_file,_line) _rc
#define MOZ_DECL_CTOR_COUNTER(_type);
#define MOZ_DECL_CTOR_COUNTER(_type)
#define MOZ_COUNT_CTOR(_type)
#define MOZ_COUNT_DTOR(_type)
@ -158,6 +162,10 @@ typedef PRBool (PR_CALLBACK *nsTraceRefcntStatFunc)
*/
class nsTraceRefcnt {
public:
static NS_COM void Startup();
static NS_COM void Shutdown();
static NS_COM void LogAddRef(void* aPtr,
nsrefcnt aNewRefCnt,
const char* aTypeName,
@ -193,9 +201,9 @@ public:
static NS_COM void LogDtor(void* aPtr, const char* aTypeName,
PRUint32 aInstanceSize);
static NS_COM void LogAddCOMPtr(void *aCOMPtr, void* aObject);
static NS_COM void LogAddCOMPtr(void *aCOMPtr, nsISupports *aObject);
static NS_COM void LogReleaseCOMPtr(void *aCOMPtr, void* aObject);
static NS_COM void LogReleaseCOMPtr(void *aCOMPtr, nsISupports *aObject);
enum StatisticsType {
ALL_STATS,
@ -220,6 +228,13 @@ public:
static NS_COM void WalkTheStack(FILE* aStream);
static NS_COM void SetPrefServiceAvailability(PRBool avail);
/**
* Tell nsTraceRefcnt whether refcounting, allocation, and destruction
* activity is legal. This is used to trigger assertions for any such
* activity that occurs because of static constructors or destructors.
*/
static NS_COM void SetActivityIsLegal(PRBool aLegal);
};
////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -18,7 +18,7 @@
* Rights Reserved.
*
* Contributor(s):
* L. David Baron (dbaron@fas.harvard.edu)
* L. David Baron <dbaron@fas.harvard.edu>
*/
#include "nsISupports.h"
@ -114,6 +114,7 @@ static FILE *gRefcntsLog = nsnull;
static FILE *gAllocLog = nsnull;
static FILE *gLeakyLog = nsnull;
static FILE *gCOMPtrLog = nsnull;
static PRBool gActivityIsLegal = PR_FALSE;
#define XPCOM_REFCNT_TRACK_BLOAT 0x1
#define XPCOM_REFCNT_LOG_ALL 0x2
@ -1520,6 +1521,58 @@ nsTraceRefcnt::LoadLibrarySymbols(const char* aLibraryName,
//----------------------------------------------------------------------
NS_COM void
nsTraceRefcnt::Startup()
{
#ifdef NS_BUILD_REFCNT_LOGGING
SetActivityIsLegal(PR_TRUE);
#endif
}
NS_COM void
nsTraceRefcnt::Shutdown()
{
#ifdef NS_BUILD_REFCNT_LOGGING
if (gBloatView) {
PL_HashTableDestroy(gBloatView);
gBloatView = nsnull;
}
if (gTypesToLog) {
PL_HashTableDestroy(gTypesToLog);
gTypesToLog = nsnull;
}
if (gObjectsToLog) {
PL_HashTableDestroy(gObjectsToLog);
gObjectsToLog = nsnull;
}
if (gSerialNumbers) {
PL_HashTableDestroy(gSerialNumbers);
gSerialNumbers = nsnull;
}
SetActivityIsLegal(PR_FALSE);
#endif
}
NS_COM void
nsTraceRefcnt::SetActivityIsLegal(PRBool aLegal)
{
#ifdef NS_BUILD_REFCNT_LOGGING
gActivityIsLegal = aLegal;
#endif
}
#ifdef DEBUG_dbaron
// I hope to turn this on for everybody once we hit it a little less.
#define ASSERT_ACTIVITY_IS_LEGAL \
NS_WARN_IF_FALSE(gActivityIsLegal, \
"XPCOM objects created/destroyed from static ctor/dtor")
#else
#define ASSERT_ACTIVITY_IS_LEGAL
#endif
/*
For consistency, and ease of munging the output, the following record format will be used:
@ -1533,6 +1586,7 @@ nsTraceRefcnt::LogAddRef(void* aPtr,
PRUint32 classSize)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
if (!gInitialized)
InitTraceLog();
if (gLogging) {
@ -1595,6 +1649,7 @@ nsTraceRefcnt::LogRelease(void* aPtr,
const char* aClazz)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
if (!gInitialized)
InitTraceLog();
if (gLogging) {
@ -1663,6 +1718,7 @@ nsTraceRefcnt::LogAddRefCall(void* aPtr,
int aLine)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
#ifdef NS_LOSING_ARCHITECTURE
if (!gInitialized)
InitTraceLog();
@ -1687,6 +1743,7 @@ nsTraceRefcnt::LogReleaseCall(void* aPtr,
int aLine)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
#ifdef NS_LOSING_ARCHITECTURE
if (!gInitialized)
InitTraceLog();
@ -1713,6 +1770,7 @@ nsTraceRefcnt::LogNewXPCOM(void* aPtr,
int aLine)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
#ifdef NS_LOSING_ARCHITECTURE
if (!gInitialized)
InitTraceLog();
@ -1736,6 +1794,7 @@ nsTraceRefcnt::LogDeleteXPCOM(void* aPtr,
int aLine)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
#ifdef NS_LOSING_ARCHITECTURE
if (!gInitialized)
InitTraceLog();
@ -1759,6 +1818,7 @@ nsTraceRefcnt::LogCtor(void* aPtr,
PRUint32 aInstanceSize)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
if (!gInitialized)
InitTraceLog();
@ -1799,6 +1859,7 @@ nsTraceRefcnt::LogDtor(void* aPtr, const char* aType,
PRUint32 aInstanceSize)
{
#ifdef NS_BUILD_REFCNT_LOGGING
ASSERT_ACTIVITY_IS_LEGAL;
if (!gInitialized)
InitTraceLog();
@ -1838,16 +1899,19 @@ nsTraceRefcnt::LogDtor(void* aPtr, const char* aType,
NS_COM void
nsTraceRefcnt::LogAddCOMPtr(void* aCOMPtr,
void* aObject)
nsISupports* aObject)
{
#ifdef NS_BUILD_REFCNT_LOGGING
#if defined(NS_BUILD_REFCNT_LOGGING) && defined(HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR)
// Get the most-derived object.
void *object = dynamic_cast<void *>(aObject);
// This is a very indirect way of finding out what the class is
// of the object being logged. If we're logging a specific type,
// then
if (!gTypesToLog || !gSerialNumbers) {
return;
}
PRInt32 serialno = GetSerialNumber(aObject, PR_FALSE);
PRInt32 serialno = GetSerialNumber(object, PR_FALSE);
if (serialno == 0) {
return;
}
@ -1857,7 +1921,7 @@ nsTraceRefcnt::LogAddCOMPtr(void* aCOMPtr,
if (gLogging) {
LOCK_TRACELOG();
PRInt32* count = GetCOMPtrCount(aObject);
PRInt32* count = GetCOMPtrCount(object);
if(count)
(*count)++;
@ -1866,7 +1930,7 @@ nsTraceRefcnt::LogAddCOMPtr(void* aCOMPtr,
if (gCOMPtrLog && loggingThisObject) {
fprintf(gCOMPtrLog, "\n<?> 0x%08X %d nsCOMPtrAddRef %d 0x%08X\n",
PRInt32(aObject), serialno, count?(*count):-1, PRInt32(aCOMPtr));
PRInt32(object), serialno, count?(*count):-1, PRInt32(aCOMPtr));
WalkTheStack(gCOMPtrLog);
}
#endif
@ -1878,16 +1942,19 @@ nsTraceRefcnt::LogAddCOMPtr(void* aCOMPtr,
NS_COM void
nsTraceRefcnt::LogReleaseCOMPtr(void* aCOMPtr,
void* aObject)
nsISupports* aObject)
{
#ifdef NS_BUILD_REFCNT_LOGGING
#if defined(NS_BUILD_REFCNT_LOGGING) && defined(HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR)
// Get the most-derived object.
void *object = dynamic_cast<void *>(aObject);
// This is a very indirect way of finding out what the class is
// of the object being logged. If we're logging a specific type,
// then
if (!gTypesToLog || !gSerialNumbers) {
return;
}
PRInt32 serialno = GetSerialNumber(aObject, PR_FALSE);
PRInt32 serialno = GetSerialNumber(object, PR_FALSE);
if (serialno == 0) {
return;
}
@ -1897,7 +1964,7 @@ nsTraceRefcnt::LogReleaseCOMPtr(void* aCOMPtr,
if (gLogging) {
LOCK_TRACELOG();
PRInt32* count = GetCOMPtrCount(aObject);
PRInt32* count = GetCOMPtrCount(object);
if(count)
(*count)--;
@ -1906,7 +1973,7 @@ nsTraceRefcnt::LogReleaseCOMPtr(void* aCOMPtr,
if (gCOMPtrLog && loggingThisObject) {
fprintf(gCOMPtrLog, "\n<?> 0x%08X %d nsCOMPtrRelease %d 0x%08X\n",
PRInt32(aObject), serialno, count?(*count):-1, PRInt32(aCOMPtr));
PRInt32(object), serialno, count?(*count):-1, PRInt32(aCOMPtr));
WalkTheStack(gCOMPtrLog);
}
#endif

Просмотреть файл

@ -18,6 +18,7 @@
* Rights Reserved.
*
* Contributor(s):
* L. David Baron <dbaron@fas.harvard.edu>
*/
#ifndef nsTraceRefcnt_h___
#define nsTraceRefcnt_h___
@ -26,6 +27,8 @@
#include <stdio.h>
class nsISupports;
// Normaly, the implementation of NS_LOG_ADDREF and NS_LOG_RELEASE
// will use a stack crawl to determine who called Addref/Release on an
// xpcom object. If your platform can't implement a stack crawling
@ -82,7 +85,7 @@
#endif
#define MOZ_DECL_CTOR_COUNTER(_type);
#define MOZ_DECL_CTOR_COUNTER(_type)
#define MOZ_COUNT_CTOR(_type) \
PR_BEGIN_MACRO \
@ -98,13 +101,14 @@ PR_END_MACRO
// set for non-autoconf platforms)
// nsCOMPtr.h allows these macros to be defined by clients
// a dynamic_cast to void* gives the most derived object
// These logging functions require dynamic_cast<void *>, so we don't
// define these macros if we don't have dynamic_cast.
#define NSCAP_LOG_ASSIGNMENT(_c, _p) \
if ((_p)) nsTraceRefcnt::LogAddCOMPtr((_c),dynamic_cast<void *>(NS_STATIC_CAST(nsISupports*,_p)))
if ((_p)) nsTraceRefcnt::LogAddCOMPtr((_c),NS_STATIC_CAST(nsISupports*,_p))
#define NSCAP_RELEASE(_c, _p); \
if ((_p)) { \
nsTraceRefcnt::LogReleaseCOMPtr((_c),dynamic_cast<void *>(NS_STATIC_CAST(nsISupports*,_p))); \
nsTraceRefcnt::LogReleaseCOMPtr((_c),NS_STATIC_CAST(nsISupports*,_p)); \
NS_RELEASE(_p); \
}
@ -118,7 +122,7 @@ PR_END_MACRO
#define NS_LOG_DELETE_XPCOM(_p,_file,_line)
#define NS_LOG_ADDREF_CALL(_p,_rc,_file,_line) _rc
#define NS_LOG_RELEASE_CALL(_p,_rc,_file,_line) _rc
#define MOZ_DECL_CTOR_COUNTER(_type);
#define MOZ_DECL_CTOR_COUNTER(_type)
#define MOZ_COUNT_CTOR(_type)
#define MOZ_COUNT_DTOR(_type)
@ -158,6 +162,10 @@ typedef PRBool (PR_CALLBACK *nsTraceRefcntStatFunc)
*/
class nsTraceRefcnt {
public:
static NS_COM void Startup();
static NS_COM void Shutdown();
static NS_COM void LogAddRef(void* aPtr,
nsrefcnt aNewRefCnt,
const char* aTypeName,
@ -193,9 +201,9 @@ public:
static NS_COM void LogDtor(void* aPtr, const char* aTypeName,
PRUint32 aInstanceSize);
static NS_COM void LogAddCOMPtr(void *aCOMPtr, void* aObject);
static NS_COM void LogAddCOMPtr(void *aCOMPtr, nsISupports *aObject);
static NS_COM void LogReleaseCOMPtr(void *aCOMPtr, void* aObject);
static NS_COM void LogReleaseCOMPtr(void *aCOMPtr, nsISupports *aObject);
enum StatisticsType {
ALL_STATS,
@ -220,6 +228,13 @@ public:
static NS_COM void WalkTheStack(FILE* aStream);
static NS_COM void SetPrefServiceAvailability(PRBool avail);
/**
* Tell nsTraceRefcnt whether refcounting, allocation, and destruction
* activity is legal. This is used to trigger assertions for any such
* activity that occurs because of static constructors or destructors.
*/
static NS_COM void SetActivityIsLegal(PRBool aLegal);
};
////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -210,6 +210,10 @@ nsresult NS_COM NS_InitXPCOM2(const char* productName,
{
nsresult rv = NS_OK;
#ifdef NS_BUILD_REFCNT_LOGGING
nsTraceRefcnt::Startup();
#endif
// Establish the main thread here.
rv = nsIThread::SetMainThread();
if (NS_FAILED(rv)) return rv;
@ -695,9 +699,10 @@ nsresult NS_COM NS_ShutdownXPCOM(nsIServiceManager* servMgr)
nsThread::Shutdown();
NS_PurgeAtomTable();
#if (defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING))
#ifdef NS_BUILD_REFCNT_LOGGING
nsTraceRefcnt::DumpStatistics();
nsTraceRefcnt::ResetStatistics();
nsTraceRefcnt::Shutdown();
#endif
#ifdef GC_LEAK_DETECTOR

Просмотреть файл

@ -313,10 +313,14 @@ PRBool nsDll::Load(void)
{
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(m_dllSpec);
#ifdef NS_BUILD_REFCNT_LOGGING
nsTraceRefcnt::SetActivityIsLegal(PR_FALSE);
#endif
if (localFile)
localFile->Load(&m_instance);
#ifdef NS_BUILD_REFCNT_LOGGING
nsTraceRefcnt::SetActivityIsLegal(PR_TRUE);
if (m_instance) {
// Inform refcnt tracer of new library so that calls through the
// new library can be traced.
@ -330,9 +334,13 @@ PRBool nsDll::Load(void)
else if (m_dllName)
{
// if there is not an nsIFile, but there is a dll name, just try to load that..
#ifdef NS_BUILD_REFCNT_LOGGING
nsTraceRefcnt::SetActivityIsLegal(PR_FALSE);
#endif
m_instance = PR_LoadLibrary(m_dllName);
#ifdef NS_BUILD_REFCNT_LOGGING
nsTraceRefcnt::SetActivityIsLegal(PR_TRUE);
if (m_instance) {
// Inform refcnt tracer of new library so that calls through the
// new library can be traced.
@ -359,7 +367,14 @@ PRBool nsDll::Unload(void)
// Shutdown the dll
Shutdown();
#ifdef NS_BUILD_REFCNT_LOGGING
nsTraceRefcnt::SetActivityIsLegal(PR_FALSE);
#endif
PRStatus ret = PR_UnloadLibrary(m_instance);
#ifdef NS_BUILD_REFCNT_LOGGING
nsTraceRefcnt::SetActivityIsLegal(PR_TRUE);
#endif
if (ret == PR_SUCCESS)
{
m_instance = NULL;