New debugging engine
This commit is contained in:
parent
0c2dbdbc47
commit
d3751054da
@ -110,7 +110,8 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
int err = amx_Execv(iter->pPlugin->getAMX(), &retVal, iter->func, m_NumParams, realParams);
|
int err = amx_Execv(iter->pPlugin->getAMX(), &retVal, iter->func, m_NumParams, realParams);
|
||||||
// log runtime error, if any
|
// log runtime error, if any
|
||||||
if (err != AMX_ERR_NONE)
|
if (err != AMX_ERR_NONE)
|
||||||
AMXXLOG_Log("[AMXX] Run time error %d on line %ld (plugin \"%s\")", err, iter->pPlugin->getAMX()->curline, iter->pPlugin->getName());
|
LogError(iter->pPlugin->getAMX(), err, "");
|
||||||
|
// AMXXLOG_Log("[AMXX] Run time error %d on line %ld (plugin \"%s\")", err, iter->pPlugin->getAMX()->curline, iter->pPlugin->getName());
|
||||||
|
|
||||||
// cleanup strings & arrays
|
// cleanup strings & arrays
|
||||||
for (i = 0; i < m_NumParams; ++i)
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
|
155
amxmodx/amx.cpp
155
amxmodx/amx.cpp
@ -39,11 +39,13 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stddef.h> /* for wchar_t */
|
#include <stddef.h> /* for wchar_t */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <malloc.h>
|
||||||
#include "osdefs.h"
|
#include "osdefs.h"
|
||||||
#if defined LINUX
|
#if defined LINUX
|
||||||
#include <sclinux.h>
|
#include <sclinux.h>
|
||||||
@ -479,6 +481,62 @@ int AMXAPI amx_Debug(AMX *amx)
|
|||||||
return AMX_ERR_DEBUG;
|
return AMX_ERR_DEBUG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Here is the actual debugger that AMX Mod X uses
|
||||||
|
int AMXAPI amx_DebugCall(AMX *amx, int mode)
|
||||||
|
{
|
||||||
|
//right away, check for debugging
|
||||||
|
AMX_HEADER *hdr;
|
||||||
|
AMX_DBG *p = 0;
|
||||||
|
AMX_TRACE *t = 0;
|
||||||
|
hdr = (AMX_HEADER *)amx->base;
|
||||||
|
if ( !(amx->flags & AMX_FLAG_DEBUG) || !(amx->flags & AMX_FLAG_LINEOPS))
|
||||||
|
return AMX_ERR_NONE;
|
||||||
|
p = (AMX_DBG *)(amx->userdata[0]);
|
||||||
|
if ( !p )
|
||||||
|
return AMX_ERR_NONE;
|
||||||
|
if (mode == 2)
|
||||||
|
{
|
||||||
|
//mode - push onto the stack
|
||||||
|
t = (AMX_TRACE *)malloc(sizeof(AMX_TRACE));
|
||||||
|
memset(t, 0, sizeof(AMX_TRACE));
|
||||||
|
if (!p->head)
|
||||||
|
{
|
||||||
|
p->head = t;
|
||||||
|
t->prev = NULL;
|
||||||
|
} else {
|
||||||
|
t->prev = p->tail;
|
||||||
|
p->tail->next = t;
|
||||||
|
}
|
||||||
|
p->tail = t;
|
||||||
|
t->line = amx->curline;
|
||||||
|
t->file = amx->curfile;
|
||||||
|
} else if (mode == 1) {
|
||||||
|
//mode <0 - pop from the stack
|
||||||
|
t = p->tail;
|
||||||
|
if (t)
|
||||||
|
{
|
||||||
|
p->tail = t->prev;
|
||||||
|
free(t);
|
||||||
|
}
|
||||||
|
if (p->tail == NULL)
|
||||||
|
p->head = NULL;
|
||||||
|
} else if (mode == 0) {
|
||||||
|
AMX_TRACE *m;
|
||||||
|
//mode == 0 - clear stack
|
||||||
|
t = p->head;
|
||||||
|
while (t)
|
||||||
|
{
|
||||||
|
m = t->next;
|
||||||
|
free(t);
|
||||||
|
t = m;
|
||||||
|
}
|
||||||
|
p->head = 0;
|
||||||
|
p->tail = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AMX_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined JIT
|
#if defined JIT
|
||||||
#if defined WIN32 || defined __cplusplus
|
#if defined WIN32 || defined __cplusplus
|
||||||
extern "C" int AMXAPI getMaxCodeSize(void);
|
extern "C" int AMXAPI getMaxCodeSize(void);
|
||||||
@ -536,6 +594,20 @@ static int amx_BrowseRelocate(AMX *amx)
|
|||||||
|
|
||||||
amx->flags=AMX_FLAG_BROWSE;
|
amx->flags=AMX_FLAG_BROWSE;
|
||||||
|
|
||||||
|
/* check the debug hook */
|
||||||
|
if ((hdr->flags & AMX_FLAG_LINEOPS) && !(hdr->flags & AMX_FLAG_TRACED))
|
||||||
|
{
|
||||||
|
amx->userdata[0] = (AMX_DBG *)malloc(sizeof(AMX_DBG));
|
||||||
|
amx->userdata[1] = (void *)amx_DebugCall;
|
||||||
|
memset(amx->userdata[0], 0, sizeof(AMX_DBG));
|
||||||
|
amx->flags |= AMX_FLAG_LINEOPS;
|
||||||
|
amx->flags |= AMX_FLAG_TRACED;
|
||||||
|
amx->flags |= AMX_FLAG_DEBUG;
|
||||||
|
} else {
|
||||||
|
amx->userdata[0] = 0;
|
||||||
|
amx->userdata[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined __GNUC__ || defined ASM32 || defined JIT && !defined __64BIT__
|
#if defined __GNUC__ || defined ASM32 || defined JIT && !defined __64BIT__
|
||||||
amx_Exec(amx, (cell*)&opcode_list, 0, 0);
|
amx_Exec(amx, (cell*)&opcode_list, 0, 0);
|
||||||
#if !defined JIT
|
#if !defined JIT
|
||||||
@ -715,6 +787,20 @@ static int amx_BrowseRelocate(AMX *amx)
|
|||||||
DBGPARAM(amx->curfile);
|
DBGPARAM(amx->curfile);
|
||||||
amx->dbgname=(char *)(code+(int)cip);
|
amx->dbgname=(char *)(code+(int)cip);
|
||||||
cip+=num - sizeof(cell);
|
cip+=num - sizeof(cell);
|
||||||
|
if (!(hdr->flags & AMX_FLAG_TRACED) && amx->userdata[0] != NULL)
|
||||||
|
{
|
||||||
|
AMX_DBG *pDbg = (AMX_DBG *)(amx->userdata[0]);
|
||||||
|
if (pDbg->numFiles == 0)
|
||||||
|
{
|
||||||
|
pDbg->numFiles++;
|
||||||
|
pDbg->files = (char **)malloc(sizeof(char *) * 1);
|
||||||
|
} else {
|
||||||
|
pDbg->numFiles++;
|
||||||
|
pDbg->files = (char **)realloc(pDbg->files, pDbg->numFiles * sizeof(char*));
|
||||||
|
}
|
||||||
|
pDbg->files[pDbg->numFiles-1] = (char *)malloc((sizeof(char) * strlen(amx->dbgname)) + 1);
|
||||||
|
strcpy(pDbg->files[pDbg->numFiles-1], amx->dbgname);
|
||||||
|
} /* if */
|
||||||
break;
|
break;
|
||||||
} /* case */
|
} /* case */
|
||||||
case OP_LINE:
|
case OP_LINE:
|
||||||
@ -765,6 +851,7 @@ static int amx_BrowseRelocate(AMX *amx)
|
|||||||
|
|
||||||
amx->flags &= ~AMX_FLAG_BROWSE;
|
amx->flags &= ~AMX_FLAG_BROWSE;
|
||||||
amx->flags |= AMX_FLAG_RELOC;
|
amx->flags |= AMX_FLAG_RELOC;
|
||||||
|
amx->flags |= AMX_FLAG_TRACED;
|
||||||
return AMX_ERR_NONE;
|
return AMX_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1721,6 +1808,8 @@ static void *amx_opcodelist_nodebug[] = {
|
|||||||
ucell codesize;
|
ucell codesize;
|
||||||
int num,i;
|
int num,i;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
AMX_DEBUGCALL tracer = 0;
|
||||||
|
AMX_DBG *pdbg = 0;
|
||||||
|
|
||||||
/* HACK: return label table (for amx_BrowseRelocate) if amx structure
|
/* HACK: return label table (for amx_BrowseRelocate) if amx structure
|
||||||
* has the AMX_FLAG_BROWSE flag set.
|
* has the AMX_FLAG_BROWSE flag set.
|
||||||
@ -1824,6 +1913,20 @@ static void *amx_opcodelist_nodebug[] = {
|
|||||||
/* check stack/heap before starting to run */
|
/* check stack/heap before starting to run */
|
||||||
CHKMARGIN();
|
CHKMARGIN();
|
||||||
|
|
||||||
|
if ((amx->flags & AMX_FLAG_DEBUG) && (amx->flags & AMX_FLAG_LINEOPS))
|
||||||
|
{
|
||||||
|
if (amx->userdata[0])
|
||||||
|
{
|
||||||
|
tracer = (AMX_DEBUGCALL)amx->userdata[1];
|
||||||
|
pdbg = (AMX_DBG *)(amx->userdata[0]);
|
||||||
|
if (tracer)
|
||||||
|
{
|
||||||
|
//as a precaution, clear the call stack
|
||||||
|
(tracer)(amx, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* start running */
|
/* start running */
|
||||||
NEXT(cip);
|
NEXT(cip);
|
||||||
|
|
||||||
@ -2108,6 +2211,10 @@ static void *amx_opcodelist_nodebug[] = {
|
|||||||
CHKMARGIN();
|
CHKMARGIN();
|
||||||
NEXT(cip);
|
NEXT(cip);
|
||||||
op_ret:
|
op_ret:
|
||||||
|
if (tracer)
|
||||||
|
{
|
||||||
|
(tracer)(amx, 1);
|
||||||
|
}
|
||||||
POP(frm);
|
POP(frm);
|
||||||
POP(offs);
|
POP(offs);
|
||||||
/* verify the return address */
|
/* verify the return address */
|
||||||
@ -2116,6 +2223,10 @@ static void *amx_opcodelist_nodebug[] = {
|
|||||||
cip=(cell *)(code+(int)offs);
|
cip=(cell *)(code+(int)offs);
|
||||||
NEXT(cip);
|
NEXT(cip);
|
||||||
op_ret_nodebug:
|
op_ret_nodebug:
|
||||||
|
if (tracer)
|
||||||
|
{
|
||||||
|
(tracer)(amx, 1);
|
||||||
|
}
|
||||||
POP(frm);
|
POP(frm);
|
||||||
POP(offs);
|
POP(offs);
|
||||||
/* verify the return address */
|
/* verify the return address */
|
||||||
@ -2124,6 +2235,10 @@ static void *amx_opcodelist_nodebug[] = {
|
|||||||
cip=(cell *)(code+(int)offs);
|
cip=(cell *)(code+(int)offs);
|
||||||
NEXT(cip);
|
NEXT(cip);
|
||||||
op_retn:
|
op_retn:
|
||||||
|
if (tracer)
|
||||||
|
{
|
||||||
|
(tracer)(amx, 1);
|
||||||
|
}
|
||||||
POP(frm);
|
POP(frm);
|
||||||
POP(offs);
|
POP(offs);
|
||||||
/* verify the return address */
|
/* verify the return address */
|
||||||
@ -2133,6 +2248,10 @@ static void *amx_opcodelist_nodebug[] = {
|
|||||||
stk+= *(cell *)(data+(int)stk) + sizeof(cell); /* remove parameters from the stack */
|
stk+= *(cell *)(data+(int)stk) + sizeof(cell); /* remove parameters from the stack */
|
||||||
NEXT(cip);
|
NEXT(cip);
|
||||||
op_retn_nodebug:
|
op_retn_nodebug:
|
||||||
|
if (tracer)
|
||||||
|
{
|
||||||
|
(tracer)(amx, 1);
|
||||||
|
}
|
||||||
POP(frm);
|
POP(frm);
|
||||||
POP(offs);
|
POP(offs);
|
||||||
/* verify the return address */
|
/* verify the return address */
|
||||||
@ -2142,18 +2261,34 @@ static void *amx_opcodelist_nodebug[] = {
|
|||||||
stk+= *(cell *)(data+(int)stk) + sizeof(cell); /* remove parameters from the stack */
|
stk+= *(cell *)(data+(int)stk) + sizeof(cell); /* remove parameters from the stack */
|
||||||
NEXT(cip);
|
NEXT(cip);
|
||||||
op_call:
|
op_call:
|
||||||
|
if (tracer)
|
||||||
|
{
|
||||||
|
(tracer)(amx, 2);
|
||||||
|
}
|
||||||
PUSH(((unsigned char *)cip-code)+sizeof(cell));/* push address behind instruction */
|
PUSH(((unsigned char *)cip-code)+sizeof(cell));/* push address behind instruction */
|
||||||
cip=JUMPABS(code, cip); /* jump to the address */
|
cip=JUMPABS(code, cip); /* jump to the address */
|
||||||
NEXT(cip);
|
NEXT(cip);
|
||||||
op_call_nodebug:
|
op_call_nodebug:
|
||||||
|
if (tracer)
|
||||||
|
{
|
||||||
|
(tracer)(amx, 2);
|
||||||
|
}
|
||||||
PUSH(((unsigned char *)cip-code)+sizeof(cell));/* push address behind instruction */
|
PUSH(((unsigned char *)cip-code)+sizeof(cell));/* push address behind instruction */
|
||||||
cip=JUMPABS(code, cip); /* jump to the address */
|
cip=JUMPABS(code, cip); /* jump to the address */
|
||||||
NEXT(cip);
|
NEXT(cip);
|
||||||
op_call_pri:
|
op_call_pri:
|
||||||
|
if (tracer)
|
||||||
|
{
|
||||||
|
(tracer)(amx, 2);
|
||||||
|
}
|
||||||
PUSH((unsigned char *)cip-code);
|
PUSH((unsigned char *)cip-code);
|
||||||
cip=(cell *)(code+(int)pri);
|
cip=(cell *)(code+(int)pri);
|
||||||
NEXT(cip);
|
NEXT(cip);
|
||||||
op_call_pri_nodebug:
|
op_call_pri_nodebug:
|
||||||
|
if (tracer)
|
||||||
|
{
|
||||||
|
(tracer)(amx, 2);
|
||||||
|
}
|
||||||
PUSH((unsigned char *)cip-code);
|
PUSH((unsigned char *)cip-code);
|
||||||
cip=(cell *)(code+(int)pri);
|
cip=(cell *)(code+(int)pri);
|
||||||
NEXT(cip);
|
NEXT(cip);
|
||||||
@ -2697,6 +2832,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index, int numparams, ...)
|
|||||||
cell offs;
|
cell offs;
|
||||||
int num;
|
int num;
|
||||||
#endif
|
#endif
|
||||||
|
AMX_DEBUGCALL tracer = 0;
|
||||||
|
AMX_DBG *pdbg = 0;
|
||||||
|
|
||||||
#if defined ASM32 || defined JIT
|
#if defined ASM32 || defined JIT
|
||||||
/* HACK: return label table (for amx_BrowseRelocate) if amx structure
|
/* HACK: return label table (for amx_BrowseRelocate) if amx structure
|
||||||
@ -2718,6 +2855,16 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index, int numparams, ...)
|
|||||||
} /* if */
|
} /* if */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
if ((amx->flags & AMX_FLAG_DEBUG) && (amx->flags & AMX_FLAG_LINEOPS))
|
||||||
|
{
|
||||||
|
if (amx->userdata[0])
|
||||||
|
{
|
||||||
|
tracer = (AMX_DEBUGCALL)amx->userdata[1];
|
||||||
|
pdbg = (AMX_DBG *)(amx->userdata[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (amx->callback==NULL)
|
if (amx->callback==NULL)
|
||||||
return AMX_ERR_CALLBACK;
|
return AMX_ERR_CALLBACK;
|
||||||
i=amx_Register(amx,NULL,0); /* verify that all natives are registered */
|
i=amx_Register(amx,NULL,0); /* verify that all natives are registered */
|
||||||
@ -3134,10 +3281,18 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index, int numparams, ...)
|
|||||||
cip=(cell *)(code+(int)offs);
|
cip=(cell *)(code+(int)offs);
|
||||||
stk+= *(cell *)(data+(int)stk) + sizeof(cell); /* remove parameters from the stack */
|
stk+= *(cell *)(data+(int)stk) + sizeof(cell); /* remove parameters from the stack */
|
||||||
amx->stk=stk;
|
amx->stk=stk;
|
||||||
|
if (tracer)
|
||||||
|
{
|
||||||
|
(tracer)(amx, 1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OP_CALL:
|
case OP_CALL:
|
||||||
PUSH(((unsigned char *)cip-code)+sizeof(cell));/* skip address */
|
PUSH(((unsigned char *)cip-code)+sizeof(cell));/* skip address */
|
||||||
cip=JUMPABS(code, cip); /* jump to the address */
|
cip=JUMPABS(code, cip); /* jump to the address */
|
||||||
|
if (tracer)
|
||||||
|
{
|
||||||
|
(tracer)(amx, 2);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case OP_CALL_PRI:
|
case OP_CALL_PRI:
|
||||||
PUSH((unsigned char *)cip-code);
|
PUSH((unsigned char *)cip-code);
|
||||||
|
@ -255,6 +255,7 @@ void free_amxmemory(void **ptr);
|
|||||||
// get_localinfo
|
// get_localinfo
|
||||||
const char* get_localinfo( const char* name , const char* def );
|
const char* get_localinfo( const char* name , const char* def );
|
||||||
cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params);
|
cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params);
|
||||||
|
void LogError(AMX *amx, int err, const char *fmt, ...);
|
||||||
|
|
||||||
enum ModuleCallReason
|
enum ModuleCallReason
|
||||||
{
|
{
|
||||||
|
@ -106,7 +106,7 @@ int g_srvindex;
|
|||||||
|
|
||||||
cvar_t init_amxmodx_version = {"amxmodx_version", "", FCVAR_SERVER | FCVAR_SPONLY};
|
cvar_t init_amxmodx_version = {"amxmodx_version", "", FCVAR_SERVER | FCVAR_SPONLY};
|
||||||
cvar_t init_amxmodx_modules = {"amxmodx_modules", "", FCVAR_SPONLY};
|
cvar_t init_amxmodx_modules = {"amxmodx_modules", "", FCVAR_SPONLY};
|
||||||
cvar_t init_amxmodx_debug = {"amx_debug", "", FCVAR_SPONLY};
|
cvar_t init_amxmodx_debug = {"amx_debug", "1", FCVAR_SPONLY};
|
||||||
cvar_t* amxmodx_version = NULL;
|
cvar_t* amxmodx_version = NULL;
|
||||||
cvar_t* amxmodx_modules = NULL;
|
cvar_t* amxmodx_modules = NULL;
|
||||||
cvar_t* hostname = NULL;
|
cvar_t* hostname = NULL;
|
||||||
|
@ -153,7 +153,6 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
|
|||||||
//automatic debug mode
|
//automatic debug mode
|
||||||
hdr->flags |= AMX_FLAG_LINEOPS;
|
hdr->flags |= AMX_FLAG_LINEOPS;
|
||||||
hdr->flags |= AMX_FLAG_DEBUG;
|
hdr->flags |= AMX_FLAG_DEBUG;
|
||||||
printf("init flags:= %d\n", hdr->flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
@ -1110,6 +1109,117 @@ void MNF_Log(const char *fmt, ...)
|
|||||||
AMXXLOG_Log("%s", msg);
|
AMXXLOG_Log("%s", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//by BAILOPAN
|
||||||
|
// generic error printing routine
|
||||||
|
void GenericError(AMX *amx, int err, int line, char buf[], const char *file)
|
||||||
|
{
|
||||||
|
static const char *amx_errs[] =
|
||||||
|
{
|
||||||
|
NULL,
|
||||||
|
"forced exit",
|
||||||
|
"assertion failed",
|
||||||
|
"stack error",
|
||||||
|
"index out of bounds",
|
||||||
|
"memory access",
|
||||||
|
"invalid instruction",
|
||||||
|
"stack low",
|
||||||
|
"heap low",
|
||||||
|
"callback",
|
||||||
|
"native",
|
||||||
|
"divide",
|
||||||
|
"sleep",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
"out of memory", //16
|
||||||
|
"bad file format",
|
||||||
|
"bad file version",
|
||||||
|
"function not found",
|
||||||
|
"invalid entry point",
|
||||||
|
"debugger cannot run",
|
||||||
|
"plugin un or re-initialized",
|
||||||
|
"userdata table full",
|
||||||
|
"JIT failed to initialize",
|
||||||
|
"parameter error",
|
||||||
|
"domain error",
|
||||||
|
};
|
||||||
|
//does this plugin have line ops?
|
||||||
|
const char *geterr = NULL;
|
||||||
|
if (err > 26 || err < 0)
|
||||||
|
geterr = NULL;
|
||||||
|
else
|
||||||
|
geterr = amx_errs[err];
|
||||||
|
if (!(amx->flags & AMX_FLAG_LINEOPS))
|
||||||
|
{
|
||||||
|
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 {
|
||||||
|
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
|
||||||
|
// debugger engine front end
|
||||||
|
void LogError(AMX *amx, int err, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
//does this plugin have debug info?
|
||||||
|
va_list arg;
|
||||||
|
AMX_DBG *dbg = (AMX_DBG *)(amx->userdata[0]);
|
||||||
|
static char buf[1024];
|
||||||
|
static char vbuf[1024];
|
||||||
|
*buf = 0;
|
||||||
|
*vbuf = 0;
|
||||||
|
|
||||||
|
va_start(arg, fmt);
|
||||||
|
vsprintf(vbuf, fmt, arg);
|
||||||
|
va_end(arg);
|
||||||
|
|
||||||
|
if (!dbg || !(dbg->tail))
|
||||||
|
{
|
||||||
|
GenericError(amx, err, amx->curline, buf, NULL);
|
||||||
|
AMXXLOG_Log("[AMXX] %s %s", buf, vbuf);
|
||||||
|
} else {
|
||||||
|
AMX_TRACE *t = dbg->tail;
|
||||||
|
AMX_DEBUGCALL tracer = (AMX_DEBUGCALL)(amx->userdata[1]);
|
||||||
|
//actuall
|
||||||
|
cell line = amx->curline;
|
||||||
|
cell file = amx->curfile;
|
||||||
|
int i = 0;
|
||||||
|
if (file >= dbg->numFiles || file < 0)
|
||||||
|
{
|
||||||
|
GenericError(amx, err, line, buf, NULL);
|
||||||
|
} else {
|
||||||
|
GenericError(amx, err, line, buf, dbg->files[file]);
|
||||||
|
}
|
||||||
|
AMXXLOG_Log("[AMXX] %s %s", buf, vbuf);
|
||||||
|
AMXXLOG_Log("[AMXX] Debug Trace =>");
|
||||||
|
//log the error right away
|
||||||
|
while (t != NULL)
|
||||||
|
{
|
||||||
|
line = t->line;
|
||||||
|
file = t->file;
|
||||||
|
if (file >= dbg->numFiles)
|
||||||
|
{
|
||||||
|
AMXXLOG_Log("[AMXX] [%d] Line %d, Plugin \"%s\"", i++, line, g_plugins.findPluginFast(amx)->getName());
|
||||||
|
} else {
|
||||||
|
AMXXLOG_Log("[AMXX] [%d] Line %d, Plugin \"%s\"", i++, line, dbg->files[file]);
|
||||||
|
}
|
||||||
|
if (tracer)
|
||||||
|
(tracer)(amx, 1); //pop
|
||||||
|
t = dbg->tail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MNF_MergeDefinitionFile(const char *file)
|
void MNF_MergeDefinitionFile(const char *file)
|
||||||
{
|
{
|
||||||
g_langMngr.MergeDefinitionFile(file);
|
g_langMngr.MergeDefinitionFile(file);
|
||||||
|
@ -283,10 +283,9 @@ void plugin_srvcmd()
|
|||||||
|
|
||||||
if ((err = amx_Exec( (*a).getPlugin()->getAMX(), &ret , (*a).getFunction()
|
if ((err = amx_Exec( (*a).getPlugin()->getAMX(), &ret , (*a).getFunction()
|
||||||
, 3 , g_srvindex , (*a).getFlags() , (*a).getId() )) != AMX_ERR_NONE)
|
, 3 , g_srvindex , (*a).getFlags() , (*a).getId() )) != AMX_ERR_NONE)
|
||||||
|
{
|
||||||
AMXXLOG_Log("[AMXX] Run time error %d on line %ld (plugin \"%s\")",
|
LogError((*a).getPlugin()->getAMX(), err, "");
|
||||||
err,(*a).getPlugin()->getAMX()->curline,(*a).getPlugin()->getName());
|
}
|
||||||
|
|
||||||
if ( ret ) break;
|
if ( ret ) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user