From 0891e2b30a98ceb6626a90120b2a05f7a0284004 Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Tue, 12 Mar 2013 01:33:45 -0300 Subject: [PATCH] Add C++ traceback to errors --- modules/client_terminal/terminal.lua | 1 + src/framework/core/logger.cpp | 11 +++++---- src/framework/platform/platform.h | 1 + src/framework/platform/unixplatform.cpp | 31 ++++++++++++++++++++++++ src/framework/platform/win32platform.cpp | 9 +++++++ 5 files changed, 48 insertions(+), 5 deletions(-) diff --git a/modules/client_terminal/terminal.lua b/modules/client_terminal/terminal.lua index 4867f7ba..e32e78b5 100644 --- a/modules/client_terminal/terminal.lua +++ b/modules/client_terminal/terminal.lua @@ -285,6 +285,7 @@ function addLine(text, color) flushEvent = scheduleEvent(flushLines, 10) end + text = string.gsub(text, '\t', ' ') table.insert(cachedLines, {text=text, color=color}) end diff --git a/src/framework/core/logger.cpp b/src/framework/core/logger.cpp index f67a6cc4..51e10f02 100644 --- a/src/framework/core/logger.cpp +++ b/src/framework/core/logger.cpp @@ -28,6 +28,7 @@ #ifdef FW_GRAPHICS #include +#include #include #endif @@ -104,16 +105,16 @@ void Logger::logFunc(Fw::LogLevel level, const std::string& message, std::string prettyFunction = prettyFunction.substr(prettyFunction.find_last_of(' ') + 1); - std::string out = message; + std::stringstream ss; + ss << message; if(!prettyFunction.empty()) { if(g_lua.isInCppCallback()) - out = g_lua.traceback(out, 1); - else - out += "\nat:\t[C++]: " + prettyFunction; + ss << g_lua.traceback("", 1); + ss << g_platform.traceback(prettyFunction, 1, 8); } - log(level, out); + log(level, ss.str()); } void Logger::fireOldMessages() diff --git a/src/framework/platform/platform.h b/src/framework/platform/platform.h index a97a99aa..066d4c31 100644 --- a/src/framework/platform/platform.h +++ b/src/framework/platform/platform.h @@ -45,6 +45,7 @@ public: std::string getCPUName(); double getTotalSystemMemory(); std::string getOSName(); + std::string traceback(const std::string& where, int level = 1, int maxDepth = 32); }; extern Platform g_platform; diff --git a/src/framework/platform/unixplatform.cpp b/src/framework/platform/unixplatform.cpp index 29fc9565..d544aaa3 100644 --- a/src/framework/platform/unixplatform.cpp +++ b/src/framework/platform/unixplatform.cpp @@ -29,6 +29,7 @@ #include #include +#include void Platform::processArgs(std::vector& args) { @@ -168,5 +169,35 @@ std::string Platform::getOSName() return std::string(); } +std::string Platform::traceback(const std::string& where, int level, int maxDepth) +{ + std::stringstream ss; + + ss << "\nC++ stack traceback:"; + if(!where.empty()) + ss << "\n\t[C++]: " << where; + + void* buffer[maxDepth + level + 1]; + int numLevels = backtrace(buffer, maxDepth + level + 1); + char **tracebackBuffer = backtrace_symbols(buffer, numLevels); + if(tracebackBuffer) { + for(int i = 1 + level; i < numLevels; i++) { + std::string line = tracebackBuffer[i]; + if(line.find("__libc_start_main") != std::string::npos) + break; + std::size_t demanglePos = line.find("(_Z"); + if(demanglePos != std::string::npos) { + demanglePos++; + int len = std::min(line.find_first_of("+", demanglePos), line.find_first_of(")", demanglePos)) - demanglePos; + std::string funcName = line.substr(demanglePos, len); + line.replace(demanglePos, len, stdext::demangle_name(funcName.c_str())); + } + ss << "\n\t" << line; + } + free(tracebackBuffer); + } + + return ss.str(); +} #endif diff --git a/src/framework/platform/win32platform.cpp b/src/framework/platform/win32platform.cpp index 724a2568..849c260d 100644 --- a/src/framework/platform/win32platform.cpp +++ b/src/framework/platform/win32platform.cpp @@ -414,4 +414,13 @@ std::string Platform::getOSName() return ret; } + +std::string Platform::traceback(const std::string& where) +{ + std::stringstream ss; + ss << "\nat:"; + ss << "\n\t[C++]: " << where; + return ss.str(); +} + #endif