diff --git a/core/logic/DebugReporter.cpp b/core/logic/DebugReporter.cpp index fd34b14b..16652137 100644 --- a/core/logic/DebugReporter.cpp +++ b/core/logic/DebugReporter.cpp @@ -29,11 +29,11 @@ * Version: $Id$ */ +#include #include #include #include "DebugReporter.h" #include "Logger.h" -#include DebugReport g_DbgReporter; @@ -194,35 +194,53 @@ void DebugReport::ReportError(const IErrorReport &report, IFrameIterator &iter) g_Logger.LogError("[SM] Blaming: %s", blame); } - if (!iter.Done()) + ke::Vector arr = GetStackTrace(&iter); + for (size_t i = 0; i < arr.length(); i++) { - g_Logger.LogError("[SM] Call stack trace:"); + g_Logger.LogError("%s", arr[i].chars()); + } +} - for (int index = 0; !iter.Done(); iter.Next(), index++) +ke::Vector DebugReport::GetStackTrace(IFrameIterator *iter) +{ + char temp[3072]; + ke::Vector trace; + iter->Reset(); + + if (!iter->Done()) + { + trace.append("[SM] Call stack trace:"); + + for (int index = 0; !iter->Done(); iter->Next(), index++) { - const char *fn = iter.FunctionName(); + const char *fn = iter->FunctionName(); if (!fn) { fn = ""; } - if (iter.IsNativeFrame()) + if (iter->IsNativeFrame()) { - g_Logger.LogError("[SM] [%d] %s", index, fn); + g_pSM->Format(temp, sizeof(temp), "[SM] [%d] %s", index, fn); + trace.append(temp); continue; } - if (iter.IsScriptedFrame()) + if (iter->IsScriptedFrame()) { - const char *file = iter.FilePath(); + const char *file = iter->FilePath(); if (!file) { file = ""; } - g_Logger.LogError("[SM] [%d] Line %d, %s::%s", + g_pSM->Format(temp, sizeof(temp), "[SM] [%d] Line %d, %s::%s", index, - iter.LineNumber(), + iter->LineNumber(), file, fn); + + trace.append(temp); } } } + + return trace; } diff --git a/core/logic/DebugReporter.h b/core/logic/DebugReporter.h index e43b3a08..cf151665 100644 --- a/core/logic/DebugReporter.h +++ b/core/logic/DebugReporter.h @@ -34,6 +34,8 @@ #include "sp_vm_api.h" #include "common_logic.h" +#include +#include class DebugReport : public SMGlobalClass, @@ -48,6 +50,7 @@ public: void GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...); void GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err, const char *message, va_list ap); void GenerateCodeError(IPluginContext *ctx, uint32_t code_addr, int err, const char *message, ...); + ke::Vector GetStackTrace(IFrameIterator *iter); private: int _GetPluginIndex(IPluginContext *ctx); }; diff --git a/core/logic/smn_core.cpp b/core/logic/smn_core.cpp index 214111e4..58c16e0d 100644 --- a/core/logic/smn_core.cpp +++ b/core/logic/smn_core.cpp @@ -937,6 +937,27 @@ static cell_t FrameIterator_GetFilePath(IPluginContext *pContext, const cell_t * return 0; } +static cell_t LogStackTrace(IPluginContext *pContext, const cell_t *params) +{ + char buffer[512]; + + g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 1); + + IFrameIterator *it = pContext->CreateFrameIterator(); + ke::Vector arr = g_DbgReporter.GetStackTrace(it); + pContext->DestroyFrameIterator(it); + + IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext()); + + g_Logger.LogError("[SM] Stack trace requested: %s", buffer); + g_Logger.LogError("[SM] Called from: %s", pPlugin->GetFilename()); + for (size_t i = 0; i < arr.length(); i) + { + g_Logger.LogError("%s", arr[i].chars()); + } + return 0; +} + REGISTER_NATIVES(coreNatives) { {"ThrowError", ThrowError}, @@ -967,6 +988,7 @@ REGISTER_NATIVES(coreNatives) {"StoreToAddress", StoreToAddress}, {"IsNullVector", IsNullVector}, {"IsNullString", IsNullString}, + {"LogStackTrace", LogStackTrace}, {"FrameIterator.FrameIterator", FrameIterator_Create}, {"FrameIterator.Next", FrameIterator_Next},