I'm not sure how to explain my issues, but here it goes. I'm with
SourceMod and am trying to create a system to create ConVars
dynamically through the use of external plugin DLLs. In the external
plugin DLL I call a function in the main server plugin DLL in order to
create a ConVar. And this works well and fine. However, these external
DLLs are unloadable and so when I attempt to unload one of these
external plugins, srcds will crash.
Here is the code that I _was_ using which is the main server plugin DLL:
void CCvarManager::RegisterCvar(const char *name, const char
*defaultValue, int flags)
{
new ConVar(name, defaultValue, flags);
}
The external plugins can call that in order to create a convar.
Calling it doesn't cause a crash, it's the unloading of the external
plugins that does.
After doing a lot of testing and experimenting, I finally figured out
that the first param of the ConVar constuctor was what was causing a
problem.
So I changed my code to this:
void CCvarManager::RegisterCvar(const char *name, const char
*defaultValue, int flags)
{
char *cvarName = new char[strlen(name) + 1];
memcpy(cvarName, name, strlen(name) + 1);
new ConVar(cvarName, defaultValue, flags);
}
And it stopped crashing when I unloaded the external DLL.
Then, I later found out there was another problem. If I were to type
the name of the cvar I had created AFTER unloading the external
plugin, srcds would crash again. I solved that problem very similarly
with:
void CCvarManager::RegisterCvar(const char *name, const char
*defaultValue, int flags)
{
char *cvarName = new char[strlen(name) + 1];
memcpy(cvarName, name, strlen(name) + 1);
char *def = new char[strlen(defaultValue) + 1];
memcpy(def, defaultValue, strlen(defaultValue) + 1);
new ConVar(cvarName, def, flags);
}
So after using the code, I have no more problems. I have a theory as
to why the crashes were happening though. The const char* vars that
were passed to the main server plugin DLL were actually allocated in
the external plugin. So when I unloaded the external plugin, those
const char pointers along with the rest of the memory held by the
external plugin disappeared. And because the server/engine still
needed those pointers, it crashed.
But I also had noticed that if I created a ConVar in the main server
plugin DLL and unload that via plugin_unload, there were no such
crashing issues. I think I know the reason for this. When
plugin_unload is used, FreeLibrary (Windows) is not called on the
server plugin, so it's memory is still accessible. FreeLibrary/dlclose
isn't actually called until srcds is shutdown. When I unload one of
the external plugins I have, I do call FreeLibrary/dlclose on it.
So either FreeLibrary/dlclose should be called on the external plugins
when the main server plugin unloads or I can just keep using memcpy as
I have shown. I don't exactly like either "solution", especially not
using FreeLibrary/dlcose on external plugin unload because these
external plugins could be loaded again later. Alternatively, is there
a way to allocate memory independent of either the main server plugin
DLL or the external plugins? Ideally, I would like to just
"unregister" the cvar when the external plugin gets unloaded. But I
guess this isn't much of a question then. But am I going about this
the correct way? Has anyone else come across a similar issue?
_______________________________________________
To unsubscribe, edit your list preferences, or view the list archives, please
visit:
http://list.valvesoftware.com/mailman/listinfo/hlcoders