예제 #1
0
DEVASSERT_INLINE void pxOnAssert( const DiagnosticOrigin& origin, const wxChar* msg )
{
	// Recursion guard: Allow at least one recursive call.  This is useful because sometimes
	// we get meaningless assertions while unwinding stack traces after exceptions have occurred.

	RecursionGuard guard( s_assert_guard );
	if (guard.Counter > 2) { return wxTrap(); }

	// wxWidgets doesn't come with debug builds on some Linux distros, and other distros make
	// it difficult to use the debug build (compilation failures).  To handle these I've had to
	// bypass the internal wxWidgets assertion handler entirely, since it may not exist even if
	// PCSX2 itself is compiled in debug mode (assertions enabled).

	bool trapit;

	if( pxDoAssert == NULL )
	{
		// Note: Format uses MSVC's syntax for output window hotlinking.
		trapit = pxAssertImpl_LogIt( origin, msg );
	}
	else
	{
		trapit = pxDoAssert( origin, msg );
	}

	if( trapit ) { pxTrap(); }
}
예제 #2
0
// this function is called when an assert fails
void wxOnAssert(const wxChar *szFile,
                int nLine,
                const wxChar *szCond,
                const wxChar *szMsg)
{
    // FIXME MT-unsafe
    static bool s_bInAssert = false;

    if ( s_bInAssert )
    {
        // He-e-e-e-elp!! we're trapped in endless loop
        wxTrap();

        s_bInAssert = false;

        return;
    }

    s_bInAssert = true;

    if ( !wxTheApp )
    {
        // by default, show the assert dialog box -- we can't customize this
        // behaviour
        ShowAssertDialog(szFile, nLine, szCond, szMsg);
    }
    else
    {
        // let the app process it as it wants
        wxTheApp->OnAssert(szFile, nLine, szCond, szMsg);
    }

    s_bInAssert = false;
}
void CardViewer::onPaint(wxPaintEvent&) {
	#ifdef _DEBUG
		// we don't want recursion
		if (inOnPaint()) {
			wxTrap();
		}
		WITH_DYNAMIC_ARG(inOnPaint, true);
	#endif
	wxSize cs = GetClientSize();
	if (!buffer.Ok() || buffer.GetWidth() != cs.GetWidth() || buffer.GetHeight() != cs.GetHeight()) {
		buffer = Bitmap(cs.GetWidth(), cs.GetHeight());
		up_to_date = false;
	}
	wxBufferedPaintDC dc(this, buffer);
	// scrolling
//	int dx = GetScrollPos(wxHORIZONTAL), dy = GetScrollPos(wxVERTICAL);
//	dc.SetDeviceOrigin(-dx, -dy);
	wxRegion clip = GetUpdateRegion();
//	clip.Offset(dx, dy);
	dc.SetDeviceClippingRegion(clip);
	// draw
	if (!up_to_date) {
		up_to_date = true;
		try {
			draw(dc);
		} CATCH_ALL_ERRORS(false); // don't show message boxes in onPaint!
	}
예제 #4
0
파일: appcmn.cpp 프로젝트: gitrider/wxsj2
bool wxGUIAppTraitsBase::ShowAssertDialog(const wxString& msg)
{
    // under MSW we prefer to use the base class version using ::MessageBox()
    // even if wxMessageBox() is available because it has less chances to
    // double fault our app than our wxMessageBox()
#if defined(__WXMSW__) || !wxUSE_MSGDLG
    return wxAppTraitsBase::ShowAssertDialog(msg);
#else // wxUSE_MSGDLG
    // this message is intentionally not translated -- it is for
    // developpers only
    wxString msgDlg(msg);
    msgDlg += wxT("\nDo you want to stop the program?\n")
              wxT("You can also choose [Cancel] to suppress ")
              wxT("further warnings.");

    switch ( wxMessageBox(msgDlg, wxT("wxWidgets Debug Alert"),
                          wxYES_NO | wxCANCEL | wxICON_STOP ) )
    {
        case wxYES:
            wxTrap();
            break;

        case wxCANCEL:
            // no more asserts
            return true;

        //case wxNO: nothing to do
    }

    return false;
#endif // !wxUSE_MSGDLG/wxUSE_MSGDLG
}
예제 #5
0
파일: appcmn.cpp 프로젝트: jonntd/dynamica
bool wxGUIAppTraitsBase::ShowAssertDialog(const wxString& msg)
{
    // under MSW we prefer to use the base class version using ::MessageBox()
    // even if wxMessageBox() is available because it has less chances to
    // double fault our app than our wxMessageBox()
    //
    // under DFB the message dialog is not always functional right now
    //
    // and finally we can't use wxMessageBox() if it wasn't compiled in, of
    // course
#if defined(__WXMSW__) || defined(__WXDFB__) || !wxUSE_MSGDLG
    return wxAppTraitsBase::ShowAssertDialog(msg);
#else // wxUSE_MSGDLG
#if wxDEBUG_LEVEL
    wxString msgDlg = msg;

#if wxUSE_STACKWALKER
    // on Unix stack frame generation may take some time, depending on the
    // size of the executable mainly... warn the user that we are working
    wxFprintf(stderr, wxT("[Debug] Generating a stack trace... please wait"));
    fflush(stderr);

    const wxString stackTrace = GetAssertStackTrace();
    if ( !stackTrace.empty() )
        msgDlg << _T("\n\nCall stack:\n") << stackTrace;
#endif // wxUSE_STACKWALKER

    // this message is intentionally not translated -- it is for
    // developpers only
    msgDlg += wxT("\nDo you want to stop the program?\n")
              wxT("You can also choose [Cancel] to suppress ")
              wxT("further warnings.");

    switch ( wxMessageBox(msgDlg, wxT("wxWidgets Debug Alert"),
                          wxYES_NO | wxCANCEL | wxICON_STOP ) )
    {
        case wxYES:
            wxTrap();
            break;

        case wxCANCEL:
            // no more asserts
            return true;

        //case wxNO: nothing to do
    }
#else // !wxDEBUG_LEVEL
    // this function always exists (for ABI compatibility) but is never called
    // if debug level is 0 and so can simply do nothing then
    wxUnusedVar(msg);
#endif // wxDEBUG_LEVEL/!wxDEBUG_LEVEL

    return false;
#endif // !wxUSE_MSGDLG/wxUSE_MSGDLG
}
예제 #6
0
bool wxGUIAppTraits::ShowAssertDialog(const wxString& msg)
{
#if wxDEBUG_LEVEL
    // we can't show the dialog from another thread
    if ( wxIsMainThread() )
    {
        // under GTK2 we prefer to use a dialog widget written using directly
        // in GTK+ as use a dialog written using wxWidgets would need the
        // wxWidgets idle processing to work correctly which might not be the
        // case when assert happens
        GtkWidget *dialog = gtk_assert_dialog_new();
        gtk_assert_dialog_set_message(GTK_ASSERT_DIALOG(dialog), msg.mb_str());

#if wxUSE_STACKWALKER
        // save the current stack ow...
        StackDump dump(GTK_ASSERT_DIALOG(dialog));
        dump.SaveStack(100); // showing more than 100 frames is not very useful

        // ...but process it only if the user needs it
        gtk_assert_dialog_set_backtrace_callback
        (
            GTK_ASSERT_DIALOG(dialog),
            (GtkAssertDialogStackFrameCallback)get_stackframe_callback,
            &dump
        );
#endif // wxUSE_STACKWALKER

        gint result = gtk_dialog_run(GTK_DIALOG (dialog));
        bool returnCode = false;
        switch (result)
        {
            case GTK_ASSERT_DIALOG_STOP:
                wxTrap();
                break;
            case GTK_ASSERT_DIALOG_CONTINUE:
                // nothing to do
                break;
            case GTK_ASSERT_DIALOG_CONTINUE_SUPPRESSING:
                // no more asserts
                returnCode = true;
                break;

            default:
                wxFAIL_MSG( wxT("unexpected return code from GtkAssertDialog") );
        }

        gtk_widget_destroy(dialog);
        return returnCode;
    }
#endif // wxDEBUG_LEVEL

    return wxAppTraitsBase::ShowAssertDialog(msg);
}
예제 #7
0
bool wxGUIAppTraits::ShowAssertDialog(const wxString& msg)
{
#if wxDEBUG_LEVEL
    // under GTK2 we prefer to use a dialog widget written using directly in
    // GTK+ as use a dialog written using wxWidgets would need the wxWidgets
    // idle processing to work correctly which might not be the case when
    // assert happens
    GtkWidget *dialog = gtk_assert_dialog_new();
    gtk_assert_dialog_set_message(GTK_ASSERT_DIALOG(dialog), msg.mb_str());

#if wxUSE_STACKWALKER
    // don't show more than maxLines or we could get a dialog too tall to be
    // shown on screen: 20 should be ok everywhere as even with 15 pixel high
    // characters it is still only 300 pixels...
    static const int maxLines = 20;

    // save current stack frame...
    StackDump dump(GTK_ASSERT_DIALOG(dialog));
    dump.SaveStack(maxLines);

    // ...but process it only if the user needs it
    gtk_assert_dialog_set_backtrace_callback(GTK_ASSERT_DIALOG(dialog),
                                             (GtkAssertDialogStackFrameCallback)get_stackframe_callback,
                                             &dump);
#endif      // wxUSE_STACKWALKER

    gint result = gtk_dialog_run(GTK_DIALOG (dialog));
    bool returnCode = false;
    switch (result)
    {
    case GTK_ASSERT_DIALOG_STOP:
        wxTrap();
        break;
    case GTK_ASSERT_DIALOG_CONTINUE:
        // nothing to do
        break;
    case GTK_ASSERT_DIALOG_CONTINUE_SUPPRESSING:
        // no more asserts
        returnCode = true;
        break;

    default:
        wxFAIL_MSG( _T("unexpected return code from GtkAssertDialog") );
    }

    gtk_widget_destroy(dialog);
    return returnCode;
#else // !wxDEBUG_LEVEL
    // this function is never called in this case
    wxUnusedVar(msg);
    return false;
#endif // wxDEBUG_LEVEL/!wxDEBUG_LEVEL
}
예제 #8
0
bool wxGUIAppTraitsBase::ShowAssertDialog(const wxString& msg)
{
#if wxDEBUG_LEVEL
    // under MSW we prefer to use the base class version using ::MessageBox()
    // even if wxMessageBox() is available because it has less chances to
    // double fault our app than our wxMessageBox()
    //
    // under DFB the message dialog is not always functional right now
    //
    // and finally we can't use wxMessageBox() if it wasn't compiled in, of
    // course
#if !defined(__WXMSW__) && !defined(__WXDFB__) && wxUSE_MSGDLG

    // we can't (safely) show the GUI dialog from another thread, only do it
    // for the asserts in the main thread
    if ( wxIsMainThread() )
    {
        wxString msgDlg = msg;

#if wxUSE_STACKWALKER
        const wxString stackTrace = GetAssertStackTrace();
        if ( !stackTrace.empty() )
            msgDlg << wxT("\n\nCall stack:\n") << stackTrace;
#endif // wxUSE_STACKWALKER

        // this message is intentionally not translated -- it is for
        // developpers only
        msgDlg += wxT("\nDo you want to stop the program?\n")
                  wxT("You can also choose [Cancel] to suppress ")
                  wxT("further warnings.");

        switch ( wxMessageBox(msgDlg, wxT("wxWidgets Debug Alert"),
                              wxYES_NO | wxCANCEL | wxICON_STOP ) )
        {
            case wxYES:
                wxTrap();
                break;

            case wxCANCEL:
                // no more asserts
                return true;

            //case wxNO: nothing to do
        }

        return false;
    }
#endif // wxUSE_MSGDLG
#endif // wxDEBUG_LEVEL

    return wxAppTraitsBase::ShowAssertDialog(msg);
}
예제 #9
0
bool DoShowAssertDialog(const wxString& msg)
{
    // under MSW we can show the dialog even in the console mode
#if defined(__WXMSW__) && !defined(__WXMICROWIN__)
    wxString msgDlg(msg);

    // this message is intentionally not translated -- it is for
    // developpers only
    msgDlg += wxT("\nDo you want to stop the program?\n")
              wxT("You can also choose [Cancel] to suppress ")
              wxT("further warnings.");

    switch ( ::MessageBox(NULL, msgDlg, _T("wxWidgets Debug Alert"),
                          MB_YESNOCANCEL | MB_ICONSTOP ) )
    {
        case IDYES:
            wxTrap();
            break;

        case IDCANCEL:
            // stop the asserts
            return true;

        //case IDNO: nothing to do
    }
#else // !__WXMSW__
    wxFprintf(stderr, wxT("%s\n"), msg.c_str());
    fflush(stderr);

    // TODO: ask the user to enter "Y" or "N" on the console?
    wxTrap();
#endif // __WXMSW__/!__WXMSW__

    // continue with the asserts
    return false;
}
예제 #10
0
void BOINCAssertHandler(const wxString &file, int line, const wxString &func, const wxString &cond, const wxString &msg) {
    wxLogTrace(
        wxT("Assert"),
        wxT("ASSERT: %s:%d - %s - %s - %s"),
        file.IsEmpty() ? wxT("<NULL>") : file.c_str(),
        line,
        func.IsEmpty() ? wxT("<NULL>") : func.c_str(),
        cond.IsEmpty() ? wxT("<NULL>") : cond.c_str(),
        msg.IsEmpty()  ? wxT("<NULL>") : msg.c_str()
    );

    if (wxIsDebuggerRunning()) {
        wxTrap();
    }
}
예제 #11
0
void BaseVmReserveListener::OnPageFaultEvent(const PageFaultInfo& info, bool& handled)
{
	sptr offset = (info.addr - (uptr)m_baseptr) / __pagesize;
	if ((offset < 0) || ((uptr)offset >= m_pages_reserved)) return;

	if (!m_allow_writes)
	{
		pxFailRel( pxsFmt(
			L"Memory Protection Fault @ %s (%s)\n"
			L"Modification of this reserve has been disabled (m_allow_writes == false).",
			pxsPtr(info.addr), m_name.c_str())
		);
		return;
	}

	// Linux Note!  the SIGNAL handler is very limited in what it can do, and not only can't
	// we let the C++ exception try to unwind the stack, we may not be able to log it either.
	// (but we might as well try -- kernel/posix rules says not to do it, but Linux kernel
	//  implementations seem to support it).
	// Note also that logging the exception and/or issuing an assertion dialog are always
	// possible if the thread handling the signal is not the main thread.

	// In windows we can let exceptions bubble out of the page fault handler.  SEH will more
	// or less handle them in a semi-expected way, and might even avoid a GPF long enough
	// for the system to log the error or something.

	#ifndef __WXMSW__
	try	{
	#endif
		DoCommitAndProtect( offset );
		handled = true;

	#ifndef __WXMSW__
	}
	catch (Exception::BaseException& ex)
	{
		handled = false;
		if (!wxThread::IsMain())
		{
			pxFailRel( ex.FormatDiagnosticMessage() );
		}
		else
		{
			wxTrap();
		}
	}
	#endif
}
예제 #12
0
// Linux implementation of SIGSEGV handler.  Bind it using sigaction().
static void SysPageFaultSignalFilter( int signal, siginfo_t *siginfo, void * )
{
	// [TODO] : Add a thread ID filter to the Linux Signal handler here.
	// Rationale: On windows, the __try/__except model allows per-thread specific behavior
	// for page fault handling.  On linux, there is a single signal handler for the whole
	// process, but the handler is executed by the thread that caused the exception.


	// Stdio Usage note: SIGSEGV handling is a synchronous in-thread signal.  It is done
	// from the context of the current thread and stackframe.  So long as the thread is not
	// the main/ui thread, use of the px assertion system should be safe.  Use of stdio should
	// be safe even on the main thread.
	//  (in other words, stdio limitations only really apply to process-level asynchronous
	//   signals)

	// Note: Use of stdio functions isn't safe here.  Avoid console logs,
	// assertions, file logs, or just about anything else useful.


	// Note: This signal can be accessed by the EE or MTVU thread
	// Source_PageFault is a global variable with its own state information
	// so for now we lock this exception code unless someone can fix this better...
	Threading::ScopedLock lock(PageFault_Mutex);

	Source_PageFault->Dispatch( PageFaultInfo( (uptr)siginfo->si_addr & ~m_pagemask ) );

	// resumes execution right where we left off (re-executes instruction that
	// caused the SIGSEGV).
	if (Source_PageFault->WasHandled()) return;

	if (!wxThread::IsMain())
	{
		pxFailRel(pxsFmt("Unhandled page fault @ 0x%08x", siginfo->si_addr));
	}

	// Bad mojo!  Completely invalid address.
	// Instigate a trap if we're in a debugger, and if not then do a SIGKILL.

	wxTrap();
	if (!IsDebugBuild) raise( SIGKILL );
}
예제 #13
0
// show the assert modal dialog
static
void ShowAssertDialog(const wxChar *szFile,
                      int nLine,
                      const wxChar *szCond,
                      const wxChar *szMsg,
                      wxAppTraits *traits)
{
    // this variable can be set to true to suppress "assert failure" messages
    static bool s_bNoAsserts = false;

    wxString msg;
    msg.reserve(2048);

    // make life easier for people using VC++ IDE by using this format: like
    // this, clicking on the message will take us immediately to the place of
    // the failed assert
    msg.Printf(wxT("%s(%d): assert \"%s\" failed"), szFile, nLine, szCond);

    if ( szMsg )
    {
        msg << _T(": ") << szMsg;
    }
    else // no message given
    {
        msg << _T('.');
    }

#if wxUSE_STACKWALKER
    const wxString stackTrace = GetAssertStackTrace();
    if ( !stackTrace.empty() )
    {
        msg << _T("\n\nCall stack:\n") << stackTrace;
    }
#endif // wxUSE_STACKWALKER

#if wxUSE_THREADS
    // if we are not in the main thread, output the assert directly and trap
    // since dialogs cannot be displayed
    if ( !wxThread::IsMain() )
    {
        msg += wxT(" [in child thread]");

#if defined(__WXMSW__) && !defined(__WXMICROWIN__)
        msg << wxT("\r\n");
        OutputDebugString(msg );
#else
        // send to stderr
        wxFprintf(stderr, wxT("%s\n"), msg.c_str());
        fflush(stderr);
#endif
        // He-e-e-e-elp!! we're asserting in a child thread
        wxTrap();
    }
    else
#endif // wxUSE_THREADS

    if ( !s_bNoAsserts )
    {
        // send it to the normal log destination
        wxLogDebug(_T("%s"), msg.c_str());

        if ( traits )
        {
            // delegate showing assert dialog (if possible) to that class
            s_bNoAsserts = traits->ShowAssertDialog(msg);
        }
        else // no traits object
        {
            // fall back to the function of last resort
            s_bNoAsserts = DoShowAssertDialog(msg);
        }
    }
}
예제 #14
0
파일: appcmn.cpp 프로젝트: madnessw/thesnow
bool wxGUIAppTraitsBase::ShowAssertDialog(const wxString& msg)
{
#if defined(__WXMSW__) || !wxUSE_MSGDLG
    // under MSW we prefer to use the base class version using ::MessageBox()
    // even if wxMessageBox() is available because it has less chances to
    // double fault our app than our wxMessageBox()
    return wxAppTraitsBase::ShowAssertDialog(msg);
#else // wxUSE_MSGDLG
    wxString msgDlg = msg;

#if wxUSE_STACKWALKER
    // on Unix stack frame generation may take some time, depending on the
    // size of the executable mainly... warn the user that we are working
    wxFprintf(stderr, wxT("[Debug] Generating a stack trace... please wait"));
    fflush(stderr);

    const wxString stackTrace = GetAssertStackTrace();
    if ( !stackTrace.empty() )
        msgDlg << _T("\n\nCall stack:\n") << stackTrace;
#endif // wxUSE_STACKWALKER

    // this message is intentionally not translated -- it is for
    // developpers only
    msgDlg += wxT("\nDo you want to stop the program?\n")
              wxT("You can also choose [Cancel] to suppress ")
              wxT("further warnings.");

#ifdef __WXMAC__
    // in order to avoid reentrancy problems, use the lowest alert API available
    CFOptionFlags exitButton;
    wxMacCFStringHolder cfText(msgDlg);
    OSStatus err = CFUserNotificationDisplayAlert(
            0, kAlertStopAlert, NULL, NULL, NULL, CFSTR("wxWidgets Debug Alert"), cfText,
            CFSTR("Yes"), CFSTR("No"), CFSTR("Cancel"), &exitButton );
    if ( err == noErr )
    {
        switch( exitButton )
        {
            case 0 : // yes
                wxTrap();
                break;
            case 2 : // cancel
                // no more asserts
                return true;
            case 1 : // no -> nothing to do
                break ;
        }
    }
#else
    switch ( wxMessageBox(msgDlg, wxT("wxWidgets Debug Alert"),
                          wxYES_NO | wxCANCEL | wxICON_STOP ) )
    {
        case wxYES:
            wxTrap();
            break;

        case wxCANCEL:
            // no more asserts
            return true;

        //case wxNO: nothing to do
    }
#endif
    return false;
#endif // !wxUSE_MSGDLG/wxUSE_MSGDLG
}