Files
pcsx2/pcsx2/gui/AppAssert.cpp
T
Jake.Stine c17455c702 User Interface code cleanups and bugfixes. some highlights:
* Configuration panels are all modal-less now, so that you can open the config panel and leave it open while running games.
 * Handful of thread sync improvements.
 * Fixed on-the-fly interpreter/recompiler configuration.
 * Fixed plugin hotswapping (mostly works, but still a little funny at times)
 * All new assertion dialogs and popup message handlers.
 * RecentIsoList defaults to 12 instead of 6

Dev Notes:
 * I had to create a new set of assertion functions called pxAssume*.  Originally I hoped to avoid that complexity, and just use a single one-assert-fits-all case, but turned out blanketly using __assume() for all assertion cases wasn't reliable.
 * wxGuiTools: Replaced the operator, with operator& -- the latter has proper order of precedence, the former required () to scope correctly. >_<

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2339 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-12-14 12:18:55 +00:00

155 lines
4.5 KiB
C++

/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "App.h"
#include <wx/stackwalk.h>
static wxString pxGetStackTrace( const FnChar_t* calledFrom )
{
wxString stackTrace;
class StackDump : public wxStackWalker
{
protected:
wxString m_stackTrace;
wxString m_srcFuncName;
bool m_ignoreDone;
int m_skipped;
public:
StackDump( const FnChar_t* src_function_name )
{
if( src_function_name != NULL )
m_srcFuncName = fromUTF8(src_function_name);
m_ignoreDone = false;
m_skipped = 0;
}
const wxString& GetStackTrace() const { return m_stackTrace; }
protected:
virtual void OnStackFrame(const wxStackFrame& frame)
{
wxString name( frame.GetName() );
if( name.IsEmpty() )
{
name = wxsFormat( L"%p ", frame.GetAddress() );
}
/*else if( m_srcFuncName.IsEmpty() || m_srcFuncName == name )
{
// FIXME: This logic isn't reliable yet.
// It's possible for our debug information to not match the function names returned by
// __pxFUNCTION__ (might happen in linux a lot, and could happen in win32 due to
// inlining on Dev aserts). The better approach is a system the queues up all the
// stacktrace info in individual wxStrings, and does a two-pass check -- first pass
// for the function name and, if not found, a second pass that just skips the first
// few stack entries.
// It's important we only walk the stack once because Linux (argh, always linux!) has
// a really god aweful slow stack walker.
// I'm not doing it right now because I've worked on this mess enough for one week. --air
m_ignoreDone = true;
}
if( !m_ignoreDone )
{
m_skipped++;
return;
}*/
//wxString briefName;
wxString essenName;
if( frame.HasSourceLocation() )
{
wxFileName wxfn(frame.GetFileName());
//briefName.Printf( L"(%s:%d)", wxfn.GetFullName().c_str(), frame.GetLine() );
wxfn.SetVolume( wxEmptyString );
int count = wxfn.GetDirCount();
for( int i=0; i<2; ++i )
wxfn.RemoveDir(0);
essenName.Printf( L"%s:%d", wxfn.GetFullPath().c_str(), frame.GetLine() );
}
m_stackTrace += wxString::Format( L"[%02d] %-44s %s\n",
frame.GetLevel()-m_skipped,
name.c_str(),
essenName.c_str()
);
}
};
StackDump dump( calledFrom );
dump.Walk( 3 );
return dump.GetStackTrace();
}
#ifdef __WXDEBUG__
static __threadlocal int _reentrant_lock = 0;
// This override of wx's implementation provides thread safe assertion message reporting. If we aren't
// on the main gui thread then the assertion message box needs to be passed off to the main gui thread
// via messages.
void Pcsx2App::OnAssertFailure( const wxChar *file, int line, const wxChar *func, const wxChar *cond, const wxChar *msg )
{
// Re-entrant assertions are bad mojo -- trap immediately.
RecursionGuard guard( _reentrant_lock );
if( guard.IsReentrant() ) wxTrap();
wxCharBuffer bleh( wxString(func).ToUTF8() );
if( AppDoAssert( DiagnosticOrigin( file, line, bleh, cond ), msg ) )
{
wxTrap();
}
}
#endif
bool AppDoAssert( const DiagnosticOrigin& origin, const wxChar *msg )
{
// Used to allow the user to suppress future assertions during this application's session.
static bool disableAsserts = false;
if( disableAsserts ) return false;
wxString trace( pxGetStackTrace(origin.function) );
wxString dbgmsg( origin.ToString( msg ) );
wxMessageOutputDebug().Printf( dbgmsg );
Console.Error( dbgmsg );
Console.WriteLn( trace );
wxString windowmsg( L"Assertion failed: " );
if( msg != NULL )
windowmsg += msg;
else if( origin.condition != NULL )
windowmsg += origin.condition;
int retval = Msgbox::Assertion( windowmsg, dbgmsg + L"\nStacktrace:\n" + trace );
if( retval == wxID_YES ) return true;
if( retval == wxID_IGNORE ) disableAsserts = true;
return false;
}