Committed brand new debugger system

This commit is contained in:
David Anderson 2005-07-26 21:31:21 +00:00
parent 586d09e533
commit 6a97d73167
9 changed files with 363 additions and 103 deletions

View File

@ -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)

View File

@ -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( )

View File

@ -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.

View File

@ -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

View File

@ -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]);

View File

@ -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)

View 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>