diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index ffaa683ae4..9362e686ce 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -25,6 +25,7 @@ set(SRCS ActionReplay.cpp Debugger/Debugger_SymbolMap.cpp Debugger/Dump.cpp Debugger/PPCDebugInterface.cpp + Debugger/StackWalker.cpp DSP/DSPAssembler.cpp DSP/DSPDisassembler.cpp DSP/DSPAccelerator.cpp diff --git a/Source/Core/Core/Debugger/StackWalker.cpp b/Source/Core/Core/Debugger/StackWalker.cpp new file mode 100644 index 0000000000..954c706724 --- /dev/null +++ b/Source/Core/Core/Debugger/StackWalker.cpp @@ -0,0 +1,68 @@ +// Copyright 2008 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include +#include +#include + +#include "Common/CommonPaths.h" +#include "Common/FileUtil.h" +#include "Common/StringUtil.h" +#include "Core/Debugger/StackWalker.h" + + +StackWalker::StackWalker(bool log) + : _log(log) +{ +#if defined(__APPLE__) + std::string path = File::GetBundleDirectory() + "/Contents/Resources"; +#elif defined(_WIN32) + std::string path = File::GetExeDirectory(); +#else + std::string path = File::GetSysDirectory(); +#endif + + // This conversion is necessary for *reasons* + char sep = DIR_SEP_CHR; + if (path.back() != sep) { + path.push_back(sep); + } + + int timestamp = std::time(0); + + path = StringFromFormat("%s%d.txt", path.c_str(), timestamp); + + if (_log) + { + printf("%s\n", path.c_str()); + File::CreateEmptyFile(path); + log_file = File::IOFile(path, "wb"); + } +} + + +void StackWalker::OnStackFrame(const wxStackFrame& frame) +{ + const std::string head = StringFromFormat( + "Frame@ %p\n", + frame.GetAddress() + ); + + const std::string body = StringFromFormat( + "%lu %lu %s %s %s\n", + frame.GetLine(), + frame.GetLevel(), + frame.GetFileName().c_str().AsChar(), + frame.GetModule().c_str().AsChar(), + frame.GetName().c_str().AsChar() + ); + + if (_log) { + log_file.WriteBytes(head.data(), head.length()); + log_file.WriteBytes(body.data(), body.length()); + } + + // To stdout as well + printf("%s%s", head.c_str(), body.c_str()); +} \ No newline at end of file diff --git a/Source/Core/Core/Debugger/StackWalker.h b/Source/Core/Core/Debugger/StackWalker.h new file mode 100644 index 0000000000..c2e36fe5c9 --- /dev/null +++ b/Source/Core/Core/Debugger/StackWalker.h @@ -0,0 +1,25 @@ +// Copyright 2008 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include +#include + +#include "Common/FileUtil.h" + +class StackWalker : public wxStackWalker +{ + public: + StackWalker(bool); + ~StackWalker() { log_file.Close(); }; + + const File::IOFile& get_log_file() { return log_file; }; + bool will_write() {return _log; }; + + protected: + void OnStackFrame(const wxStackFrame&); + + private: + File::IOFile log_file; + bool _log; +}; diff --git a/Source/Core/DolphinWX/Main.cpp b/Source/Core/DolphinWX/Main.cpp index 0a7a4cd8b2..0b4930197c 100644 --- a/Source/Core/DolphinWX/Main.cpp +++ b/Source/Core/DolphinWX/Main.cpp @@ -38,6 +38,7 @@ #include "Core/HW/Wiimote.h" #include "Core/Host.h" #include "Core/Movie.h" +#include "Core/Debugger/StackWalker.h" #include "DolphinWX/Debugger/CodeWindow.h" #include "DolphinWX/Debugger/JitWindow.h" @@ -473,6 +474,8 @@ int DolphinApp::OnExit() void DolphinApp::OnFatalException() { + StackWalker walker (true); + walker.WalkFromException(); WiimoteReal::Shutdown(); }