Improved Aegisub's exception handling and crash log generation.

Originally committed to SVN as r2008.
This commit is contained in:
Rodrigo Braz Monteiro 2008-03-10 06:28:21 +00:00
parent 437dbdc8f4
commit 7c505f06d4
3 changed files with 53 additions and 23 deletions

View File

@ -109,8 +109,7 @@ void FormatHandlerASS::Load(wxInputStream &file,const String encoding)
// Create and insert line // Create and insert line
SectionEntry *entry = MakeEntry(cur,curGroup,version); SectionEntry *entry = MakeEntry(cur,curGroup,version);
//if (!entry) throw Exception(Exception::Parse_Error); if (entry) section->AddEntry(entry);
section->AddEntry(entry);
} }
// Debug // Debug
@ -172,6 +171,9 @@ SectionEntry *FormatHandlerASS::MakeEntry(String data,String group,int version)
// Script info // Script info
else if (group == _T("Script Info")) { else if (group == _T("Script Info")) {
// Discard comments
if (data.Left(1) == _T(";")) return NULL;
// TODO // TODO
} }

View File

@ -44,6 +44,7 @@
#include <wx/utils.h> #include <wx/utils.h>
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
#include <wx/filefn.h> #include <wx/filefn.h>
#include <wx/datetime.h>
#include "main.h" #include "main.h"
#include "frame_main.h" #include "frame_main.h"
@ -283,7 +284,7 @@ void AegisubApp::OnFatalException() {
// Stack walk // Stack walk
#if wxUSE_STACKWALKER == 1 #if wxUSE_STACKWALKER == 1
StackWalker walker; StackWalker walker(_T("Fatal exception"));
walker.WalkFromException(); walker.WalkFromException();
#endif #endif
@ -297,25 +298,35 @@ void AegisubApp::OnFatalException() {
// Stack walker // Stack walker
#if wxUSE_STACKWALKER == 1 #if wxUSE_STACKWALKER == 1
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() + _T(" on ") + frame.GetFileName() + wxString::Format(_T(":%i"),frame.GetLine()); wxString dst = wxString::Format(_T("%03i - 0x%08X: "),frame.GetLevel(),frame.GetAddress()) + frame.GetName();
char temp[2048]; if (frame.HasSourceLocation()) dst += _T(" on ") + frame.GetFileName() + wxString::Format(_T(":%i"),frame.GetLine());
if (file.is_open()) { if (file.is_open()) {
strcpy(temp,dst.mb_str()); file << dst.mb_str() << std::endl;
file << temp << std::endl;
} }
else wxLogMessage(dst); else wxLogMessage(dst);
} }
StackWalker::StackWalker() { StackWalker::StackWalker(wxString cause) {
file.open(wxString(StandardPaths::DecodePath(_T("?user/crashlog.txt"))).mb_str(),std::ios::out | std::ios::app); file.open(wxString(StandardPaths::DecodePath(_T("?user/crashlog.txt"))).mb_str(),std::ios::out | std::ios::app);
if (file.is_open()) { if (file.is_open()) {
file << std::endl << "Begining stack dump:\n"; wxDateTime time = wxDateTime::Now();
wxString timeStr = _T("---") + time.FormatISODate() + _T(" ") + time.FormatISOTime() + _T("------------------");
formatLen = timeStr.Length();
file << std::endl << timeStr.mb_str(wxConvLocal);
file << "\nVER - " << GetAegisubLongVersionString().mb_str(wxConvUTF8);
file << "\nFTL - Begining stack dump for \"" << cause.mb_str(wxConvUTF8) <<"\":\n";
} }
} }
StackWalker::~StackWalker() { StackWalker::~StackWalker() {
if (file.is_open()) { if (file.is_open()) {
file << "End of stack dump.\n\n"; char dashes[1024];
int i = 0;
for (i=0;i<formatLen;i++) dashes[i] = '-';
dashes[i] = 0;
file << "End of stack dump.\n";
file << dashes;
file << "\n";
file.close(); file.close();
} }
} }
@ -326,25 +337,41 @@ StackWalker::~StackWalker() {
////////////////// //////////////////
// Call main loop // Call main loop
int AegisubApp::OnRun() { int AegisubApp::OnRun() {
wxString error;
// Run program
try { try {
if (m_exitOnFrameDelete == Later) m_exitOnFrameDelete = Yes; if (m_exitOnFrameDelete == Later) m_exitOnFrameDelete = Yes;
return MainLoop(); return MainLoop();
} }
catch (wxString err) { // Catch errors
wxMessageBox(err, _T("Unhandled exception"), wxOK | wxICON_ERROR, NULL); catch (wxString &err) { error = err; }
} catch (wxChar *err) { error = err; }
catch (std::exception &e) { error = wxString(_T("std::exception: ")) + wxString(e.what(),wxConvUTF8); }
catch (...) { error = _T("Program terminated in error."); }
catch (wxChar *error) { // Report errors
wxMessageBox(error, _T("Unhandled exception"), wxOK | wxICON_ERROR, NULL); if (!error.IsEmpty()) {
} std::ofstream file;
file.open(wxString(StandardPaths::DecodePath(_T("?user/crashlog.txt"))).mb_str(),std::ios::out | std::ios::app);
if (file.is_open()) {
wxDateTime time = wxDateTime::Now();
wxString timeStr = _T("---") + time.FormatISODate() + _T(" ") + time.FormatISOTime() + _T("------------------");
file << std::endl << timeStr.mb_str(wxConvLocal);
file << "\nVER - " << GetAegisubLongVersionString().mb_str(wxConvUTF8);
file << "\nEXC - Aegisub has crashed with unhandled exception \"" << error.mb_str(wxConvLocal) <<"\".\n";
int formatLen = timeStr.Length();
char dashes[1024];
int i = 0;
for (i=0;i<formatLen;i++) dashes[i] = '-';
dashes[i] = 0;
file << dashes;
file << "\n";
file.close();
}
catch (std::exception e) { OnUnhandledException();
wxMessageBox(wxString(_T("std::exception: ")) + wxString(e.what(),wxConvUTF8), _T("Unhandled exception"), wxOK | wxICON_ERROR, NULL);
}
catch (...) {
wxMessageBox(_T("Program terminated in error."), _T("Unhandled exception"), wxOK | wxICON_ERROR, NULL);
} }
ExitMainLoop(); ExitMainLoop();

View File

@ -104,9 +104,10 @@ DECLARE_APP(AegisubApp)
class StackWalker: public wxStackWalker { class StackWalker: public wxStackWalker {
private: private:
std::ofstream file; std::ofstream file;
int formatLen;
public: public:
StackWalker(); StackWalker(wxString cause);
~StackWalker(); ~StackWalker();
void OnStackFrame(const wxStackFrame& frame); void OnStackFrame(const wxStackFrame& frame);
}; };