Esempio n. 1
0
bool HandleSystem::TryAndFreeSomeHandles()
{
    IPluginIterator *pl_iter = g_PluginSys.GetPluginIterator();
    IPlugin *highest_owner = NULL;
    unsigned int highest_handle_count = 0;

    /* Search all plugins */
    while (pl_iter->MorePlugins())
    {
        IPlugin *plugin = pl_iter->GetPlugin();
        IdentityToken_t *identity = plugin->GetIdentity();
        unsigned int handle_count = 0;

        if (identity == NULL)
        {
            continue;
        }

        /* Search all handles */
        for (unsigned int i = 1; i <= m_HandleTail; i++)
        {
            if (m_Handles[i].set != HandleSet_Used)
            {
                continue;
            }
            if (m_Handles[i].owner == identity)
            {
                handle_count++;
            }
        }

        if (handle_count > highest_handle_count)
        {
            highest_owner = plugin;
            highest_handle_count = handle_count;
        }

        pl_iter->NextPlugin();
    }

    if (highest_owner == NULL || highest_handle_count == 0)
    {
        return false;
    }

    g_Logger.LogFatal("[SM] MEMORY LEAK DETECTED IN PLUGIN (file \"%s\")", highest_owner->GetFilename());
    g_Logger.LogFatal("[SM] Unloading plugin to free %d handles.", highest_handle_count);
    g_Logger.LogFatal("[SM] Contact the author(s) of this plugin to correct this error.", highest_handle_count);

    highest_owner->GetBaseContext()->ThrowNativeErrorEx(SP_ERROR_MEMACCESS, "Memory leak");

    return g_PluginSys.UnloadPlugin(highest_owner);
}
Esempio n. 2
0
static void PawnFrameAction(void *pData)
{
	ke::AutoPtr<SMFrameActionData> frame(reinterpret_cast<SMFrameActionData *>(pData));
	IPlugin *pPlugin = pluginsys->PluginFromHandle(frame->ownerhandle, NULL);
	if (!pPlugin)
	{
		return;
	}

	IChangeableForward *pForward;
	HandleSecurity sec(pPlugin->GetIdentity(), g_pCoreIdent);
	if (handlesys->ReadHandle(frame->handle, g_PrivateFwdType, &sec, (void **)&pForward) != HandleError_None)
	{
		return;
	}

	pForward->PushCell(frame->data);
	pForward->Execute(NULL);

	handlesys->FreeHandle(frame->handle, &sec);
}
Esempio n. 3
0
bool HandleSystem::TryAndFreeSomeHandles()
{
	IPlugin *highest_owner = NULL;
	unsigned int highest_handle_count = 0;

	/* Search all plugins */
	for (IPluginIterator *pl_iter = g_PluginSys.GetPluginIterator(); pl_iter->MorePlugins(); pl_iter->NextPlugin())
	{
		IPlugin *plugin = pl_iter->GetPlugin();
		IdentityToken_t *identity = plugin->GetIdentity();
		unsigned int handle_count = 0;

		if (identity == NULL)
		{
			continue;
		}

		/* Search all handles */
		for (unsigned int i = 1; i <= m_HandleTail; i++)
		{
			if (m_Handles[i].set != HandleSet_Used)
			{
				continue;
			}
			if (m_Handles[i].owner == identity)
			{
				handle_count++;
			}
		}

		if (handle_count > highest_handle_count)
		{
			highest_owner = plugin;
			highest_handle_count = handle_count;
		}
	}

	if (highest_owner == NULL || highest_handle_count == 0)
	{
		return false;
	}

	HANDLE_LOG_VERY_BAD("[SM] MEMORY LEAK DETECTED IN PLUGIN (file \"%s\")", highest_owner->GetFilename());
	HANDLE_LOG_VERY_BAD("[SM] Unloading plugin to free %d handles.", highest_handle_count);
	HANDLE_LOG_VERY_BAD("[SM] Contact the author(s) of this plugin to correct this error.", highest_handle_count);
	HANDLE_LOG_VERY_BAD("--------------------------------------------------------------------------");

	const IdentityToken_t *pIdentity = highest_owner->GetIdentity();
	unsigned int total = 0, highest_index = 0, total_size = 0, size;
	unsigned int * pCount = new unsigned int[HANDLESYS_TYPEARRAY_SIZE+1];
	memset(pCount, 0, ((HANDLESYS_TYPEARRAY_SIZE + 1) * sizeof(unsigned int)));

	for (unsigned int i = 1; i <= m_HandleTail; ++i)
	{
		const QHandle &Handle = m_Handles[i];
		if (Handle.set != HandleSet_Used || Handle.owner != pIdentity)
		{
			continue;
		}

		++pCount[Handle.type];
		++total;

		if (Handle.type >= highest_index)
		{
			highest_index = ((Handle.type) + 1);
		}

		if (Handle.clone != 0)
		{
			continue;
		}

		if (m_Types[Handle.type].dispatch->GetHandleApproxSize(Handle.type, Handle.object, &size))
		{
			total_size += size;
		}
	}

	const char * pTypeName = NULL;

	for (unsigned int i = 0; i < highest_index; ++i)
	{
		if (pCount[i] == 0)
		{
			continue; /* We may have gaps, it's fine. */
		}

		if (m_Types[i].name)
			pTypeName = m_Types[i].name->chars();
		else
			pTypeName = "ANON";

		HANDLE_LOG_VERY_BAD("Type\t%-20.20s|\tCount\t%u", pTypeName, pCount[i]);
	}

	HANDLE_LOG_VERY_BAD("-- Approximately %d bytes of memory are in use by (%u) Handles.\n", total_size, total);
	delete [] pCount;

	highest_owner->GetBaseContext()->ThrowNativeErrorEx(SP_ERROR_MEMACCESS, "Memory leak");

	return scripts->UnloadPlugin(highest_owner);
}