SourceMod will now spit out errors for scripts that become corrupt and would otherwise be crashing Core. if you get these errors contact the dev team.

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401345
This commit is contained in:
David Anderson
2007-08-15 20:18:15 +00:00
parent 290f90a3a3
commit da0a160371
6 changed files with 103 additions and 32 deletions
+31 -16
View File
@@ -39,6 +39,7 @@
#ifdef SOURCEMOD_BUILD
#include "Logger.h"
#include "DebugReporter.h"
#endif
using namespace SourcePawn;
@@ -149,7 +150,7 @@ void BaseContext::RefreshFunctionCache()
{
continue;
}
m_pub_funcs[i]->Set(pub->code_offs, this);
m_pub_funcs[i]->Set(pub->code_offs, this, pub->funcid);
}
}
@@ -221,6 +222,10 @@ int BaseContext::SetDebugBreak(SPVM_DEBUGBREAK newpfn, SPVM_DEBUGBREAK *oldpfn)
IPluginDebugInfo *BaseContext::GetDebugInfo()
{
if (!IsDebugging())
{
return NULL;
}
return this;
}
@@ -243,7 +248,13 @@ int BaseContext::Execute(uint32_t code_addr, cell_t *result)
uint32_t pushcount = ctx->pushcount;
int err;
PushCell(pushcount++);
if ((err = PushCell(pushcount++)) != SP_ERROR_NONE)
{
#if defined SOURCEMOD_BUILD
g_DbgReporter.GenerateCodeError(this, code_addr, err, "Stack error; cannot complete execution!");
#endif
return SP_ERROR_NOT_RUNNABLE;
}
ctx->pushcount = 0;
cell_t save_sp = ctx->sp;
@@ -271,26 +282,30 @@ int BaseContext::Execute(uint32_t code_addr, cell_t *result)
*/
g_SourcePawn.PopTracer(err, m_CustomMsg ? m_MsgCache : NULL);
#if 1//defined _DEBUG
//:TODO: debug code for leak detection, remove before the release?
#if defined SOURCEMOD_BUILD
if (err == SP_ERROR_NONE)
{
if ((ctx->sp - (cell_t)(pushcount * sizeof(cell_t))) != save_sp)
{
const char *name;
ctx->context->GetDebugInfo()->LookupFunction(code_addr, &name);
g_Logger.LogError("Stack leak detected: sp:%d should be %d on function %s", ctx->sp, save_sp, name);
g_DbgReporter.GenerateCodeError(this,
code_addr,
SP_ERROR_STACKLEAK,
"Stack leak detected: sp:%d should be %d!",
ctx->sp,
save_sp);
}
if (ctx->hp != save_hp)
{
const char *name;
ctx->context->GetDebugInfo()->LookupFunction(code_addr, &name);
g_Logger.LogError("Heap leak detected: hp:%d should be %d on function %s", ctx->hp, save_hp, name);
g_DbgReporter.GenerateCodeError(this,
code_addr,
SP_ERROR_HEAPLEAK,
"Heap leak detected: sp:%d should be %d!",
ctx->hp,
save_hp);
}
//assert(ctx->sp - pushcount * sizeof(cell_t) == save_sp);
//assert(ctx->hp == save_hp);
}
#endif
if (err != SP_ERROR_NONE)
{
ctx->sp = save_sp;
@@ -958,10 +973,10 @@ IPluginFunction *BaseContext::GetFunctionById(funcid_t func_id)
pFunc = m_pub_funcs[func_id];
if (!pFunc)
{
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, ctx->publics[func_id].funcid);
pFunc = m_pub_funcs[func_id];
} else if (pFunc->IsInvalidated()) {
pFunc->Set(ctx->publics[func_id].code_offs, this);
pFunc->Set(ctx->publics[func_id].code_offs, this, ctx->publics[func_id].funcid);
}
} else {
/* :TODO: currently not used */
@@ -1001,7 +1016,7 @@ IPluginFunction *BaseContext::GetFunctionByName(const char *public_name)
GetPublicByIndex(index, &pub);
if (pub)
{
m_pub_funcs[index] = new CFunction(pub->code_offs, this);
m_pub_funcs[index] = new CFunction(pub->code_offs, this, pub->funcid);
}
pFunc = m_pub_funcs[index];
} else if (pFunc->IsInvalidated()) {
@@ -1009,7 +1024,7 @@ IPluginFunction *BaseContext::GetFunctionByName(const char *public_name)
GetPublicByIndex(index, &pub);
if (pub)
{
pFunc->Set(pub->code_offs, this);
pFunc->Set(pub->code_offs, this, pub->funcid);
} else {
pFunc = NULL;
}
+9 -3
View File
@@ -37,7 +37,7 @@
* FUNCTION CALLING *
********************/
void CFunction::Set(uint32_t code_addr, IPluginContext *plugin)
void CFunction::Set(uint32_t code_addr, IPluginContext *plugin, funcid_t id)
{
m_codeaddr = code_addr;
m_pContext = plugin;
@@ -45,6 +45,7 @@ void CFunction::Set(uint32_t code_addr, IPluginContext *plugin)
m_errorstate = SP_ERROR_NONE;
m_Invalid = false;
m_pCtx = plugin ? plugin->GetContext() : NULL;
m_FnId = id;
}
bool CFunction::IsRunnable()
@@ -72,9 +73,9 @@ IPluginContext *CFunction::GetParentContext()
return m_pContext;
}
CFunction::CFunction(uint32_t code_addr, IPluginContext *plugin) :
CFunction::CFunction(uint32_t code_addr, IPluginContext *plugin, funcid_t id) :
m_codeaddr(code_addr), m_pContext(plugin), m_curparam(0),
m_errorstate(SP_ERROR_NONE)
m_errorstate(SP_ERROR_NONE), m_FnId(id)
{
m_Invalid = false;
if (plugin)
@@ -313,3 +314,8 @@ int CFunction::Execute(cell_t *result)
return err;
}
funcid_t CFunction::GetFunctionID()
{
return m_FnId;
}
+4 -2
View File
@@ -55,7 +55,7 @@ class CFunction : public IPluginFunction
{
friend class SourcePawnEngine;
public:
CFunction(uint32_t code_addr, IPluginContext *pContext);
CFunction(uint32_t code_addr, IPluginContext *pContext, funcid_t fnid);
public:
virtual int PushCell(cell_t cell);
virtual int PushCellByRef(cell_t *cell, int flags);
@@ -77,8 +77,9 @@ public:
m_Invalid = true;
}
bool IsRunnable();
funcid_t GetFunctionID();
public:
void Set(uint32_t code_addr, IPluginContext *plugin);
void Set(uint32_t code_addr, IPluginContext *plugin, funcid_t fnid);
private:
int _PushString(const char *string, int sz_flags, int cp_flags, size_t len);
inline int SetError(int err)
@@ -96,6 +97,7 @@ private:
int m_errorstate;
CFunction *m_pNext;
bool m_Invalid;
funcid_t m_FnId;
};
#endif //_INCLUDE_SOURCEMOD_BASEFUNCTION_H_