Skip to content

CommandIterator crashing SRCDS - [SM] Exception reported: Could not read Handle xxxxx (error 4)  #1387

@iNilo

Description

@iNilo

Environment

  • Operating System version: Linux version 5.4.65-1-pve (build@pve) (gcc version 8.3.0 (Debian 8.3.0-6)) SMP PVE 5.4.65-1 (Mon, 21 Sep 2020 15:40:22 +0200)
  • Game/AppID (with version if applicable): CS:GO 730 Protocol version 13770
  • Current SourceMod version: SourceMod 1.11.0.6497
  • Current Metamod: Source snapshot: Metamod:Source version 1.11.0-dev+1130
  • Compiled on SourcePawn Compiler 1.10.0.6458 (Windows)

Description

Might be related to #819
#819 (comment)

Not sure where and how, but:

2 or more plugins register the same command with RegAdminCmd

Plugin1 -> RegAdminCmd("sm_babyyoda"...
Plugin2 -> RegAdminCmd("sm_babyyoda"...

AND

Plugin 2 CmdIter's upon its own load (https://sm.alliedmods.net/new-api/console/CommandIterator)
Plugin2 -> OnPluginStart -> CommandIterator

If you reload plugin 1.
Then reload plugin 2

Srcds goes poof

Problematic Code (or Steps to Reproduce)

Compile these:

babyyoda.inc

/** Double-include prevention */
#if defined _mando_included_
  #endinput
#endif
#define _mando_included_


stock GreenThing()
{
	RegAdminCmd("sm_babyyoda", Command_BabyYoda, ADMFLAG_GENERIC, "sm_babyyoda - checks if Mando is still there");
}

public Action Command_BabyYoda(int client,int args)
{
	char cName[512];
	GetPluginInfo(GetMyHandle(), PlInfo_Name, cName, sizeof(cName));
	ReplyToCommand(client, " I'm [%s]", cName);
	ReplyToCommand(client, " [T]");
	ReplyToCommand(client, " | |√  <••>");
	ReplyToCommand(client, " ( )   (  )");
	return Plugin_Handled;
}

Plugin1.sp

#include <sourcemod>
#include <babyyoda>

#pragma semicolon 1
#pragma newdecls required

public Plugin myinfo =
{
    name        = "Plugin1",
    author      = "",
    description = "",
    version     = "0.0.0",
    url         = ""
};

public void OnPluginStart()
{
	GreenThing();
}

PluginDumper.sp

#include <sourcemod>
#include <babyyoda>

#pragma semicolon 1
#pragma newdecls required

public Plugin myinfo =
{
    name        = "PluginDumper",
    author      = "",
    description = "",
    version     = "0.0.0",
    url         = ""
};

public void OnPluginStart()
{
	LoopCommands();
	GreenThing();
	LoopCommands();
	RegAdminCmd("sm_dumpcommands", Command_DumpCommands, ADMFLAG_GENERIC, "sm_dumpcommands - dump the commands");
}


public Action Command_DumpCommands(int client, int args)
{
	LoopCommands();
	return Plugin_Handled;
}

public void OnConfigsExecuted()
{
	LoopCommands();
}

public void LoopCommands()
{
	char cName[128];
	char Desc[255];
	char cDesc[512];
	int Flags;
	CommandIterator CmdIter = new CommandIterator();
	while (CmdIter.Next())
	{
		CmdIter.GetName(cName, sizeof(cName));
		CmdIter.GetDescription(cDesc, sizeof(cDesc));
		Flags = CmdIter.Flags;

		Handle plugin = CmdIter.Plugin;
		//plugin stuff.
		char cPluginFilename[128];
		GetPluginFilename(plugin, cPluginFilename, sizeof(cPluginFilename));

		char GetPluginInfo_PlInfo_Name[128];
		char GetPluginInfo_PlInfo_Author[128];
		char GetPluginInfo_PlInfo_Description[128];
		char GetPluginInfo_PlInfo_Version[128];
		char GetPluginInfo_PlInfo_URL[128];
		GetPluginInfo(plugin, PlInfo_Name, GetPluginInfo_PlInfo_Name, sizeof(GetPluginInfo_PlInfo_Name));
		GetPluginInfo(plugin, PlInfo_Author, GetPluginInfo_PlInfo_Author, sizeof(GetPluginInfo_PlInfo_Author));
		GetPluginInfo(plugin, PlInfo_Description, GetPluginInfo_PlInfo_Description, sizeof(GetPluginInfo_PlInfo_Description));
		GetPluginInfo(plugin, PlInfo_Version, GetPluginInfo_PlInfo_Version, sizeof(GetPluginInfo_PlInfo_Version));
		GetPluginInfo(plugin, PlInfo_URL, GetPluginInfo_PlInfo_URL, sizeof(GetPluginInfo_PlInfo_URL));

		if(StrContains(cName, "yoda", false) == -1)
			continue;

		PrintToServer(" -----> name[%s] desc[%s] flags[%i] filename[%s] name[%s]",  cName, cDesc, Flags, cPluginFilename, GetPluginInfo_PlInfo_Name);
		PrintToConsoleAll(" -----> name[%s] desc[%s] flags[%i] filename[%s] name[%s]",  cName, cDesc, Flags, cPluginFilename, GetPluginInfo_PlInfo_Name);
	}
	delete CmdIter;
}

Now:

sm plugins load Plugin1
sm plugins load PluginDumper
sm plugins reload Plugin1
sm plugins reload PluginDumper

if it doesn't crash, just keep reloading things at random, should crash sooner or later

It should do:
[SM] Exception reported: Could not read Handle xxxxx (error 4)

Stack trace a bit, and poof 🍃

Logs

image
image

https://crash.limetech.org/M75HEZJ4WVTW
https://crash.limetech.org/TDNU6E6CS3I6
https://crash.limetech.org/EXDJMDYLHWFG
https://crash.limetech.org/IRUOHPCJ3XG4
https://crash.limetech.org/QOIU44MMRTZY

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions