mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2025-01-12 23:08:03 +03:00
Added Phase 3 of the debugger (debug tracing from plugins)
This commit is contained in:
parent
deaaf20713
commit
cc37f479aa
@ -830,9 +830,8 @@ const char *Debugger::_GetFilename()
|
||||
return m_FileName.c_str();
|
||||
}
|
||||
|
||||
void Debugger::GenericMessage(AMX *amx, int err)
|
||||
void Debugger::FmtGenericMsg(AMX *amx, int error, char buffer[], size_t maxLength)
|
||||
{
|
||||
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
|
||||
const char *filename = "";
|
||||
|
||||
CList<CScript,AMX*>::iterator a = g_loadedscripts.find(amx);
|
||||
@ -848,7 +847,18 @@ void Debugger::GenericMessage(AMX *amx, int err)
|
||||
}
|
||||
}
|
||||
|
||||
AMXXLOG_Log("[AMXX] Run time error %d (plugin \"%s\") - debug not enabled!", err, filename);
|
||||
_snprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") - debug not enabled!", error, filename);
|
||||
}
|
||||
|
||||
void Debugger::GenericMessage(AMX *amx, int err)
|
||||
{
|
||||
static char buffer[512];
|
||||
|
||||
buffer[0] = '\0';
|
||||
Debugger::FmtGenericMsg(amx, err, buffer, sizeof(buffer)-1);
|
||||
|
||||
if (buffer[0] != '\0')
|
||||
AMXXLOG_Log("[AMXX] %s", buffer);
|
||||
}
|
||||
|
||||
Debugger::~Debugger()
|
||||
@ -914,13 +924,25 @@ int Handler::HandleError(const char *msg)
|
||||
return 0;
|
||||
|
||||
m_Handling = true;
|
||||
m_pTrace = NULL;
|
||||
m_FmtCache.clear();
|
||||
|
||||
Debugger *pDebugger = (Debugger *)m_pAmx->userdata[UD_DEBUGGER];
|
||||
|
||||
int error = m_pAmx->error;
|
||||
|
||||
static char _buffer[512];
|
||||
if (pDebugger)
|
||||
{
|
||||
pDebugger->SetTracedError(error);
|
||||
m_pTrace = pDebugger->GetTraceStart();
|
||||
pDebugger->FormatError(_buffer, sizeof(_buffer)-1);
|
||||
m_FmtCache.assign(_buffer);
|
||||
pDebugger->BeginExec();
|
||||
} else {
|
||||
Debugger::FmtGenericMsg(m_pAmx, error, _buffer, sizeof(_buffer)-1);
|
||||
m_FmtCache.assign(_buffer);
|
||||
}
|
||||
|
||||
SetErrorMsg(msg);
|
||||
|
||||
@ -951,6 +973,8 @@ int Handler::HandleError(const char *msg)
|
||||
amx_Release(m_pAmx, hea_addr);
|
||||
|
||||
m_Handling = false;
|
||||
m_pTrace = NULL;
|
||||
m_FmtCache.clear();
|
||||
|
||||
if (err != AMX_ERR_NONE || !result)
|
||||
return 0;
|
||||
@ -983,7 +1007,77 @@ static cell AMX_NATIVE_CALL set_error_filter(AMX *amx, cell *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL dbg_trace_begin(AMX *amx, cell *params)
|
||||
{
|
||||
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
|
||||
|
||||
if (!pHandler)
|
||||
return 0; //should never happen
|
||||
|
||||
trace_info_t *pTrace = pHandler->GetTrace();
|
||||
|
||||
return (cell)(pTrace);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL dbg_trace_next(AMX *amx, cell *params)
|
||||
{
|
||||
Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
|
||||
|
||||
if (!pDebugger)
|
||||
return 0;
|
||||
|
||||
trace_info_t *pTrace = (trace_info_t *)(params[1]);
|
||||
|
||||
if (pTrace)
|
||||
return (cell)(pDebugger->GetNextTrace(pTrace));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL dbg_trace_info(AMX *amx, cell *params)
|
||||
{
|
||||
Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
|
||||
|
||||
if (!pDebugger)
|
||||
return 0;
|
||||
|
||||
trace_info_t *pTrace = (trace_info_t *)(params[1]);
|
||||
|
||||
if (!pTrace)
|
||||
return 0;
|
||||
|
||||
cell *line_addr = get_amxaddr(amx, params[2]);
|
||||
long lLine=-1;
|
||||
const char *function=NULL, *file=NULL;
|
||||
|
||||
pDebugger->GetTraceInfo(pTrace, lLine, function, file);
|
||||
|
||||
set_amxstring(amx, params[3], function ? function : "", params[4]);
|
||||
set_amxstring(amx, params[5], file ? file : "", params[5]);
|
||||
*line_addr = (cell)lLine + 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL dbg_fmt_error(AMX *amx, cell *params)
|
||||
{
|
||||
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
|
||||
|
||||
if (!pHandler)
|
||||
return 0;
|
||||
|
||||
const char *str = pHandler->GetFmtCache();
|
||||
|
||||
set_amxstring(amx, params[1], str, params[2]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO g_DebugNatives[] = {
|
||||
{"set_error_filter", set_error_filter},
|
||||
{"dbg_trace_begin", dbg_trace_begin},
|
||||
{"dbg_trace_next", dbg_trace_next},
|
||||
{"dbg_trace_info", dbg_trace_info},
|
||||
{"dbg_fmt_error", dbg_fmt_error},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
@ -123,6 +123,7 @@ public:
|
||||
public:
|
||||
//generic static opcode breaker
|
||||
static int AMXAPI DebugHook(AMX *amx);
|
||||
static void FmtGenericMsg(AMX *amx, int error, char buffer[], size_t maxLength);
|
||||
static void GenericMessage(AMX *amx, int error);
|
||||
private:
|
||||
void _CacheAmxOpcodeList();
|
||||
@ -164,13 +165,17 @@ public:
|
||||
bool IsHandling() const { return m_Handling; }
|
||||
void SetErrorMsg(const char *msg);
|
||||
const char *GetLastMsg();
|
||||
public:
|
||||
trace_info_t *GetTrace() const { return m_pTrace; }
|
||||
const char *GetFmtCache() { return m_FmtCache.c_str(); }
|
||||
private:
|
||||
AMX *m_pAmx;
|
||||
int m_iErrFunc;
|
||||
int m_iModFunc;
|
||||
int m_iNatFunc;
|
||||
bool m_Handling;
|
||||
String m_MsgCache;
|
||||
String m_FmtCache;
|
||||
trace_info_t *m_pTrace;
|
||||
};
|
||||
|
||||
extern AMX_NATIVE_INFO g_DebugNatives[];
|
||||
|
@ -809,3 +809,24 @@ native query_client_cvar(id, const cvar[], const resultFunc[], paramlen=0, const
|
||||
* Return PLUGIN_HANDLED to block the error from displaying.
|
||||
*/
|
||||
native set_error_filter(consthandler[]);
|
||||
|
||||
/**
|
||||
* Gets a trace handle for the item at the top of the traced call stack.
|
||||
* Returns 0 if no debugging information is available.
|
||||
*/
|
||||
native dbg_trace_begin();
|
||||
|
||||
/**
|
||||
* Gets the next item in a traced call stack. Returns 0 if no more traces exist.
|
||||
*/
|
||||
native dbg_trace_next(trace);
|
||||
|
||||
/**
|
||||
* Gets the call stack info for a trace.
|
||||
*/
|
||||
native dbg_trace_info(trace, &line, function[], maxLength1, file[], maxLength2);
|
||||
|
||||
/**
|
||||
* Gets the formatted error string, which looks like "Run time error X: (description)"
|
||||
*/
|
||||
native dbg_fmt_error(buffer[], maxLength);
|
||||
|
Loading…
x
Reference in New Issue
Block a user