/[pcsx2_0.9.7]/trunk/pcsx2/gui/AppAssert.cpp
ViewVC logotype

Contents of /trunk/pcsx2/gui/AppAssert.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 1 month ago) by william
File size: 4414 byte(s)
re-commit (had local access denied errors when committing)
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #include "PrecompiledHeader.h"
17 #include "App.h"
18 #include "Utilities/TlsVariable.inl"
19
20 #include <wx/stackwalk.h>
21
22 class StackDump : public wxStackWalker
23 {
24 protected:
25 FastFormatUnicode m_stackTrace;
26 wxString m_srcFuncName;
27 bool m_ignoreDone;
28 int m_skipped;
29
30 public:
31 StackDump( const FnChar_t* src_function_name )
32 {
33 if( src_function_name != NULL )
34 m_srcFuncName = fromUTF8(src_function_name);
35
36 m_ignoreDone = false;
37 m_skipped = 0;
38 }
39
40 const wxChar* GetStackTrace() const { return m_stackTrace.c_str(); }
41
42 protected:
43 virtual void OnStackFrame(const wxStackFrame& frame)
44 {
45 /*if( m_srcFuncName.IsEmpty() || m_srcFuncName == name )
46 {
47 // FIXME: This logic isn't reliable yet.
48 // It's possible for our debug information to not match the function names returned by
49 // __pxFUNCTION__ (might happen in linux a lot, and could happen in win32 due to
50 // inlining on Dev aserts). The better approach is a system the queues up all the
51 // stacktrace info in individual wxStrings, and does a two-pass check -- first pass
52 // for the function name and, if not found, a second pass that just skips the first
53 // few stack entries.
54
55 // It's important we only walk the stack once because Linux (argh, always linux!) has
56 // a really god aweful slow stack walker.
57
58 // I'm not doing it right now because I've worked on this mess enough for one week. --air
59
60 m_ignoreDone = true;
61 }
62
63 if( !m_ignoreDone )
64 {
65 m_skipped++;
66 return;
67 }*/
68
69 m_stackTrace.Write(pxsFmt( L"[%02d]", frame.GetLevel()-m_skipped));
70
71 if (!frame.GetName().IsEmpty())
72 m_stackTrace.Write(pxsFmt( L" %-44s", frame.GetName().c_str() ));
73 else
74 m_stackTrace.Write(pxsFmt( L" 0x%-42p", frame.GetAddress() ));
75
76 if( frame.HasSourceLocation() )
77 {
78 wxFileName wxfn(frame.GetFileName());
79
80 wxfn.SetVolume( wxEmptyString );
81 for( int i=0; i<2; ++i )
82 wxfn.RemoveDir(0);
83
84 m_stackTrace.Write( L" %s:%d", wxfn.GetFullPath().c_str(), frame.GetLine() );
85 }
86
87 m_stackTrace.Write(L"\n");
88 }
89 };
90
91 static wxString pxGetStackTrace( const FnChar_t* calledFrom )
92 {
93 StackDump dump( calledFrom );
94 dump.Walk( 3 );
95 return dump.GetStackTrace();
96 }
97
98 #ifdef __WXDEBUG__
99
100 // This override of wx's implementation provides thread safe assertion message reporting.
101 // If we aren't on the main gui thread then the assertion message box needs to be passed
102 // off to the main gui thread via messages.
103 void Pcsx2App::OnAssertFailure( const wxChar *file, int line, const wxChar *func, const wxChar *cond, const wxChar *msg )
104 {
105 // Re-entrant assertions are bad mojo -- trap immediately.
106 static DeclareTls(int) _reentrant_lock( 0 );
107 RecursionGuard guard( _reentrant_lock );
108 if( guard.IsReentrant() ) wxTrap();
109
110 wxCharBuffer bleh( wxString(func).ToUTF8() );
111 if( AppDoAssert( DiagnosticOrigin( file, line, bleh, cond ), msg ) )
112 {
113 wxTrap();
114 }
115 }
116
117 #endif
118
119 bool AppDoAssert( const DiagnosticOrigin& origin, const wxChar *msg )
120 {
121 // Used to allow the user to suppress future assertions during this application's session.
122 static bool disableAsserts = false;
123 if( disableAsserts ) return false;
124
125 wxString trace( pxGetStackTrace(origin.function) );
126 wxString dbgmsg( origin.ToString( msg ) );
127
128 wxMessageOutputDebug().Printf( L"%s", dbgmsg.c_str() );
129
130 Console.Error( L"%s", dbgmsg.c_str() );
131 Console.WriteLn( L"%s", trace.c_str() );
132
133 wxString windowmsg( L"Assertion failed: " );
134 if( msg != NULL )
135 windowmsg += msg;
136 else if( origin.condition != NULL )
137 windowmsg += origin.condition;
138
139 int retval = Msgbox::Assertion( windowmsg, dbgmsg + L"\nStacktrace:\n" + trace );
140
141 if( retval == wxID_YES ) return true;
142 if( retval == wxID_IGNORE ) disableAsserts = true;
143
144 return false;
145 }

  ViewVC Help
Powered by ViewVC 1.1.22