Dump handle information when a plugin is forcefully unloaded. (bug 5666, r=asherkin)
authorKyle Sanderson <kyle.leet@gmail.com>
Mon Aug 12 00:45:29 2013 +0100 (2013-08-12)
changeset 39964a0daf289347
parent 3995 e94dfd569130
child 3997 59bcfc51eb79
Dump handle information when a plugin is forcefully unloaded. (bug 5666, r=asherkin)
core/logic/HandleSys.cpp
     1.1 --- a/core/logic/HandleSys.cpp	Mon Aug 12 00:44:22 2013 +0100
     1.2 +++ b/core/logic/HandleSys.cpp	Mon Aug 12 00:45:29 2013 +0100
     1.3 @@ -1027,6 +1027,63 @@
     1.4  	HANDLE_LOG_VERY_BAD("[SM] MEMORY LEAK DETECTED IN PLUGIN (file \"%s\")", highest_owner->GetFilename());
     1.5  	HANDLE_LOG_VERY_BAD("[SM] Unloading plugin to free %d handles.", highest_handle_count);
     1.6  	HANDLE_LOG_VERY_BAD("[SM] Contact the author(s) of this plugin to correct this error.", highest_handle_count);
     1.7 +	HANDLE_LOG_VERY_BAD("--------------------------------------------------------------------------");
     1.8 +
     1.9 +	const IdentityToken_t *pIdentity = highest_owner->GetIdentity();
    1.10 +	unsigned int total = 0, highest_index = 0, total_size = 0, size;
    1.11 +	unsigned int * pCount = new unsigned int[HANDLESYS_TYPEARRAY_SIZE+1];
    1.12 +	memset(pCount, 0, ((HANDLESYS_TYPEARRAY_SIZE + 1) * sizeof(unsigned int)));
    1.13 +
    1.14 +	for (unsigned int i = 1; i <= m_HandleTail; ++i)
    1.15 +	{
    1.16 +		const QHandle &Handle = m_Handles[i];
    1.17 +		if (Handle.set != HandleSet_Used || Handle.owner != pIdentity)
    1.18 +		{
    1.19 +			continue;
    1.20 +		}
    1.21 +
    1.22 +		++pCount[Handle.type];
    1.23 +		++total;
    1.24 +
    1.25 +		if (Handle.type >= highest_index)
    1.26 +		{
    1.27 +			highest_index = ((Handle.type) + 1);
    1.28 +		}
    1.29 +
    1.30 +		if (Handle.clone != 0)
    1.31 +		{
    1.32 +			continue;
    1.33 +		}
    1.34 +
    1.35 +		if (m_Types[Handle.type].dispatch->GetHandleApproxSize(Handle.type, Handle.object, &size))
    1.36 +		{
    1.37 +			total_size += size;
    1.38 +		}
    1.39 +	}
    1.40 +
    1.41 +	const char * pTypeName = NULL;
    1.42 +
    1.43 +	for (unsigned int i = 0; i < highest_index; ++i)
    1.44 +	{
    1.45 +		if (pCount[i] == 0)
    1.46 +		{
    1.47 +			continue; /* We may have gaps, it's fine. */
    1.48 +		}
    1.49 +
    1.50 +		if (m_Types[i].nameIdx != -1)
    1.51 +		{
    1.52 +			pTypeName = m_strtab->GetString(m_Types[i].nameIdx);
    1.53 +		}
    1.54 +		else
    1.55 +		{
    1.56 +			pTypeName = "ANON";
    1.57 +		}
    1.58 +
    1.59 +		HANDLE_LOG_VERY_BAD("Type\t%-20.20s|\tCount\t%u", pTypeName, pCount[i]);
    1.60 +	}
    1.61 +
    1.62 +	HANDLE_LOG_VERY_BAD("-- Approximately %d bytes of memory are in use by (%u) Handles.\n", total_size, total);
    1.63 +	delete [] pCount;
    1.64  
    1.65  	highest_owner->GetBaseContext()->ThrowNativeErrorEx(SP_ERROR_MEMACCESS, "Memory leak");
    1.66