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:
parent
a75e87a076
commit
165b8ed893
@ -66,14 +66,19 @@ BaseContext::BaseContext(sp_context_t *_ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseContext::FlushFunctionCache()
|
void BaseContext::FlushFunctionCache(bool remove)
|
||||||
{
|
{
|
||||||
if (m_pub_funcs)
|
if (m_pub_funcs)
|
||||||
{
|
{
|
||||||
for (uint32_t i=0; i<ctx->plugin->info.publics_num; i++)
|
for (uint32_t i=0; i<ctx->plugin->info.publics_num; i++)
|
||||||
{
|
{
|
||||||
delete m_pub_funcs[i];
|
if (remove)
|
||||||
m_pub_funcs[i] = NULL;
|
{
|
||||||
|
delete m_pub_funcs[i];
|
||||||
|
m_pub_funcs[i] = NULL;
|
||||||
|
} else if (m_pub_funcs[i]) {
|
||||||
|
m_pub_funcs[i]->Invalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,15 +86,20 @@ void BaseContext::FlushFunctionCache()
|
|||||||
{
|
{
|
||||||
for (unsigned int i=0; i<m_funcsnum; i++)
|
for (unsigned int i=0; i<m_funcsnum; i++)
|
||||||
{
|
{
|
||||||
delete m_priv_funcs[i];
|
if (remove)
|
||||||
m_priv_funcs[i] = NULL;
|
{
|
||||||
|
delete m_priv_funcs[i];
|
||||||
|
m_priv_funcs[i] = NULL;
|
||||||
|
} else if (m_priv_funcs[i]) {
|
||||||
|
m_priv_funcs[i]->Invalidate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseContext::~BaseContext()
|
BaseContext::~BaseContext()
|
||||||
{
|
{
|
||||||
FlushFunctionCache();
|
FlushFunctionCache(true);
|
||||||
delete [] m_pub_funcs;
|
delete [] m_pub_funcs;
|
||||||
m_pub_funcs = NULL;
|
m_pub_funcs = NULL;
|
||||||
delete [] m_priv_funcs;
|
delete [] m_priv_funcs;
|
||||||
@ -105,7 +115,7 @@ void BaseContext::SetContext(sp_context_t *_ctx)
|
|||||||
ctx = _ctx;
|
ctx = _ctx;
|
||||||
ctx->context = this;
|
ctx->context = this;
|
||||||
ctx->dbreak = GlobalDebugBreak;
|
ctx->dbreak = GlobalDebugBreak;
|
||||||
FlushFunctionCache();
|
FlushFunctionCache(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
IVirtualMachine *BaseContext::GetVirtualMachine()
|
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);
|
m_pub_funcs[func_id] = new CFunction(ctx->publics[func_id].code_offs, this);
|
||||||
pFunc = m_pub_funcs[func_id];
|
pFunc = m_pub_funcs[func_id];
|
||||||
|
} else if (pFunc->IsInvalidated()) {
|
||||||
|
pFunc->Set(ctx->publics[func_id].code_offs, this);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* :TODO: currently not used */
|
/* :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);
|
m_pub_funcs[index] = new CFunction(pub->code_offs, this);
|
||||||
}
|
}
|
||||||
pFunc = m_pub_funcs[index];
|
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;
|
return pFunc;
|
||||||
|
@ -79,7 +79,7 @@ namespace SourcePawn
|
|||||||
void SetContext(sp_context_t *_ctx);
|
void SetContext(sp_context_t *_ctx);
|
||||||
private:
|
private:
|
||||||
void SetErrorMessage(const char *msg, va_list ap);
|
void SetErrorMessage(const char *msg, va_list ap);
|
||||||
void FlushFunctionCache();
|
void FlushFunctionCache(bool remove);
|
||||||
private:
|
private:
|
||||||
sp_context_t *ctx;
|
sp_context_t *ctx;
|
||||||
#if defined SOURCEMOD_BUILD
|
#if defined SOURCEMOD_BUILD
|
||||||
|
@ -25,6 +25,7 @@ void CFunction::Set(uint32_t code_addr, IPluginContext *plugin)
|
|||||||
m_pContext = plugin;
|
m_pContext = plugin;
|
||||||
m_curparam = 0;
|
m_curparam = 0;
|
||||||
m_errorstate = SP_ERROR_NONE;
|
m_errorstate = SP_ERROR_NONE;
|
||||||
|
m_Invalid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CFunction::CallFunction(const cell_t *params, unsigned int num_params, cell_t *result)
|
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_codeaddr(code_addr), m_pContext(plugin), m_curparam(0),
|
||||||
m_errorstate(SP_ERROR_NONE)
|
m_errorstate(SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
|
m_Invalid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CFunction::PushCell(cell_t cell)
|
int CFunction::PushCell(cell_t cell)
|
||||||
|
@ -46,6 +46,14 @@ public:
|
|||||||
virtual void Cancel();
|
virtual void Cancel();
|
||||||
virtual int CallFunction(const cell_t *params, unsigned int num_params, cell_t *result);
|
virtual int CallFunction(const cell_t *params, unsigned int num_params, cell_t *result);
|
||||||
virtual IPluginContext *GetParentContext();
|
virtual IPluginContext *GetParentContext();
|
||||||
|
inline bool IsInvalidated()
|
||||||
|
{
|
||||||
|
return m_Invalid;
|
||||||
|
}
|
||||||
|
inline void Invalidate()
|
||||||
|
{
|
||||||
|
m_Invalid = true;
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
void Set(uint32_t code_addr, IPluginContext *plugin);
|
void Set(uint32_t code_addr, IPluginContext *plugin);
|
||||||
private:
|
private:
|
||||||
@ -63,6 +71,7 @@ private:
|
|||||||
unsigned int m_curparam;
|
unsigned int m_curparam;
|
||||||
int m_errorstate;
|
int m_errorstate;
|
||||||
CFunction *m_pNext;
|
CFunction *m_pNext;
|
||||||
|
bool m_Invalid;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEMOD_BASEFUNCTION_H_
|
#endif //_INCLUDE_SOURCEMOD_BASEFUNCTION_H_
|
||||||
|
Loading…
Reference in New Issue
Block a user