зеркало из https://github.com/mozilla/pjs.git
r=dp; implement some macros to help track memory leaks
This commit is contained in:
Родитель
c90dade264
Коммит
596f2c8f8b
|
@ -17,8 +17,10 @@
|
|||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
#include "nsISupports.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "prprf.h"
|
||||
#include "prlog.h"
|
||||
#include "plstr.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
|
@ -542,3 +544,99 @@ nsTraceRefcnt::DemangleSymbol(const char * aSymbol,
|
|||
}
|
||||
#endif // __linux__
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
struct CtorEntry {
|
||||
const char* type;
|
||||
mozCtorDtorCounter* counter;
|
||||
};
|
||||
|
||||
nsVoidArray* nsTraceRefcnt::mCtors;
|
||||
|
||||
void
|
||||
nsTraceRefcnt::RegisterCtor(const char* aType,
|
||||
mozCtorDtorCounter* aCounterAddr)
|
||||
{
|
||||
if (!mCtors) {
|
||||
mCtors = new nsVoidArray();
|
||||
if (!mCtors) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
CtorEntry* e = new CtorEntry();
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
e->type = aType;
|
||||
e->counter = aCounterAddr;
|
||||
mCtors->AppendElement(e);
|
||||
}
|
||||
|
||||
void
|
||||
nsTraceRefcnt::UnregisterCtor(const char* aType)
|
||||
{
|
||||
if (mCtors) {
|
||||
PRInt32 i, n = mCtors->Count();
|
||||
for (i = 0; i < n; i++) {
|
||||
CtorEntry* e = (CtorEntry*) mCtors->ElementAt(i);
|
||||
if (0 == PL_strcmp(e->type, aType)) {
|
||||
delete e;
|
||||
mCtors->RemoveElementAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTraceRefcnt::DumpLeaks(FILE* out)
|
||||
{
|
||||
if (mCtors) {
|
||||
PRBool haveLeaks = PR_FALSE;
|
||||
PRInt32 i, n = mCtors->Count();
|
||||
for (i = 0; i < n; i++) {
|
||||
CtorEntry* e = (CtorEntry*) mCtors->ElementAt(i);
|
||||
if (e) {
|
||||
mozCtorDtorCounter* cdc = e->counter;
|
||||
if (cdc) {
|
||||
if (cdc->ctors != cdc->dtors) {
|
||||
haveLeaks = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (haveLeaks) {
|
||||
fprintf(out, "*** There are memory leaks:\n");
|
||||
fprintf(out, "%-40s %-15s %s\n", "Type", "# created", "# leaked");
|
||||
fprintf(out, "%-40s %-15s %s\n", "----", "---------", "--------");
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
CtorEntry* e = (CtorEntry*) mCtors->ElementAt(i);
|
||||
if (e && e->counter) {
|
||||
mozCtorDtorCounter* cdc = e->counter;
|
||||
if (cdc->ctors != cdc->dtors) {
|
||||
fprintf(out, "%-40s %-15d %d\n", e->type, cdc->ctors,
|
||||
cdc->ctors - cdc->dtors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTraceRefcnt::FlushCtorRegistry(void)
|
||||
{
|
||||
if (mCtors) {
|
||||
PRInt32 i, n = mCtors->Count();
|
||||
for (i = 0; i < n; i++) {
|
||||
CtorEntry* e = (CtorEntry*) mCtors->ElementAt(i);
|
||||
delete e;
|
||||
}
|
||||
delete mCtors;
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
|
|
@ -20,6 +20,16 @@
|
|||
#define nsTraceRefcnt_h___
|
||||
|
||||
#include "nsCom.h"
|
||||
#include <stdio.h>
|
||||
|
||||
class nsVoidArray;
|
||||
|
||||
#ifdef DEBUG
|
||||
struct mozCtorDtorCounter {
|
||||
PRInt32 ctors;
|
||||
PRInt32 dtors;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This class is used to support tracing (and logging using nspr) of
|
||||
|
@ -71,6 +81,63 @@ public:
|
|||
const char* aFile,
|
||||
int aLine);
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
* Register a constructor with the xpcom library. This records the
|
||||
* type name and the address of the counter so that later on when
|
||||
* DumpLeaks is called, we can print out those objects ctors whose
|
||||
* counter is not zero (the ones that have live object references
|
||||
* still out there)
|
||||
*/
|
||||
static NS_COM void RegisterCtor(const char* aType,
|
||||
mozCtorDtorCounter* aCounterAddr);
|
||||
|
||||
static NS_COM void UnregisterCtor(const char* aType);
|
||||
|
||||
/**
|
||||
* Dump the leaking constructors out.
|
||||
*/
|
||||
static NS_COM void DumpLeaks(FILE* out);
|
||||
|
||||
/**
|
||||
* Erase the ctor registration data.
|
||||
*/
|
||||
static NS_COM void FlushCtorRegistry(void);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
#ifdef DEBUG
|
||||
static nsVoidArray* mCtors;
|
||||
#endif
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#define MOZ_DECL_CTOR(_type) \
|
||||
static mozCtorDtorCounter gCounter_##_type
|
||||
|
||||
#define MOZ_CTOR(_type) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (0 == gCounter_##_type . ctors) { \
|
||||
nsTraceRefcnt::RegisterCtor(#_type, &gCounter_##_type); \
|
||||
} \
|
||||
gCounter_##_type . ctors++; \
|
||||
PR_END_MACRO
|
||||
|
||||
#define MOZ_DTOR(_type) \
|
||||
PR_BEGIN_MACRO \
|
||||
gCounter_##_type . dtors ++; \
|
||||
PR_END_MACRO
|
||||
|
||||
#else
|
||||
|
||||
#define MOZ_REG_CTOR(_type,_counter)
|
||||
#define MOZ_DECL_CTOR_(type)
|
||||
#define MOZ_CTOR(_type)
|
||||
#define MOZ_DTOR(_type)
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
#endif /* nsTraceRefcnt_h___ */
|
||||
|
|
|
@ -17,8 +17,10 @@
|
|||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
#include "nsISupports.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "prprf.h"
|
||||
#include "prlog.h"
|
||||
#include "plstr.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
|
@ -542,3 +544,99 @@ nsTraceRefcnt::DemangleSymbol(const char * aSymbol,
|
|||
}
|
||||
#endif // __linux__
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
struct CtorEntry {
|
||||
const char* type;
|
||||
mozCtorDtorCounter* counter;
|
||||
};
|
||||
|
||||
nsVoidArray* nsTraceRefcnt::mCtors;
|
||||
|
||||
void
|
||||
nsTraceRefcnt::RegisterCtor(const char* aType,
|
||||
mozCtorDtorCounter* aCounterAddr)
|
||||
{
|
||||
if (!mCtors) {
|
||||
mCtors = new nsVoidArray();
|
||||
if (!mCtors) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
CtorEntry* e = new CtorEntry();
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
e->type = aType;
|
||||
e->counter = aCounterAddr;
|
||||
mCtors->AppendElement(e);
|
||||
}
|
||||
|
||||
void
|
||||
nsTraceRefcnt::UnregisterCtor(const char* aType)
|
||||
{
|
||||
if (mCtors) {
|
||||
PRInt32 i, n = mCtors->Count();
|
||||
for (i = 0; i < n; i++) {
|
||||
CtorEntry* e = (CtorEntry*) mCtors->ElementAt(i);
|
||||
if (0 == PL_strcmp(e->type, aType)) {
|
||||
delete e;
|
||||
mCtors->RemoveElementAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTraceRefcnt::DumpLeaks(FILE* out)
|
||||
{
|
||||
if (mCtors) {
|
||||
PRBool haveLeaks = PR_FALSE;
|
||||
PRInt32 i, n = mCtors->Count();
|
||||
for (i = 0; i < n; i++) {
|
||||
CtorEntry* e = (CtorEntry*) mCtors->ElementAt(i);
|
||||
if (e) {
|
||||
mozCtorDtorCounter* cdc = e->counter;
|
||||
if (cdc) {
|
||||
if (cdc->ctors != cdc->dtors) {
|
||||
haveLeaks = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (haveLeaks) {
|
||||
fprintf(out, "*** There are memory leaks:\n");
|
||||
fprintf(out, "%-40s %-15s %s\n", "Type", "# created", "# leaked");
|
||||
fprintf(out, "%-40s %-15s %s\n", "----", "---------", "--------");
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
CtorEntry* e = (CtorEntry*) mCtors->ElementAt(i);
|
||||
if (e && e->counter) {
|
||||
mozCtorDtorCounter* cdc = e->counter;
|
||||
if (cdc->ctors != cdc->dtors) {
|
||||
fprintf(out, "%-40s %-15d %d\n", e->type, cdc->ctors,
|
||||
cdc->ctors - cdc->dtors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsTraceRefcnt::FlushCtorRegistry(void)
|
||||
{
|
||||
if (mCtors) {
|
||||
PRInt32 i, n = mCtors->Count();
|
||||
for (i = 0; i < n; i++) {
|
||||
CtorEntry* e = (CtorEntry*) mCtors->ElementAt(i);
|
||||
delete e;
|
||||
}
|
||||
delete mCtors;
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
|
|
@ -20,6 +20,16 @@
|
|||
#define nsTraceRefcnt_h___
|
||||
|
||||
#include "nsCom.h"
|
||||
#include <stdio.h>
|
||||
|
||||
class nsVoidArray;
|
||||
|
||||
#ifdef DEBUG
|
||||
struct mozCtorDtorCounter {
|
||||
PRInt32 ctors;
|
||||
PRInt32 dtors;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This class is used to support tracing (and logging using nspr) of
|
||||
|
@ -71,6 +81,63 @@ public:
|
|||
const char* aFile,
|
||||
int aLine);
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
* Register a constructor with the xpcom library. This records the
|
||||
* type name and the address of the counter so that later on when
|
||||
* DumpLeaks is called, we can print out those objects ctors whose
|
||||
* counter is not zero (the ones that have live object references
|
||||
* still out there)
|
||||
*/
|
||||
static NS_COM void RegisterCtor(const char* aType,
|
||||
mozCtorDtorCounter* aCounterAddr);
|
||||
|
||||
static NS_COM void UnregisterCtor(const char* aType);
|
||||
|
||||
/**
|
||||
* Dump the leaking constructors out.
|
||||
*/
|
||||
static NS_COM void DumpLeaks(FILE* out);
|
||||
|
||||
/**
|
||||
* Erase the ctor registration data.
|
||||
*/
|
||||
static NS_COM void FlushCtorRegistry(void);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
#ifdef DEBUG
|
||||
static nsVoidArray* mCtors;
|
||||
#endif
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#define MOZ_DECL_CTOR(_type) \
|
||||
static mozCtorDtorCounter gCounter_##_type
|
||||
|
||||
#define MOZ_CTOR(_type) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (0 == gCounter_##_type . ctors) { \
|
||||
nsTraceRefcnt::RegisterCtor(#_type, &gCounter_##_type); \
|
||||
} \
|
||||
gCounter_##_type . ctors++; \
|
||||
PR_END_MACRO
|
||||
|
||||
#define MOZ_DTOR(_type) \
|
||||
PR_BEGIN_MACRO \
|
||||
gCounter_##_type . dtors ++; \
|
||||
PR_END_MACRO
|
||||
|
||||
#else
|
||||
|
||||
#define MOZ_REG_CTOR(_type,_counter)
|
||||
#define MOZ_DECL_CTOR_(type)
|
||||
#define MOZ_CTOR(_type)
|
||||
#define MOZ_DTOR(_type)
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
#endif /* nsTraceRefcnt_h___ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче