fixed a serious potential bug with swapping plugins to debug mode, leaving stale function pointers without plugin removal

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40508
This commit is contained in:
David Anderson 2007-02-16 04:16:31 +00:00
parent a75e87a076
commit 165b8ed893
4 changed files with 40 additions and 8 deletions

View File

@ -66,30 +66,40 @@ BaseContext::BaseContext(sp_context_t *_ctx)
}
}
void BaseContext::FlushFunctionCache()
void BaseContext::FlushFunctionCache(bool remove)
{
if (m_pub_funcs)
{
for (uint32_t i=0; i<ctx->plugin->info.publics_num; i++)
{
if (remove)
{
delete m_pub_funcs[i];
m_pub_funcs[i] = NULL;
} else if (m_pub_funcs[i]) {
m_pub_funcs[i]->Invalidate();
}
}
}
if (m_priv_funcs)
{
for (unsigned int i=0; i<m_funcsnum; i++)
{
if (remove)
{
delete m_priv_funcs[i];
m_priv_funcs[i] = NULL;
} else if (m_priv_funcs[i]) {
m_priv_funcs[i]->Invalidate();
}
}
}
}
BaseContext::~BaseContext()
{
FlushFunctionCache();
FlushFunctionCache(true);
delete [] m_pub_funcs;
m_pub_funcs = NULL;
delete [] m_priv_funcs;
@ -105,7 +115,7 @@ void BaseContext::SetContext(sp_context_t *_ctx)
ctx = _ctx;
ctx->context = this;
ctx->dbreak = GlobalDebugBreak;
FlushFunctionCache();
FlushFunctionCache(false);
}
IVirtualMachine *BaseContext::GetVirtualMachine()
@ -850,6 +860,8 @@ IPluginFunction *BaseContext::GetFunctionById(funcid_t func_id)
{
m_pub_funcs[func_id] = new CFunction(ctx->publics[func_id].code_offs, this);
pFunc = m_pub_funcs[func_id];
} else if (pFunc->IsInvalidated()) {
pFunc->Set(ctx->publics[func_id].code_offs, this);
}
} else {
/* :TODO: currently not used */
@ -892,6 +904,15 @@ IPluginFunction *BaseContext::GetFunctionByName(const char *public_name)
m_pub_funcs[index] = new CFunction(pub->code_offs, this);
}
pFunc = m_pub_funcs[index];
} else if (pFunc->IsInvalidated()) {
sp_public_t *pub = NULL;
GetPublicByIndex(index, &pub);
if (pub)
{
pFunc->Set(pub->code_offs, this);
} else {
pFunc = NULL;
}
}
return pFunc;

View File

@ -79,7 +79,7 @@ namespace SourcePawn
void SetContext(sp_context_t *_ctx);
private:
void SetErrorMessage(const char *msg, va_list ap);
void FlushFunctionCache();
void FlushFunctionCache(bool remove);
private:
sp_context_t *ctx;
#if defined SOURCEMOD_BUILD

View File

@ -25,6 +25,7 @@ void CFunction::Set(uint32_t code_addr, IPluginContext *plugin)
m_pContext = plugin;
m_curparam = 0;
m_errorstate = SP_ERROR_NONE;
m_Invalid = false;
}
int CFunction::CallFunction(const cell_t *params, unsigned int num_params, cell_t *result)
@ -46,6 +47,7 @@ CFunction::CFunction(uint32_t code_addr, IPluginContext *plugin) :
m_codeaddr(code_addr), m_pContext(plugin), m_curparam(0),
m_errorstate(SP_ERROR_NONE)
{
m_Invalid = false;
}
int CFunction::PushCell(cell_t cell)

View File

@ -46,6 +46,14 @@ public:
virtual void Cancel();
virtual int CallFunction(const cell_t *params, unsigned int num_params, cell_t *result);
virtual IPluginContext *GetParentContext();
inline bool IsInvalidated()
{
return m_Invalid;
}
inline void Invalidate()
{
m_Invalid = true;
}
public:
void Set(uint32_t code_addr, IPluginContext *plugin);
private:
@ -63,6 +71,7 @@ private:
unsigned int m_curparam;
int m_errorstate;
CFunction *m_pNext;
bool m_Invalid;
};
#endif //_INCLUDE_SOURCEMOD_BASEFUNCTION_H_