void nsTraceRefcntImpl::Shutdown() { #ifdef NS_IMPL_REFCNT_LOGGING if (gBloatView) { PL_HashTableDestroy(gBloatView); gBloatView = nullptr; } if (gTypesToLog) { PL_HashTableDestroy(gTypesToLog); gTypesToLog = nullptr; } if (gObjectsToLog) { PL_HashTableDestroy(gObjectsToLog); gObjectsToLog = nullptr; } if (gSerialNumbers) { PL_HashTableDestroy(gSerialNumbers); gSerialNumbers = nullptr; } maybeUnregisterAndCloseFile(gBloatLog); maybeUnregisterAndCloseFile(gRefcntsLog); maybeUnregisterAndCloseFile(gAllocLog); maybeUnregisterAndCloseFile(gLeakyLog); maybeUnregisterAndCloseFile(gCOMPtrLog); #endif }
void nsTraceRefcnt::Shutdown() { #ifdef NS_IMPL_REFCNT_LOGGING #ifdef MOZ_STACKWALKING gCodeAddressService = nullptr; #endif if (gBloatView) { PL_HashTableDestroy(gBloatView); gBloatView = nullptr; } if (gTypesToLog) { PL_HashTableDestroy(gTypesToLog); gTypesToLog = nullptr; } if (gObjectsToLog) { PL_HashTableDestroy(gObjectsToLog); gObjectsToLog = nullptr; } if (gSerialNumbers) { PL_HashTableDestroy(gSerialNumbers); gSerialNumbers = nullptr; } maybeUnregisterAndCloseFile(gBloatLog); maybeUnregisterAndCloseFile(gRefcntsLog); maybeUnregisterAndCloseFile(gAllocLog); maybeUnregisterAndCloseFile(gCOMPtrLog); #endif }
void nsTraceRefcnt::Shutdown() { gCodeAddressService = nullptr; if (gBloatView) { PL_HashTableDestroy(gBloatView); gBloatView = nullptr; } if (gTypesToLog) { PL_HashTableDestroy(gTypesToLog); gTypesToLog = nullptr; } if (gObjectsToLog) { PL_HashTableDestroy(gObjectsToLog); gObjectsToLog = nullptr; } if (gSerialNumbers) { PL_HashTableDestroy(gSerialNumbers); gSerialNumbers = nullptr; } maybeUnregisterAndCloseFile(gBloatLog); maybeUnregisterAndCloseFile(gRefcntsLog); maybeUnregisterAndCloseFile(gAllocLog); maybeUnregisterAndCloseFile(gCOMPtrLog); }
static void InitTraceLog() { if (gInitialized) { return; } gInitialized = true; bool defined = InitLog("XPCOM_MEM_BLOAT_LOG", "bloat/leaks", &gBloatLog); if (!defined) { gLogLeaksOnly = InitLog("XPCOM_MEM_LEAK_LOG", "leaks", &gBloatLog); } if (defined || gLogLeaksOnly) { RecreateBloatView(); if (!gBloatView) { NS_WARNING("out of memory"); maybeUnregisterAndCloseFile(gBloatLog); gLogLeaksOnly = false; } } InitLog("XPCOM_MEM_REFCNT_LOG", "refcounts", &gRefcntsLog); InitLog("XPCOM_MEM_ALLOC_LOG", "new/delete", &gAllocLog); const char* classes = getenv("XPCOM_MEM_LOG_CLASSES"); #ifdef HAVE_CPP_DYNAMIC_CAST_TO_VOID_PTR if (classes) { InitLog("XPCOM_MEM_COMPTR_LOG", "nsCOMPtr", &gCOMPtrLog); } else { if (getenv("XPCOM_MEM_COMPTR_LOG")) { fprintf(stdout, "### XPCOM_MEM_COMPTR_LOG defined -- but XPCOM_MEM_LOG_CLASSES is not defined\n"); } } #else const char* comptr_log = getenv("XPCOM_MEM_COMPTR_LOG"); if (comptr_log) { fprintf(stdout, "### XPCOM_MEM_COMPTR_LOG defined -- but it will not work without dynamic_cast\n"); } #endif if (classes) { // if XPCOM_MEM_LOG_CLASSES was set to some value, the value is interpreted // as a list of class names to track gTypesToLog = PL_NewHashTable(256, PL_HashString, PL_CompareStrings, PL_CompareValues, &typesToLogHashAllocOps, nullptr); if (!gTypesToLog) { NS_WARNING("out of memory"); fprintf(stdout, "### XPCOM_MEM_LOG_CLASSES defined -- unable to log specific classes\n"); } else { fprintf(stdout, "### XPCOM_MEM_LOG_CLASSES defined -- only logging these classes: "); const char* cp = classes; for (;;) { char* cm = (char*)strchr(cp, ','); if (cm) { *cm = '\0'; } PL_HashTableAdd(gTypesToLog, strdup(cp), (void*)1); fprintf(stdout, "%s ", cp); if (!cm) { break; } *cm = ','; cp = cm + 1; } fprintf(stdout, "\n"); } gSerialNumbers = PL_NewHashTable(256, HashNumber, PL_CompareValues, PL_CompareValues, &serialNumberHashAllocOps, nullptr); } const char* objects = getenv("XPCOM_MEM_LOG_OBJECTS"); if (objects) { gObjectsToLog = PL_NewHashTable(256, HashNumber, PL_CompareValues, PL_CompareValues, nullptr, nullptr); if (!gObjectsToLog) { NS_WARNING("out of memory"); fprintf(stdout, "### XPCOM_MEM_LOG_OBJECTS defined -- unable to log specific objects\n"); } else if (!(gRefcntsLog || gAllocLog || gCOMPtrLog)) { fprintf(stdout, "### XPCOM_MEM_LOG_OBJECTS defined -- but none of XPCOM_MEM_(REFCNT|ALLOC|COMPTR)_LOG is defined\n"); } else { fprintf(stdout, "### XPCOM_MEM_LOG_OBJECTS defined -- only logging these objects: "); const char* cp = objects; for (;;) { char* cm = (char*)strchr(cp, ','); if (cm) { *cm = '\0'; } intptr_t top = 0; intptr_t bottom = 0; while (*cp) { if (*cp == '-') { bottom = top; top = 0; ++cp; } top *= 10; top += *cp - '0'; ++cp; } if (!bottom) { bottom = top; } for (intptr_t serialno = bottom; serialno <= top; serialno++) { PL_HashTableAdd(gObjectsToLog, (const void*)serialno, (void*)1); fprintf(stdout, "%" PRIdPTR " ", serialno); } if (!cm) { break; } *cm = ','; cp = cm + 1; } fprintf(stdout, "\n"); } } if (gBloatLog) { gLogging = OnlyBloatLogging; } if (gRefcntsLog || gAllocLog || gCOMPtrLog) { gLogging = FullLogging; } gTraceLock = PR_NewLock(); }