Bug 1308652, part 2 - Only allow nsTraceRefcnt::DumpStatistics to be called once. r=froydnj
DumpStatistics does not track any objects that are created or
destroyed while it is running, which means that any subsequent calls
to it will produce incorrect results. This can lead to incorrect
positive or negative leaks being reported. See 1271182.
Now that about:bloat has been removed, DumpStatistics should only be
called once, during shutdown.
MozReview-Commit-ID: IjMkExeBRBr
--- a/xpcom/base/nsTraceRefcnt.cpp
+++ b/xpcom/base/nsTraceRefcnt.cpp
@@ -78,16 +78,17 @@ struct MOZ_STACK_CLASS AutoTraceLogLock
~AutoTraceLogLock() { if (doRelease) gTraceLogLocked = 0; }
};
static PLHashTable* gBloatView;
static PLHashTable* gTypesToLog;
static PLHashTable* gObjectsToLog;
static PLHashTable* gSerialNumbers;
static intptr_t gNextSerialNumber;
+static bool gDumpedStatistics = false;
// By default, debug builds only do bloat logging. Bloat logging
// only tries to record when an object is created or destroyed, so we
// optimize the common case in NS_LogAddRef and NS_LogRelease where
// only bloat logging is enabled and no logging needs to be done.
enum LoggingType
{
NoLogging,
@@ -519,16 +520,21 @@ nsTraceRefcnt::DumpStatistics(Statistics
return NS_ERROR_FAILURE;
}
if (!aOut) {
aOut = gBloatLog;
}
AutoTraceLogLock lock;
+ MOZ_ASSERT(!gDumpedStatistics,
+ "Calling DumpStatistics more than once may result in "
+ "bogus positive or negative leaks being reported");
+ gDumpedStatistics = true;
+
// Don't try to log while we hold the lock, we'd deadlock.
AutoRestore<LoggingType> saveLogging(gLogging);
gLogging = NoLogging;
BloatEntry total("TOTAL", 0);
PL_HashTableEnumerateEntries(gBloatView, BloatEntry::TotalEntries, &total);
const char* msg;
if (aType == NEW_STATS) {