mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-26 23:05:37 +03:00
Added set_error_filter()
This commit is contained in:
parent
de65e65854
commit
0dc2ba85e8
@ -830,6 +830,27 @@ const char *Debugger::_GetFilename()
|
|||||||
return m_FileName.c_str();
|
return m_FileName.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Debugger::GenericMessage(AMX *amx, int err)
|
||||||
|
{
|
||||||
|
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
|
||||||
|
const char *filename = "";
|
||||||
|
|
||||||
|
CList<CScript,AMX*>::iterator a = g_loadedscripts.find(amx);
|
||||||
|
if (a)
|
||||||
|
filename = (*a).getName();
|
||||||
|
size_t len = strlen(filename);
|
||||||
|
for (size_t i=len-1; i>=0; i--)
|
||||||
|
{
|
||||||
|
if (filename[i] == '/' || filename[i] == '\\' && i != len - 1)
|
||||||
|
{
|
||||||
|
filename = &(filename[i+1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AMXXLOG_Log("[AMXX] Run time error %d (plugin \"%s\") - debug not enabled!", err, filename);
|
||||||
|
}
|
||||||
|
|
||||||
Debugger::~Debugger()
|
Debugger::~Debugger()
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
@ -871,7 +892,98 @@ int Handler::SetNativeFilter(const char *function)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Handler::SetErrorMsg(const char *msg)
|
||||||
|
{
|
||||||
|
if (!msg)
|
||||||
|
m_MsgCache.clear();
|
||||||
|
else
|
||||||
|
m_MsgCache.assign(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *Handler::GetLastMsg()
|
||||||
|
{
|
||||||
|
if (m_MsgCache.size() < 1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return m_MsgCache.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
int Handler::HandleError(const char *msg)
|
int Handler::HandleError(const char *msg)
|
||||||
{
|
{
|
||||||
|
if (m_iErrFunc <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
m_Handling = true;
|
||||||
|
|
||||||
|
Debugger *pDebugger = (Debugger *)m_pAmx->userdata[UD_DEBUGGER];
|
||||||
|
|
||||||
|
int error = m_pAmx->error;
|
||||||
|
|
||||||
|
if (pDebugger)
|
||||||
|
pDebugger->BeginExec();
|
||||||
|
|
||||||
|
SetErrorMsg(msg);
|
||||||
|
|
||||||
|
cell hea_addr, *phys_addr, result;
|
||||||
|
|
||||||
|
amx_PushString(m_pAmx, &hea_addr, &phys_addr, msg, 0, 0);
|
||||||
|
amx_Push(m_pAmx, pDebugger ? 1 : 0);
|
||||||
|
amx_Push(m_pAmx, error);
|
||||||
|
int err = amx_Exec(m_pAmx, &result, m_iErrFunc);
|
||||||
|
if (err != AMX_ERR_NONE)
|
||||||
|
{
|
||||||
|
//handle this manually.
|
||||||
|
if (pDebugger)
|
||||||
|
{
|
||||||
|
pDebugger->SetTracedError(err);
|
||||||
|
pDebugger->DisplayTrace(msg);
|
||||||
|
} else {
|
||||||
|
if (GetLastMsg())
|
||||||
|
AMXXLOG_Log("%s", GetLastMsg());
|
||||||
|
Debugger::GenericMessage(m_pAmx, err);
|
||||||
|
}
|
||||||
|
AMXXLOG_Log("[AMXX] NOTE: Runtime failures in an error filter are not good!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDebugger)
|
||||||
|
pDebugger->EndExec();
|
||||||
|
|
||||||
|
amx_Release(m_pAmx, hea_addr);
|
||||||
|
|
||||||
|
m_Handling = false;
|
||||||
|
|
||||||
|
if (err != AMX_ERR_NONE || !result)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cell AMX_NATIVE_CALL set_error_filter(AMX *amx, cell *params)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
char *function = get_amxstring(amx, params[1], 0, len);
|
||||||
|
|
||||||
|
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
|
||||||
|
|
||||||
|
if (!pHandler)
|
||||||
|
{
|
||||||
|
Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND);
|
||||||
|
AMXXLOG_Log("[AMXX] Plugin not initialized correctly.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int err = pHandler->SetErrorHandler(function);
|
||||||
|
if (err != AMX_ERR_NONE)
|
||||||
|
{
|
||||||
|
Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND);
|
||||||
|
AMXXLOG_Log("[AMXX] Function not found: %s", function);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AMX_NATIVE_INFO g_DebugNatives[] = {
|
||||||
|
{"set_error_filter", set_error_filter},
|
||||||
|
{NULL, NULL},
|
||||||
|
};
|
||||||
|
@ -123,6 +123,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
//generic static opcode breaker
|
//generic static opcode breaker
|
||||||
static int AMXAPI DebugHook(AMX *amx);
|
static int AMXAPI DebugHook(AMX *amx);
|
||||||
|
static void GenericMessage(AMX *amx, int error);
|
||||||
private:
|
private:
|
||||||
void _CacheAmxOpcodeList();
|
void _CacheAmxOpcodeList();
|
||||||
int _GetOpcodeFromCip(cell cip, cell *&addr);
|
int _GetOpcodeFromCip(cell cip, cell *&addr);
|
||||||
@ -147,7 +148,8 @@ class Handler
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Handler(AMX *pAmx) : m_pAmx(pAmx),
|
Handler(AMX *pAmx) : m_pAmx(pAmx),
|
||||||
m_iErrFunc(-1), m_iModFunc(-1), m_iNatFunc(-1)
|
m_iErrFunc(-1), m_iModFunc(-1), m_iNatFunc(-1),
|
||||||
|
m_Handling(false)
|
||||||
{ };
|
{ };
|
||||||
~Handler() { };
|
~Handler() { };
|
||||||
public:
|
public:
|
||||||
@ -158,11 +160,19 @@ public:
|
|||||||
int HandleError(const char *msg);
|
int HandleError(const char *msg);
|
||||||
int HandleNative(const char *native);
|
int HandleNative(const char *native);
|
||||||
int HandleModule(const char *module);
|
int HandleModule(const char *module);
|
||||||
|
public:
|
||||||
|
bool IsHandling() const { return m_Handling; }
|
||||||
|
void SetErrorMsg(const char *msg);
|
||||||
|
const char *GetLastMsg();
|
||||||
public:
|
public:
|
||||||
AMX *m_pAmx;
|
AMX *m_pAmx;
|
||||||
int m_iErrFunc;
|
int m_iErrFunc;
|
||||||
int m_iModFunc;
|
int m_iModFunc;
|
||||||
int m_iNatFunc;
|
int m_iNatFunc;
|
||||||
|
bool m_Handling;
|
||||||
|
String m_MsgCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern AMX_NATIVE_INFO g_DebugNatives[];
|
||||||
|
|
||||||
#endif //_INCLUDE_DEBUGGER_H_
|
#endif //_INCLUDE_DEBUGGER_H_
|
||||||
|
@ -209,6 +209,9 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
|||||||
return (amx->error = AMX_ERR_INIT);
|
return (amx->error = AMX_ERR_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handler *pHandler = new Handler(amx);
|
||||||
|
amx->userdata[UD_HANDLER] = (void *)pHandler;
|
||||||
|
|
||||||
if (will_be_debugged)
|
if (will_be_debugged)
|
||||||
{
|
{
|
||||||
amx->flags |= AMX_FLAG_DEBUG;
|
amx->flags |= AMX_FLAG_DEBUG;
|
||||||
@ -409,17 +412,19 @@ int set_amxnatives(AMX* amx,char error[128])
|
|||||||
amx_Register(amx, vault_Natives, -1);
|
amx_Register(amx, vault_Natives, -1);
|
||||||
amx_Register(amx, g_NewMenuNatives, -1);
|
amx_Register(amx, g_NewMenuNatives, -1);
|
||||||
amx_Register(amx, g_NativeNatives, -1);
|
amx_Register(amx, g_NativeNatives, -1);
|
||||||
|
amx_Register(amx, g_DebugNatives, -1);
|
||||||
|
|
||||||
//we're not actually gonna check these here anymore
|
//we're not actually gonna check these here anymore
|
||||||
amx->flags |= AMX_FLAG_PRENIT;
|
amx->flags |= AMX_FLAG_PRENIT;
|
||||||
|
|
||||||
int idx;
|
int idx, err;
|
||||||
cell retval;
|
cell retval;
|
||||||
if (amx_FindPublic(amx, "plugin_natives", &idx)==AMX_ERR_NONE)
|
if (amx_FindPublic(amx, "plugin_natives", &idx)==AMX_ERR_NONE)
|
||||||
{
|
{
|
||||||
if (amx_Exec(amx, &retval, idx)!=AMX_ERR_NONE)
|
if ( (err=amx_Exec(amx, &retval, idx))!=AMX_ERR_NONE )
|
||||||
{
|
{
|
||||||
//someday clear libraries that this added
|
Debugger::GenericMessage(amx, err);
|
||||||
|
AMXXLOG_Log("An error occurred in plugins_native. This is dangerous!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,6 +439,9 @@ int unload_amxscript(AMX* amx, void** program)
|
|||||||
Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
|
Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
|
||||||
if (pDebugger)
|
if (pDebugger)
|
||||||
delete pDebugger;
|
delete pDebugger;
|
||||||
|
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
|
||||||
|
if (pHandler)
|
||||||
|
delete pHandler;
|
||||||
CList<CScript,AMX*>::iterator a = g_loadedscripts.find( amx );
|
CList<CScript,AMX*>::iterator a = g_loadedscripts.find( amx );
|
||||||
if ( a ) a.remove();
|
if ( a ) a.remove();
|
||||||
char *prg = (char *)*program;
|
char *prg = (char *)*program;
|
||||||
@ -1256,11 +1264,6 @@ float MNF_GetPlayerHealth(int id)
|
|||||||
return (GET_PLAYER_POINTER_I(id)->pEdict->v.health);
|
return (GET_PLAYER_POINTER_I(id)->pEdict->v.health);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MNF_HiddenStuff()
|
|
||||||
{
|
|
||||||
// :TODO:
|
|
||||||
}
|
|
||||||
|
|
||||||
cell MNF_RealToCell(REAL x)
|
cell MNF_RealToCell(REAL x)
|
||||||
{
|
{
|
||||||
return *(cell*)&x;
|
return *(cell*)&x;
|
||||||
@ -1305,36 +1308,34 @@ void LogError(AMX *amx, int err, const char *fmt, ...)
|
|||||||
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
|
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
|
||||||
if (pHandler)
|
if (pHandler)
|
||||||
{
|
{
|
||||||
//give the user a first-chance at blocking the error from displaying
|
if (pHandler->IsHandling())
|
||||||
if (pHandler->HandleError(msg_buffer) != 0)
|
{
|
||||||
|
if (fmt != NULL)
|
||||||
|
pHandler->SetErrorMsg(msg_buffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//give the user a first-chance at blocking the error from displaying
|
||||||
|
if (pHandler->HandleError(fmt ? msg_buffer : NULL) != 0)
|
||||||
|
{
|
||||||
|
amx->error = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!pDebugger)
|
if (!pDebugger)
|
||||||
{
|
{
|
||||||
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
|
if (fmt)
|
||||||
|
|
||||||
const char *filename = "";
|
|
||||||
if (pl)
|
|
||||||
{
|
|
||||||
filename = pl->getName();
|
|
||||||
} else {
|
|
||||||
CList<CScript,AMX*>::iterator a = g_loadedscripts.find(amx);
|
|
||||||
if (a)
|
|
||||||
filename = (*a).getName();
|
|
||||||
}
|
|
||||||
if (fmt != NULL)
|
|
||||||
AMXXLOG_Log("%s", msg_buffer);
|
AMXXLOG_Log("%s", msg_buffer);
|
||||||
//give the module's error first. makes the report look nicer.
|
Debugger::GenericMessage(amx, err);
|
||||||
AMXXLOG_Log("[AMXX] Run time error %d (plugin \"%s\") - debug not enabled!", err, filename);
|
|
||||||
AMXXLOG_Log("[AMXX] To enable debug mode, add \"debug\" after the plugin name in plugins.ini (without quotes).");
|
AMXXLOG_Log("[AMXX] To enable debug mode, add \"debug\" after the plugin name in plugins.ini (without quotes).");
|
||||||
//destroy original error code so the original is not displayed again
|
//destroy original error code so the original is not displayed again
|
||||||
amx->error = -1;
|
|
||||||
} else {
|
} else {
|
||||||
pDebugger->SetTracedError(err);
|
pDebugger->SetTracedError(err);
|
||||||
//we can display error now
|
//we can display error now
|
||||||
pDebugger->DisplayTrace(fmt ? msg_buffer : NULL);
|
pDebugger->DisplayTrace(fmt ? msg_buffer : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
amx->error = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MNF_MergeDefinitionFile(const char *file)
|
void MNF_MergeDefinitionFile(const char *file)
|
||||||
@ -1516,8 +1517,6 @@ void Module_CacheFunctions()
|
|||||||
REGISTER_FUNC("Deallocator", MNF_Deallocator)
|
REGISTER_FUNC("Deallocator", MNF_Deallocator)
|
||||||
REGISTER_FUNC("Reallocator", MNF_Reallocator)
|
REGISTER_FUNC("Reallocator", MNF_Reallocator)
|
||||||
#endif // MEMORY_TEST
|
#endif // MEMORY_TEST
|
||||||
|
|
||||||
REGISTER_FUNC("Haha_HiddenStuff", MNF_HiddenStuff)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *Module_ReqFnptr(const char *funcName)
|
void *Module_ReqFnptr(const char *funcName)
|
||||||
|
Loading…
Reference in New Issue
Block a user