Rewrite how wxStackWalker works:

* Change from fstream to wxFile.
 * Create both text-based and xml based reports (for the reporter)

Originally committed to SVN as r3499.
This commit is contained in:
Amar Takhar 2009-09-09 07:04:10 +00:00
parent 5ab1eab906
commit 0992a68488
2 changed files with 58 additions and 36 deletions

View file

@ -300,6 +300,7 @@ void AegisubApp::OnUnhandledException() {
wxMessageBox(wxString::Format(exception_message, filename.c_str()), _("Program error"), wxOK | wxICON_ERROR, NULL); wxMessageBox(wxString::Format(exception_message, filename.c_str()), _("Program error"), wxOK | wxICON_ERROR, NULL);
} }
/// @brief Called during a fatal exception. /// @brief Called during a fatal exception.
void AegisubApp::OnFatalException() { void AegisubApp::OnFatalException() {
// Current filename if any. // Current filename if any.
@ -327,54 +328,78 @@ void AegisubApp::OnFatalException() {
#if wxUSE_STACKWALKER == 1 #if wxUSE_STACKWALKER == 1
/// @brief Called at the start of walking the stack.
/// @param cause cause of the crash.
///
StackWalker::StackWalker(wxString cause) {
wxFileName report_dir("");
report_dir.SetPath(StandardPaths::DecodePath(_T("?user/reporter")));
if (!report_dir.DirExists()) report_dir.Mkdir();
crash_text = new wxFile(StandardPaths::DecodePath("?user/crashlog.txt"), wxFile::write_append);
crash_xml = new wxFile(StandardPaths::DecodePath("?user/reporter/crash.xml"), wxFile::write);
if ((crash_text->IsOpened()) && (crash_xml->IsOpened())) {
wxDateTime time = wxDateTime::Now();
crash_text->Write(wxString::Format("--- %s ------------------\n", time.FormatISOCombined()));
crash_text->Write(wxString::Format("VER - %s\n", GetAegisubLongVersionString()));
crash_text->Write(wxString::Format("FTL - Begining stack dump for \"%s\":\n", cause));
crash_xml->Write( "<crash>\n");
crash_xml->Write( " <info>\n");
crash_xml->Write(wxString::Format(" <cause>%s</cause>\n", cause));
crash_xml->Write(wxString::Format(" <time>%s</time>\n", time.FormatISOCombined()));
crash_xml->Write(wxString::Format(" <version>%s</version>\n", GetAegisubLongVersionString()));
crash_xml->Write( " </info>\n");
crash_xml->Write( " <trace>\n");
}
}
/// @brief Callback to format a single frame /// @brief Callback to format a single frame
/// @param frame frame to parse. /// @param frame frame to parse.
/// ///
void StackWalker::OnStackFrame(const wxStackFrame &frame) { void StackWalker::OnStackFrame(const wxStackFrame &frame) {
wxString dst = wxString::Format(_T("%03i - 0x%08X: "),frame.GetLevel(),frame.GetAddress()) + frame.GetName();
if (frame.HasSourceLocation()) dst += _T(" on ") + frame.GetFileName() + wxString::Format(_T(":%i"),frame.GetLine());
if (file.is_open()) {
file << dst.mb_str() << std::endl;
}
else wxLogMessage(dst);
}
if ((crash_text->IsOpened()) && (crash_xml->IsOpened())) {
/// @brief Called at the start of walking the stack. wxString dst = wxString::Format("%03i - 0x%08X: ",frame.GetLevel(),frame.GetAddress()) + frame.GetName();
/// @param cause cause of the crash. if (frame.HasSourceLocation())
/// dst = wxString::Format("%s on %s:%d", dst, frame.GetFileName(), frame.GetLine());
StackWalker::StackWalker(wxString cause) {
file.open(wxString(StandardPaths::DecodePath(_T("?user/crashlog.txt"))).mb_str(),std::ios::out | std::ios::app); crash_text->Write(wxString::Format("%s\n", dst));
if (file.is_open()) {
wxDateTime time = wxDateTime::Now(); crash_xml->Write(wxString::Format(" <frame id='%i' loc='%X'>\n", frame.GetLevel(), frame.GetAddress()));
wxString timeStr = _T("---") + time.FormatISODate() + _T(" ") + time.FormatISOTime() + _T("------------------"); crash_xml->Write(wxString::Format(" <name>%s</name>\n", frame.GetName()));
formatLen = timeStr.Length(); if (frame.HasSourceLocation())
file << std::endl << timeStr.mb_str(csConvLocal); crash_xml->Write(wxString::Format(" <file line='%d'>%s</file>>%s</name>\n", frame.GetLine(), frame.GetFileName()));
file << "\nVER - " << GetAegisubLongVersionString().mb_str(wxConvUTF8); crash_xml->Write(wxString::Format(" <module><![CDATA[%s]]></module>\n", frame.GetModule()));
file << "\nFTL - Begining stack dump for \"" << cause.mb_str(wxConvUTF8) <<"\":\n"; crash_xml->Write( " </frame>\n");
} }
} }
/// @brief Called at the end of walking the stack. /// @brief Called at the end of walking the stack.
StackWalker::~StackWalker() { StackWalker::~StackWalker() {
if (file.is_open()) {
char dashes[1024]; if ((crash_text->IsOpened()) && (crash_xml->IsOpened())) {
int i = 0;
for (i=0;i<formatLen;i++) dashes[i] = '-'; crash_text->Write("End of stack dump.\n");
dashes[i] = 0; crash_text->Write("----------------------------------------\n\n");
file << "End of stack dump.\n";
file << dashes; crash_text->Close();
file << "\n";
file.close(); crash_xml->Write(" </trace>\n");
crash_xml->Write("</crash>\n");
crash_xml->Close();
} }
} }
#endif #endif
/// @brief Call main loop /// @brief Call main loop
/// @return /// @return
/// ///

View file

@ -46,7 +46,7 @@
#include <wx/wxprec.h> #include <wx/wxprec.h>
#include <wx/app.h> #include <wx/app.h>
#include <wx/stackwalk.h> #include <wx/stackwalk.h>
#include <fstream> #include <wx/file.h>
#include "aegisublocale.h" #include "aegisublocale.h"
@ -131,11 +131,8 @@ DECLARE_APP(AegisubApp)
class StackWalker: public wxStackWalker { class StackWalker: public wxStackWalker {
private: private:
/// DOCME wxFile *crash_text; // FP to the crash text file.
std::ofstream file; wxFile *crash_xml; // FP to the crash xml file.
/// DOCME
int formatLen;
public: public:
StackWalker(wxString cause); StackWalker(wxString cause);