From 6a97d73167adcbc26960c61afc723a424846b06d Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 26 Jul 2005 21:31:21 +0000 Subject: [PATCH] Committed brand new debugger system --- amxmodx/CForward.cpp | 45 +++- amxmodx/CPlugin.cpp | 15 +- amxmodx/CPlugin.h | 4 +- amxmodx/JIT/amxjitsn.o | Bin 26528 -> 26112 bytes amxmodx/JIT/amxjitsn.obj | Bin 27061 -> 26592 bytes amxmodx/amx.h | 16 +- amxmodx/amxmodx.cpp | 2 +- amxmodx/modules.cpp | 374 +++++++++++++++++++++++++-------- amxmodx/msvc/amxmodx_mm.vcproj | 10 +- 9 files changed, 363 insertions(+), 103 deletions(-) diff --git a/amxmodx/CForward.cpp b/amxmodx/CForward.cpp index 6641d4ff..50ba729b 100755 --- a/amxmodx/CForward.cpp +++ b/amxmodx/CForward.cpp @@ -31,6 +31,8 @@ #include "amxmodx.h" +void AMXAPI amxx_InvalidateTrace(AMX *amx); + CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes) { m_FuncName = name; @@ -70,6 +72,11 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays) { 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 int i, ax=0; 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) { cell *tmp; - amx_Allot(iter->pPlugin->getAMX(), preparedArrays[params[i]].size, + amx_Allot(amx, preparedArrays[params[i]].size, &realParams[i], &tmp); physAddrs[i] = tmp; 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! for (i=m_NumParams-1; i>=0; i--) { - amx_Push(iter->pPlugin->getAMX(), realParams[i]); + amx_Push(amx, realParams[i]); } // exec 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 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 for (i = 0; i < m_NumParams; ++i) @@ -211,6 +229,10 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays) if (!pPlugin->isExecutable(m_Func)) return 0; + AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(m_Amx->userdata[2]); + if (pInfo) + pInfo->error = AMX_ERR_NONE; + // handle strings & arrays int i; for (i = 0; i < m_NumParams; ++i) @@ -251,10 +273,19 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays) // exec cell retVal; int err = amx_Exec(m_Amx, &retVal, m_Func); - - // log runtime error, if any 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 for (i = 0; i < m_NumParams; ++i) diff --git a/amxmodx/CPlugin.cpp b/amxmodx/CPlugin.cpp index b6c10710..37a4693a 100755 --- a/amxmodx/CPlugin.cpp +++ b/amxmodx/CPlugin.cpp @@ -137,7 +137,7 @@ const char* CPluginMngr::CPlugin::getStatus() const { switch(status){ case ps_running: { - if (getAMX()->flags & AMX_FLAG_DEBUG) + if (m_Debug) { return "debug"; } else { @@ -172,8 +172,17 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p,const char* n, char* e, int d paused_fun = 0; next = 0; id = i; - m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause"); - m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause"); + if (status == ps_running) + { + 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( ) diff --git a/amxmodx/CPlugin.h b/amxmodx/CPlugin.h index 55efb3e2..6411ebae 100755 --- a/amxmodx/CPlugin.h +++ b/amxmodx/CPlugin.h @@ -42,7 +42,7 @@ enum { ps_paused, ps_running, ps_stopped, - ps_locked + ps_locked, }; class CPluginMngr @@ -72,6 +72,7 @@ public: int id; CPlugin(int i , const char* p,const char* n, char* e, int d); ~CPlugin( ); + bool m_Debug; public: @@ -98,6 +99,7 @@ public: void unpauseFunction( int id ); void setStatus( int a ); const char* getStatus() const; + inline bool isDebug() const { return m_Debug; } }; private: diff --git a/amxmodx/JIT/amxjitsn.o b/amxmodx/JIT/amxjitsn.o index 541585fb27e1596dd605c630ea9d1cad00b07bcf..89ffa4928e0b7f3a224e0a64f03328df0014b067 100755 GIT binary patch literal 26112 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 b0i|`Iv;mYhfzlRG+6GEHKxr2!?E$3$(ioVG literal 26528 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 diff --git a/amxmodx/JIT/amxjitsn.obj b/amxmodx/JIT/amxjitsn.obj index 92fcd2402206aaaa4f2533def7cb40400867baf0..53a7237feac0b94081e6cb8abd4759324b1df70b 100755 GIT binary patch literal 26592 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 literal 27061 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 diff --git a/amxmodx/amx.h b/amxmodx/amx.h index 1264528e..4160e20d 100755 --- a/amxmodx/amx.h +++ b/amxmodx/amx.h @@ -334,10 +334,22 @@ enum { #define AMX_COMPACTMARGIN 64 #endif +struct amx_trace +{ + cell frm; + amx_trace *prev; + amx_trace *next; + bool used; +}; + struct AMX_DBGINFO { - void *pDebug; //Pointer to debug data - int error; //non-amx_Exec() error setting + void *pDebug; //Pointer to debug data + 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 diff --git a/amxmodx/amxmodx.cpp b/amxmodx/amxmodx.cpp index 33faf851..67a8ab72 100755 --- a/amxmodx/amxmodx.cpp +++ b/amxmodx/amxmodx.cpp @@ -958,7 +958,7 @@ static cell AMX_NATIVE_CALL get_concmd(AMX *amx, cell *params) /* 7 param */ else // -1 parameter - all commands 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; set_amxstring(amx,params[2], cmd->getCmdLine() ,params[3]); diff --git a/amxmodx/modules.cpp b/amxmodx/modules.cpp index 05a16f1c..20997e1f 100755 --- a/amxmodx/modules.cpp +++ b/amxmodx/modules.cpp @@ -38,6 +38,7 @@ #include "osdep.h" // sleep, etc #include "CFile.h" #include "amxxfile.h" +#include "amxdbg.h" CList g_modules; CList g_loadedscripts; @@ -88,10 +89,170 @@ void* alloc_amxmemory(void** p, int size) void free_amxmemory(void **ptr) { - delete[] *ptr; + delete[] (unsigned char *)(*ptr); *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) { *error = 0; @@ -155,12 +316,36 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64 int err; memset(amx, 0, sizeof(*amx)); + bool will_be_debugged = false; + + tagAMX_DBG *pDbg = NULL; 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 { #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 (pDbg) + { + dbg_FreeInfo(pDbg); + delete pDbg; + } sprintf(error,"Load error %d (invalid file format or version)", err); 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 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) { + amxx_FreeDebug(amx); CList::iterator a = g_loadedscripts.find( amx ); if ( a ) a.remove(); char *prg = (char *)*program; @@ -363,7 +569,6 @@ int unload_amxscript(AMX* amx, void** program) return AMX_ERR_NONE; } - AMX* get_amxscript(int id , void** code, const char** filename) { CList::iterator a = g_loadedscripts.begin(); @@ -1180,9 +1385,27 @@ void MNF_Log(const char *fmt, ...) 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 // 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[] = { @@ -1199,7 +1422,7 @@ void GenericError(AMX *amx, int err, int line, char buf[], const char *file) "native", "divide", "sleep", - NULL, + "invalid access state", NULL, NULL, "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? const char *geterr = NULL; if (err > 26 || err < 0) - geterr = NULL; + geterr = ""; else geterr = amx_errs[err]; - if (!(amx->flags & AMX_FLAG_DEBUG)) - { - 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())); - } - } - } + return geterr; } //by BAILOPAN @@ -1250,71 +1452,69 @@ 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]); + AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]); + CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx); static char buf[1024]; static char vbuf[1024]; *buf = 0; *vbuf = 0; - va_start(arg, fmt); - vsprintf(vbuf, fmt, arg); - va_end(arg); -#if 0 - if (!dbg || !(dbg->tail)) + if (fmt[0] == '\0') { - if (dbg && amx->curfile < dbg->numFiles && amx->curfile >= 0) - { - 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)."); - } + _snprintf(vbuf, sizeof(vbuf)-1, "Run time error %d (%s)", err, GenericError(err)); } 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; - 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; - } + va_start(arg, fmt); + vsprintf(vbuf, fmt, arg); + va_end(arg); } -#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(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) diff --git a/amxmodx/msvc/amxmodx_mm.vcproj b/amxmodx/msvc/amxmodx_mm.vcproj index e7a85095..da7b687f 100755 --- a/amxmodx/msvc/amxmodx_mm.vcproj +++ b/amxmodx/msvc/amxmodx_mm.vcproj @@ -442,7 +442,7 @@ InlineFunctionExpansion="1" FavorSizeOrSpeed="1" 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" RuntimeLibrary="4" EnableFunctionLevelLinking="TRUE" @@ -460,7 +460,7 @@ + + @@ -721,6 +724,9 @@ + +