mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-25 06:15:37 +03:00
Committed brand new debugger system
This commit is contained in:
parent
586d09e533
commit
6a97d73167
@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
#include "amxmodx.h"
|
#include "amxmodx.h"
|
||||||
|
|
||||||
|
void AMXAPI amxx_InvalidateTrace(AMX *amx);
|
||||||
|
|
||||||
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes)
|
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes)
|
||||||
{
|
{
|
||||||
m_FuncName = name;
|
m_FuncName = name;
|
||||||
@ -70,6 +72,11 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
{
|
{
|
||||||
if (iter->pPlugin->isExecutable(iter->func))
|
if (iter->pPlugin->isExecutable(iter->func))
|
||||||
{
|
{
|
||||||
|
// Get debug info
|
||||||
|
AMX *amx = (*iter).pPlugin->getAMX();
|
||||||
|
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]);
|
||||||
|
if (pInfo)
|
||||||
|
pInfo->error = AMX_ERR_NONE;
|
||||||
// handle strings & arrays
|
// handle strings & arrays
|
||||||
int i, ax=0;
|
int i, ax=0;
|
||||||
for (i = 0; i < m_NumParams; ++i)
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
@ -86,7 +93,7 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||||
{
|
{
|
||||||
cell *tmp;
|
cell *tmp;
|
||||||
amx_Allot(iter->pPlugin->getAMX(), preparedArrays[params[i]].size,
|
amx_Allot(amx, preparedArrays[params[i]].size,
|
||||||
&realParams[i], &tmp);
|
&realParams[i], &tmp);
|
||||||
physAddrs[i] = tmp;
|
physAddrs[i] = tmp;
|
||||||
if (preparedArrays[params[i]].type == Type_Cell)
|
if (preparedArrays[params[i]].type == Type_Cell)
|
||||||
@ -108,14 +115,25 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
//Push the parameters in reverse order. Weird, unfriendly part of Small 3.0!
|
//Push the parameters in reverse order. Weird, unfriendly part of Small 3.0!
|
||||||
for (i=m_NumParams-1; i>=0; i--)
|
for (i=m_NumParams-1; i>=0; i--)
|
||||||
{
|
{
|
||||||
amx_Push(iter->pPlugin->getAMX(), realParams[i]);
|
amx_Push(amx, realParams[i]);
|
||||||
}
|
}
|
||||||
// exec
|
// exec
|
||||||
cell retVal;
|
cell retVal;
|
||||||
int err = amx_Exec(iter->pPlugin->getAMX(), &retVal, iter->func);
|
int err = amx_Exec(amx, &retVal, iter->func);
|
||||||
// log runtime error, if any
|
// log runtime error, if any
|
||||||
if (err != AMX_ERR_NONE)
|
if (err != AMX_ERR_NONE)
|
||||||
LogError(iter->pPlugin->getAMX(), err, "");
|
{
|
||||||
|
//Did something else set an error?
|
||||||
|
if (pInfo && pInfo->error != AMX_ERR_NONE)
|
||||||
|
{
|
||||||
|
//we don't care, something else logged the error.
|
||||||
|
} else {
|
||||||
|
//nothing logged the error so spit it out anyway
|
||||||
|
LogError(amx, err, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
amxx_InvalidateTrace(amx);
|
||||||
|
amx->error = AMX_ERR_NONE;
|
||||||
|
|
||||||
// cleanup strings & arrays
|
// cleanup strings & arrays
|
||||||
for (i = 0; i < m_NumParams; ++i)
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
@ -211,6 +229,10 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
if (!pPlugin->isExecutable(m_Func))
|
if (!pPlugin->isExecutable(m_Func))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(m_Amx->userdata[2]);
|
||||||
|
if (pInfo)
|
||||||
|
pInfo->error = AMX_ERR_NONE;
|
||||||
|
|
||||||
// handle strings & arrays
|
// handle strings & arrays
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < m_NumParams; ++i)
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
@ -251,10 +273,19 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
// exec
|
// exec
|
||||||
cell retVal;
|
cell retVal;
|
||||||
int err = amx_Exec(m_Amx, &retVal, m_Func);
|
int err = amx_Exec(m_Amx, &retVal, m_Func);
|
||||||
|
|
||||||
// log runtime error, if any
|
|
||||||
if (err != AMX_ERR_NONE)
|
if (err != AMX_ERR_NONE)
|
||||||
LogError(m_Amx, err, "");
|
{
|
||||||
|
//Did something else set an error?
|
||||||
|
if (pInfo && pInfo->error != AMX_ERR_NONE)
|
||||||
|
{
|
||||||
|
//we don't care, something else logged the error.
|
||||||
|
} else {
|
||||||
|
//nothing logged the error so spit it out anyway
|
||||||
|
LogError(m_Amx, err, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
amxx_InvalidateTrace(m_Amx);
|
||||||
|
m_Amx->error = AMX_ERR_NONE;
|
||||||
|
|
||||||
// cleanup strings & arrays
|
// cleanup strings & arrays
|
||||||
for (i = 0; i < m_NumParams; ++i)
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
|
@ -137,7 +137,7 @@ const char* CPluginMngr::CPlugin::getStatus() const {
|
|||||||
switch(status){
|
switch(status){
|
||||||
case ps_running:
|
case ps_running:
|
||||||
{
|
{
|
||||||
if (getAMX()->flags & AMX_FLAG_DEBUG)
|
if (m_Debug)
|
||||||
{
|
{
|
||||||
return "debug";
|
return "debug";
|
||||||
} else {
|
} else {
|
||||||
@ -172,8 +172,17 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p,const char* n, char* e, int d
|
|||||||
paused_fun = 0;
|
paused_fun = 0;
|
||||||
next = 0;
|
next = 0;
|
||||||
id = i;
|
id = i;
|
||||||
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause");
|
if (status == ps_running)
|
||||||
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause");
|
{
|
||||||
|
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause");
|
||||||
|
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause");
|
||||||
|
if (amx.flags & AMX_FLAG_DEBUG)
|
||||||
|
{
|
||||||
|
m_Debug = true;
|
||||||
|
} else {
|
||||||
|
m_Debug = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPluginMngr::CPlugin::~CPlugin( )
|
CPluginMngr::CPlugin::~CPlugin( )
|
||||||
|
@ -42,7 +42,7 @@ enum {
|
|||||||
ps_paused,
|
ps_paused,
|
||||||
ps_running,
|
ps_running,
|
||||||
ps_stopped,
|
ps_stopped,
|
||||||
ps_locked
|
ps_locked,
|
||||||
};
|
};
|
||||||
|
|
||||||
class CPluginMngr
|
class CPluginMngr
|
||||||
@ -72,6 +72,7 @@ public:
|
|||||||
int id;
|
int id;
|
||||||
CPlugin(int i , const char* p,const char* n, char* e, int d);
|
CPlugin(int i , const char* p,const char* n, char* e, int d);
|
||||||
~CPlugin( );
|
~CPlugin( );
|
||||||
|
bool m_Debug;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -98,6 +99,7 @@ public:
|
|||||||
void unpauseFunction( int id );
|
void unpauseFunction( int id );
|
||||||
void setStatus( int a );
|
void setStatus( int a );
|
||||||
const char* getStatus() const;
|
const char* getStatus() const;
|
||||||
|
inline bool isDebug() const { return m_Debug; }
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -334,10 +334,22 @@ enum {
|
|||||||
#define AMX_COMPACTMARGIN 64
|
#define AMX_COMPACTMARGIN 64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct amx_trace
|
||||||
|
{
|
||||||
|
cell frm;
|
||||||
|
amx_trace *prev;
|
||||||
|
amx_trace *next;
|
||||||
|
bool used;
|
||||||
|
};
|
||||||
|
|
||||||
struct AMX_DBGINFO
|
struct AMX_DBGINFO
|
||||||
{
|
{
|
||||||
void *pDebug; //Pointer to debug data
|
void *pDebug; //Pointer to debug data
|
||||||
int error; //non-amx_Exec() error setting
|
int error; //non-amx_Exec() error setting
|
||||||
|
amx_trace *pTrace; //Pointer to stack trace
|
||||||
|
amx_trace *pTraceFrm;
|
||||||
|
amx_trace *pTraceEnd;
|
||||||
|
cell frm;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* for native functions that use floating point parameters, the following
|
/* for native functions that use floating point parameters, the following
|
||||||
|
@ -958,7 +958,7 @@ static cell AMX_NATIVE_CALL get_concmd(AMX *amx, cell *params) /* 7 param */
|
|||||||
else // -1 parameter - all commands
|
else // -1 parameter - all commands
|
||||||
who = CMD_ConsoleCommand;
|
who = CMD_ConsoleCommand;
|
||||||
|
|
||||||
CmdMngr::Command* cmd = g_commands.getCmd(params[1] ,who , params[7] );
|
CmdMngr::Command* cmd = g_commands.getCmd(params[1], who, params[7]);
|
||||||
|
|
||||||
if ( cmd == 0 ) return 0;
|
if ( cmd == 0 ) return 0;
|
||||||
set_amxstring(amx,params[2], cmd->getCmdLine() ,params[3]);
|
set_amxstring(amx,params[2], cmd->getCmdLine() ,params[3]);
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "osdep.h" // sleep, etc
|
#include "osdep.h" // sleep, etc
|
||||||
#include "CFile.h"
|
#include "CFile.h"
|
||||||
#include "amxxfile.h"
|
#include "amxxfile.h"
|
||||||
|
#include "amxdbg.h"
|
||||||
|
|
||||||
CList<CModule,const char*> g_modules;
|
CList<CModule,const char*> g_modules;
|
||||||
CList<CScript,AMX*> g_loadedscripts;
|
CList<CScript,AMX*> g_loadedscripts;
|
||||||
@ -88,10 +89,170 @@ void* alloc_amxmemory(void** p, int size)
|
|||||||
|
|
||||||
void free_amxmemory(void **ptr)
|
void free_amxmemory(void **ptr)
|
||||||
{
|
{
|
||||||
delete[] *ptr;
|
delete[] (unsigned char *)(*ptr);
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void amxx_FreeTrace(AMX_DBGINFO *pInfo)
|
||||||
|
{
|
||||||
|
amx_trace *pTrace = pInfo->pTrace;
|
||||||
|
amx_trace *pTemp = NULL;
|
||||||
|
|
||||||
|
while (pTrace)
|
||||||
|
{
|
||||||
|
pTemp = pTrace->next;
|
||||||
|
delete pTrace;
|
||||||
|
pTrace = pTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->pTrace = NULL;
|
||||||
|
pInfo->pTraceFrm = NULL;
|
||||||
|
pInfo->pTraceEnd = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//returns true if this was the last call
|
||||||
|
bool amxx_RemTraceCall(AMX_DBGINFO *pInfo)
|
||||||
|
{
|
||||||
|
amx_trace *pTrace = pInfo->pTraceFrm;
|
||||||
|
|
||||||
|
assert(pTrace != NULL);
|
||||||
|
|
||||||
|
pInfo->pTraceFrm = pTrace->prev;
|
||||||
|
pTrace->used = false;
|
||||||
|
|
||||||
|
if (pInfo->pTraceFrm == NULL)
|
||||||
|
{
|
||||||
|
//invalidate the trace
|
||||||
|
pInfo->frm = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void amxx_FreeDebug(AMX *amx)
|
||||||
|
{
|
||||||
|
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)amx->userdata[2];
|
||||||
|
if (pInfo)
|
||||||
|
{
|
||||||
|
AMX_DBG *pDbg = (AMX_DBG *)pInfo->pDebug;
|
||||||
|
if (pDbg)
|
||||||
|
{
|
||||||
|
dbg_FreeInfo(pDbg);
|
||||||
|
delete pDbg;
|
||||||
|
}
|
||||||
|
if (pInfo->pTrace)
|
||||||
|
amxx_FreeTrace(pInfo);
|
||||||
|
delete pInfo;
|
||||||
|
amx->userdata[2] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
amx_trace *amxx_AddTraceCall(AMX_DBGINFO *pInfo)
|
||||||
|
{
|
||||||
|
amx_trace *pTrace = NULL;
|
||||||
|
|
||||||
|
if (pInfo->pTrace == NULL)
|
||||||
|
{
|
||||||
|
pTrace = new amx_trace;
|
||||||
|
memset(pTrace, 0, sizeof(amx_trace));
|
||||||
|
pInfo->pTrace = pTrace;
|
||||||
|
pInfo->pTraceFrm = pTrace;
|
||||||
|
pInfo->pTraceEnd = pTrace;
|
||||||
|
} else if (pInfo->pTraceFrm == NULL) {
|
||||||
|
pTrace = pInfo->pTrace;
|
||||||
|
pInfo->pTraceFrm = pTrace;
|
||||||
|
} else {
|
||||||
|
if (pInfo->pTraceFrm->next == NULL)
|
||||||
|
{
|
||||||
|
//if we are at the end of the list...
|
||||||
|
assert(pInfo->pTraceFrm == pInfo->pTraceEnd);
|
||||||
|
pTrace = new amx_trace;
|
||||||
|
memset(pTrace, 0, sizeof(amx_trace));
|
||||||
|
pTrace->prev = pInfo->pTraceEnd;
|
||||||
|
pInfo->pTraceEnd->next = pTrace;
|
||||||
|
pInfo->pTraceEnd = pTrace;
|
||||||
|
pInfo->pTraceFrm = pTrace;
|
||||||
|
} else {
|
||||||
|
//we are somewhere else. whatever.
|
||||||
|
pTrace = pInfo->pTraceFrm->next;
|
||||||
|
pInfo->pTraceFrm = pTrace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pTrace->used = true;
|
||||||
|
|
||||||
|
return pTrace;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMXAPI amxx_InvalidateTrace(AMX *amx)
|
||||||
|
{
|
||||||
|
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]);
|
||||||
|
if (!pInfo)
|
||||||
|
return;
|
||||||
|
amx_trace *pTrace = pInfo->pTrace;
|
||||||
|
|
||||||
|
while (pTrace && pTrace->used)
|
||||||
|
{
|
||||||
|
pTrace->used = false;
|
||||||
|
pTrace = pTrace->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->pTraceFrm = NULL;
|
||||||
|
pInfo->frm = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AMXAPI amxx_DebugHook(AMX *amx)
|
||||||
|
{
|
||||||
|
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)amx->userdata[2];
|
||||||
|
|
||||||
|
if ( !(amx->flags & AMX_FLAG_DEBUG) || !pInfo )
|
||||||
|
return AMX_ERR_DEBUG;
|
||||||
|
|
||||||
|
enum StackState
|
||||||
|
{
|
||||||
|
Stack_Same,
|
||||||
|
Stack_Push,
|
||||||
|
Stack_Pop,
|
||||||
|
};
|
||||||
|
|
||||||
|
StackState state = Stack_Same;
|
||||||
|
|
||||||
|
if (!pInfo->frm)
|
||||||
|
{
|
||||||
|
pInfo->frm = amx->frm;
|
||||||
|
state = Stack_Push;
|
||||||
|
} else {
|
||||||
|
//Are we stepping through a different frame?
|
||||||
|
if (amx->frm < pInfo->frm)
|
||||||
|
{
|
||||||
|
pInfo->frm = amx->frm;
|
||||||
|
state = Stack_Push;
|
||||||
|
} else if (amx->frm > pInfo->frm) {
|
||||||
|
pInfo->frm = amx->frm;
|
||||||
|
state = Stack_Pop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state == Stack_Push)
|
||||||
|
{
|
||||||
|
amx_trace *pTrace = amxx_AddTraceCall(pInfo);
|
||||||
|
pTrace->frm = amx->cip;
|
||||||
|
} else if (state == Stack_Pop) {
|
||||||
|
if (amxx_RemTraceCall(pInfo))
|
||||||
|
{
|
||||||
|
pInfo->frm = 0;
|
||||||
|
}
|
||||||
|
} else if (state == Stack_Same) {
|
||||||
|
//save the cip
|
||||||
|
amx_trace *pTrace = pInfo->pTraceFrm;
|
||||||
|
assert(pTrace != NULL);
|
||||||
|
pTrace->frm = amx->cip;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AMX_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug)
|
int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug)
|
||||||
{
|
{
|
||||||
*error = 0;
|
*error = 0;
|
||||||
@ -155,12 +316,36 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
|||||||
|
|
||||||
int err;
|
int err;
|
||||||
memset(amx, 0, sizeof(*amx));
|
memset(amx, 0, sizeof(*amx));
|
||||||
|
bool will_be_debugged = false;
|
||||||
|
|
||||||
|
tagAMX_DBG *pDbg = NULL;
|
||||||
|
|
||||||
if ((int)CVAR_GET_FLOAT("amx_debug") >= 2 || debug)
|
if ((int)CVAR_GET_FLOAT("amx_debug") >= 2 || debug)
|
||||||
{
|
{
|
||||||
if ((amx->flags & AMX_FLAG_DEBUG) != 0)
|
if ((hdr->file_version < CUR_FILE_VERSION))
|
||||||
{
|
{
|
||||||
//:TODO: debug support
|
sprintf(error, "Plugin needs newer debug version info");
|
||||||
|
return (amx->error = AMX_ERR_VERSION);
|
||||||
|
} else if ((hdr->flags & AMX_FLAG_DEBUG) != 0) {
|
||||||
|
will_be_debugged = true;
|
||||||
|
char *addr = (char *)hdr + hdr->size;
|
||||||
|
pDbg = new tagAMX_DBG;
|
||||||
|
memset(pDbg, 0, sizeof(AMX_DBG));
|
||||||
|
|
||||||
|
int err = dbg_LoadInfo(pDbg, addr);
|
||||||
|
|
||||||
|
if (err != AMX_ERR_NONE)
|
||||||
|
{
|
||||||
|
dbg_FreeInfo(pDbg);
|
||||||
|
delete pDbg;
|
||||||
|
sprintf(error, "Debug loading error %d", err);
|
||||||
|
return (amx->error = AMX_ERR_INIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
amx->flags |= AMX_FLAG_DEBUG;
|
||||||
|
} else {
|
||||||
|
sprintf(error,"Plugin not compiled with debug option");
|
||||||
|
return (amx->error = AMX_ERR_INIT);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifdef JIT
|
#ifdef JIT
|
||||||
@ -171,11 +356,31 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
|||||||
|
|
||||||
if ((err = amx_Init( amx, *program )) != AMX_ERR_NONE)
|
if ((err = amx_Init( amx, *program )) != AMX_ERR_NONE)
|
||||||
{
|
{
|
||||||
|
if (pDbg)
|
||||||
|
{
|
||||||
|
dbg_FreeInfo(pDbg);
|
||||||
|
delete pDbg;
|
||||||
|
}
|
||||||
sprintf(error,"Load error %d (invalid file format or version)", err);
|
sprintf(error,"Load error %d (invalid file format or version)", err);
|
||||||
return (amx->error = AMX_ERR_INIT);
|
return (amx->error = AMX_ERR_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_MESSAGE(PLID, "AMX: %p FLAGS: %d\n", amx, amx->flags);
|
AMX_DBGINFO *pInfo = new AMX_DBGINFO;
|
||||||
|
memset(pInfo, 0, sizeof(AMX_DBGINFO));
|
||||||
|
amx->userdata[2] = (void *)pInfo;
|
||||||
|
|
||||||
|
pInfo->error = AMX_ERR_NONE;
|
||||||
|
pInfo->pDebug = (void *)pDbg;
|
||||||
|
|
||||||
|
if (will_be_debugged)
|
||||||
|
{
|
||||||
|
amx->flags |= AMX_FLAG_DEBUG;
|
||||||
|
amx_SetDebugHook(amx, amxx_DebugHook);
|
||||||
|
} else {
|
||||||
|
//set this again because amx_Init() erases it!
|
||||||
|
amx->flags |= AMX_FLAG_JITC;
|
||||||
|
amx->sysreq_d = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef JIT
|
#ifdef JIT
|
||||||
if (amx->flags & AMX_FLAG_JITC)
|
if (amx->flags & AMX_FLAG_JITC)
|
||||||
@ -355,6 +560,7 @@ int set_amxnatives(AMX* amx,char error[128])
|
|||||||
|
|
||||||
int unload_amxscript(AMX* amx, void** program)
|
int unload_amxscript(AMX* amx, void** program)
|
||||||
{
|
{
|
||||||
|
amxx_FreeDebug(amx);
|
||||||
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;
|
||||||
@ -363,7 +569,6 @@ int unload_amxscript(AMX* amx, void** program)
|
|||||||
return AMX_ERR_NONE;
|
return AMX_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AMX* get_amxscript(int id , void** code, const char** filename)
|
AMX* get_amxscript(int id , void** code, const char** filename)
|
||||||
{
|
{
|
||||||
CList<CScript,AMX*>::iterator a = g_loadedscripts.begin();
|
CList<CScript,AMX*>::iterator a = g_loadedscripts.begin();
|
||||||
@ -1180,9 +1385,27 @@ void MNF_Log(const char *fmt, ...)
|
|||||||
AMXXLOG_Log("%s", msg);
|
AMXXLOG_Log("%s", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool amxx_GetPluginData(AMX *amx, cell addr, long &line, const char *&filename, const char *&function)
|
||||||
|
{
|
||||||
|
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]);
|
||||||
|
|
||||||
|
if (pInfo && pInfo->pDebug)
|
||||||
|
{
|
||||||
|
AMX_DBG *pDbg = (AMX_DBG *)pInfo->pDebug;
|
||||||
|
dbg_LookupFunction(pDbg, addr, &function);
|
||||||
|
dbg_LookupLine(pDbg, addr, &line);
|
||||||
|
dbg_LookupFile(pDbg, addr, &filename);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//by BAILOPAN
|
//by BAILOPAN
|
||||||
// generic error printing routine
|
// generic error printing routine
|
||||||
void GenericError(AMX *amx, int err, int line, char buf[], const char *file)
|
// for pawn 3.0 this is just a wrapper
|
||||||
|
const char *GenericError(int err)
|
||||||
{
|
{
|
||||||
static const char *amx_errs[] =
|
static const char *amx_errs[] =
|
||||||
{
|
{
|
||||||
@ -1199,7 +1422,7 @@ void GenericError(AMX *amx, int err, int line, char buf[], const char *file)
|
|||||||
"native",
|
"native",
|
||||||
"divide",
|
"divide",
|
||||||
"sleep",
|
"sleep",
|
||||||
NULL,
|
"invalid access state",
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
"out of memory", //16
|
"out of memory", //16
|
||||||
@ -1217,31 +1440,10 @@ void GenericError(AMX *amx, int err, int line, char buf[], const char *file)
|
|||||||
//does this plugin have line ops?
|
//does this plugin have line ops?
|
||||||
const char *geterr = NULL;
|
const char *geterr = NULL;
|
||||||
if (err > 26 || err < 0)
|
if (err > 26 || err < 0)
|
||||||
geterr = NULL;
|
geterr = "";
|
||||||
else
|
else
|
||||||
geterr = amx_errs[err];
|
geterr = amx_errs[err];
|
||||||
if (!(amx->flags & AMX_FLAG_DEBUG))
|
return geterr;
|
||||||
{
|
|
||||||
if (geterr == NULL)
|
|
||||||
{
|
|
||||||
sprintf(buf, "Run time error %d (plugin \"%s\" - debug not enabled).", err, g_plugins.findPluginFast(amx)->getName());
|
|
||||||
} else {
|
|
||||||
sprintf(buf, "Run time error %d (%s) (plugin \"%s\") - debug not enabled.", err, geterr, g_plugins.findPluginFast(amx)->getName());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (geterr == NULL)
|
|
||||||
{
|
|
||||||
sprintf(buf, "Run time error %d on line %d (%s \"%s\").", err, line, (file?"file":"plugin"), (file?file:g_plugins.findPluginFast(amx)->getName()));
|
|
||||||
} else {
|
|
||||||
if (err == AMX_ERR_NATIVE && amx->userdata[2])
|
|
||||||
{
|
|
||||||
geterr = (char *)(amx->userdata[2]);
|
|
||||||
sprintf(buf, "Native error in \"%s\" on line %d (%s \"%s\").", geterr, line, (file?"file":"plugin"), (file?file:g_plugins.findPluginFast(amx)->getName()));
|
|
||||||
} else {
|
|
||||||
sprintf(buf, "Run time error %d (%s) on line %d (%s \"%s\").", err, geterr, line, (file?"file":"plugin"), (file?file:g_plugins.findPluginFast(amx)->getName()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//by BAILOPAN
|
//by BAILOPAN
|
||||||
@ -1250,71 +1452,69 @@ void LogError(AMX *amx, int err, const char *fmt, ...)
|
|||||||
{
|
{
|
||||||
//does this plugin have debug info?
|
//does this plugin have debug info?
|
||||||
va_list arg;
|
va_list arg;
|
||||||
//AMX_DBG *dbg = (AMX_DBG *)(amx->userdata[0]);
|
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]);
|
||||||
|
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
|
||||||
static char buf[1024];
|
static char buf[1024];
|
||||||
static char vbuf[1024];
|
static char vbuf[1024];
|
||||||
*buf = 0;
|
*buf = 0;
|
||||||
*vbuf = 0;
|
*vbuf = 0;
|
||||||
|
|
||||||
va_start(arg, fmt);
|
if (fmt[0] == '\0')
|
||||||
vsprintf(vbuf, fmt, arg);
|
|
||||||
va_end(arg);
|
|
||||||
#if 0
|
|
||||||
if (!dbg || !(dbg->tail))
|
|
||||||
{
|
{
|
||||||
if (dbg && amx->curfile < dbg->numFiles && amx->curfile >= 0)
|
_snprintf(vbuf, sizeof(vbuf)-1, "Run time error %d (%s)", err, GenericError(err));
|
||||||
{
|
|
||||||
GenericError(amx, err, amx->curline, buf, dbg->files[amx->curfile]);
|
|
||||||
} else {
|
|
||||||
GenericError(amx, err, amx->curline, buf, NULL);
|
|
||||||
}
|
|
||||||
AMXXLOG_Log("[AMXX] %s", buf);
|
|
||||||
if (*vbuf)
|
|
||||||
{
|
|
||||||
AMXXLOG_Log("%s", vbuf);
|
|
||||||
}
|
|
||||||
if (!dbg)
|
|
||||||
{
|
|
||||||
AMXXLOG_Log("[AMXX] To enable debug mode, add \" debug\" after the plugin name in plugins.ini (without quotes).");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
AMX_TRACE *t = dbg->tail;
|
va_start(arg, fmt);
|
||||||
AMX_DEBUGCALL tracer = (AMX_DEBUGCALL)(amx->userdata[1]);
|
vsprintf(vbuf, fmt, arg);
|
||||||
//actuall
|
va_end(arg);
|
||||||
cell line = amx->curline;
|
|
||||||
cell file = amx->curfile;
|
|
||||||
int i = 0;
|
|
||||||
GenericError(amx, err, line, buf, NULL);
|
|
||||||
AMXXLOG_Log("[AMXX] %s", buf);
|
|
||||||
if (*vbuf)
|
|
||||||
{
|
|
||||||
AMXXLOG_Log("%s", vbuf);
|
|
||||||
}
|
|
||||||
AMXXLOG_Log("[AMXX] Debug Trace =>");
|
|
||||||
//log the error right away
|
|
||||||
if (file >= dbg->numFiles || file < 0)
|
|
||||||
{
|
|
||||||
AMXXLOG_Log("[AMXX] [%d] Line %d, File \"%s\"", i++, line, g_plugins.findPluginFast(amx)->getName());
|
|
||||||
} else {
|
|
||||||
AMXXLOG_Log("[AMXX] [%d] Line %d, File \"%s\"", i++, line, dbg->files[file]);
|
|
||||||
}
|
|
||||||
while (t != NULL)
|
|
||||||
{
|
|
||||||
line = t->line;
|
|
||||||
file = t->file;
|
|
||||||
if (file >= dbg->numFiles)
|
|
||||||
{
|
|
||||||
AMXXLOG_Log("[AMXX] [%d] Line %d, File \"%s\"", i++, line, g_plugins.findPluginFast(amx)->getName());
|
|
||||||
} else {
|
|
||||||
AMXXLOG_Log("[AMXX] [%d] Line %d, File \"%s\"", i++, line, dbg->files[file]);
|
|
||||||
}
|
|
||||||
if (tracer)
|
|
||||||
(tracer)(amx, 1); //pop
|
|
||||||
t = dbg->tail;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
amx_RaiseError(amx, err);
|
bool invalidate = false;
|
||||||
|
AMXXLOG_Log("[AMXX] %s", vbuf);
|
||||||
|
if (!pInfo || !(amx->flags & AMX_FLAG_DEBUG) || !pInfo->pDebug)
|
||||||
|
{
|
||||||
|
AMXXLOG_Log("[AMXX] Debug is not enabled (plugin \"%s\")", pPlugin->getName());
|
||||||
|
invalidate = true;
|
||||||
|
} else {
|
||||||
|
long line;
|
||||||
|
const char *filename = NULL;
|
||||||
|
const char *function = NULL;
|
||||||
|
amx_trace *pTrace = pInfo->pTraceFrm;
|
||||||
|
int i=0, iLine;
|
||||||
|
cell frame;
|
||||||
|
|
||||||
|
AMXXLOG_Log("[AMXX] Displaying call trace (plugin \"%s\")", pPlugin->getName());
|
||||||
|
while (pTrace)
|
||||||
|
{
|
||||||
|
frame = pTrace->frm;
|
||||||
|
|
||||||
|
if (amxx_GetPluginData(amx, frame, line, filename, function))
|
||||||
|
{
|
||||||
|
//line seems to be 1 off o_O
|
||||||
|
iLine = static_cast<int>(line) + 1;
|
||||||
|
AMXXLOG_Log("[AMXX] [%d] %s::%s (line %d)",
|
||||||
|
i,
|
||||||
|
filename?filename:"",
|
||||||
|
function?function:"",
|
||||||
|
iLine
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pTrace->used = false;
|
||||||
|
pTrace = pTrace->prev;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
//by now we have already invalidated
|
||||||
|
pInfo->pTraceFrm = NULL;
|
||||||
|
pInfo->frm = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invalidate)
|
||||||
|
amxx_InvalidateTrace(amx);
|
||||||
|
|
||||||
|
//set these so ForwardMngr knows not to call us again
|
||||||
|
//This will also halt the script!
|
||||||
|
amx->error = err;
|
||||||
|
pInfo->error = err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MNF_MergeDefinitionFile(const char *file)
|
void MNF_MergeDefinitionFile(const char *file)
|
||||||
|
@ -442,7 +442,7 @@
|
|||||||
InlineFunctionExpansion="1"
|
InlineFunctionExpansion="1"
|
||||||
FavorSizeOrSpeed="1"
|
FavorSizeOrSpeed="1"
|
||||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST;JIT"
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST;JIT;ASM32;PAWN_CELL_SIZE=32"
|
||||||
StringPooling="TRUE"
|
StringPooling="TRUE"
|
||||||
RuntimeLibrary="4"
|
RuntimeLibrary="4"
|
||||||
EnableFunctionLevelLinking="TRUE"
|
EnableFunctionLevelLinking="TRUE"
|
||||||
@ -460,7 +460,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalOptions="/MACHINE:I386"
|
AdditionalOptions="/MACHINE:I386"
|
||||||
AdditionalDependencies="..\jit\jits.obj ..\zlib\zlib.lib"
|
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj"
|
||||||
OutputFile="jitmemtestrelease/amxmodx_mm.dll"
|
OutputFile="jitmemtestrelease/amxmodx_mm.dll"
|
||||||
LinkIncremental="1"
|
LinkIncremental="1"
|
||||||
SuppressStartupBanner="TRUE"
|
SuppressStartupBanner="TRUE"
|
||||||
@ -581,6 +581,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\amxcore.cpp">
|
RelativePath="..\amxcore.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\amxdbg.cpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\amxmodx.cpp">
|
RelativePath="..\amxmodx.cpp">
|
||||||
</File>
|
</File>
|
||||||
@ -721,6 +724,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\amx.h">
|
RelativePath="..\amx.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\amxdbg.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\amxmodx.h">
|
RelativePath="..\amxmodx.h">
|
||||||
</File>
|
</File>
|
||||||
|
Loading…
Reference in New Issue
Block a user