OnExceptionInMainLoop not called in wx2.8.11/gcc4.4.0 Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Baskit
In need of some credit
In need of some credit
Posts: 3
Joined: Thu Mar 17, 2011 2:50 pm
Location: Vienna

OnExceptionInMainLoop not called in wx2.8.11/gcc4.4.0

Post by Baskit »

Hello!

i am building video-applications for WindowsXP using mingw/msys

I have been using mingw gcc 3.4.5 with wxWidgets 2.8.7 (Prebuilt wxPack version)

Recently i switched my build environmet to mingw gcc 4.4.0 and wxWidgets 2.8.11 (self-built)

When using wx2.8.11/gcc4.4.0 OnExceptionInMainLoop is not called when an Exception is thrown and not caught somewhere in the program.
Instead the program terminates with code 3 and shows a "Microsoft Visual C++ Runtime Library" Error box notifying me of an Runtime Error

OnExceptionInMainLoop does get called properly using the same code and wx2.8.7/gcc3.4.5

I was using --enable_exceptions=yes when running configure for my wx2.8.11 build

To illustrate my problem and to eliminate potential side effects of my relatively large application i have written a small example. (Files attached)

Header:

Code: Select all

#ifndef __ExceptionTest__
#define __ExceptionTest__

#include <string>
#include <iostream>

#include <wx/wx.h>
#include <wx/string.h>
#include <wx/button.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/frame.h>

#if wxUSE_EXCEPTIONS
#else
	#error No wx Exception Support
#endif

using namespace std;

class TestException
{
public:
	TestException() {}
	virtual ~TestException() {}
};

void showMsg(wxString msg);

class ExceptionFrame : public wxFrame {

public:
	ExceptionFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 500,300 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL );
	~ExceptionFrame();

protected:
	wxButton* throwButton;
	
	virtual void onThrowButton( wxCommandEvent& event );
};

class ExceptionApp: public wxApp
{
public:
	ExceptionApp(){};
	virtual ~ExceptionApp(){};
	
	virtual bool OnInit();

	virtual int OnRun();
	virtual bool OnExceptionInMainLoop();
	virtual void OnUnhandledException();
};


#endif //__ExceptionTest__
Source:

Code: Select all

#include "ExceptionTest.h"

void showMsg(wxString msg){
	wxMessageDialog* dialog= new wxMessageDialog( NULL, msg, _("Message"), wxOK|wxICON_INFORMATION);
	(void)dialog->ShowModal();
	dialog->Destroy();
}

ExceptionFrame::ExceptionFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
{
	this->SetSizeHints( wxDefaultSize, wxDefaultSize );
	
	wxBoxSizer* bSizer1;
	bSizer1 = new wxBoxSizer( wxVERTICAL );
	
	throwButton = new wxButton( this, wxID_ANY, wxT("THROW EXCEPTION"), wxDefaultPosition, wxDefaultSize, 0 );
	bSizer1->Add( throwButton, 0, wxALL, 5 );

	this->SetSizer( bSizer1 );
	this->Layout();

	throwButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ExceptionFrame::onThrowButton ), NULL, this );
}

ExceptionFrame::~ExceptionFrame()
{
	throwButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ExceptionFrame::onThrowButton ), NULL, this );
}

void ExceptionFrame::onThrowButton( wxCommandEvent& event ){
	showMsg(wxT("Throwing 1st Exception now"));
	try{
		throw TestException();
	}
	catch(TestException& e){
		showMsg(wxT("Caught 1st Exception"));
	}

	showMsg(wxT("Throwing 2nd Exception now"));
	throw TestException();
}


IMPLEMENT_APP(ExceptionApp)

bool ExceptionApp::OnInit(){
	ExceptionFrame* exceptionFrame = new ExceptionFrame(NULL, wxID_ANY,wxT("ExceptionFrame") ,wxDefaultPosition, wxSize(200,200));
	exceptionFrame->Show();

	return true;
}

int ExceptionApp::OnRun(){
	try{
		return wxApp::OnRun();
	}
	catch(TestException& e){
		showMsg(wxT("Caught Exception in OnRun"));
	}
}

bool ExceptionApp::OnExceptionInMainLoop(){
	showMsg(wxT("OnExceptionInMainLoop called"));
	return true;
}

void ExceptionApp::OnUnhandledException(){
	showMsg(wxT("OnUnhandledException"));
}
Building the example with wx2.8.7/gcc3.4.5
Expected behavior - OnExceptionInMainLoop called

Building the example with wx2.8.11/gcc4.4.0
Program terminates - Error Box with Runtime Error

I have no idea if there is a problem in my application code, my wx-build or this is a potential gcc or wxWidgets bug

For various reasons i would prefer to use wx2.8.11/gcc4.4.0 so i would be really grateful for any suggestions

Regards
Florian
You do not have the required permissions to view the files attached to this post.
Baskit
In need of some credit
In need of some credit
Posts: 3
Joined: Thu Mar 17, 2011 2:50 pm
Location: Vienna

Re: OnExceptionInMainLoop not called in wx2.8.11/gcc4.4.0

Post by Baskit »

Update:
I recently tried again using wx2.8.12 and a recent mingw/msys installation (gcc 4.8.1)
Sadly the issue still persists.

Furthermore the "except" sample provided with wx2.8.12 shows the same behavior
User avatar
doublemax
Moderator
Moderator
Posts: 19164
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: OnExceptionInMainLoop not called in wx2.8.11/gcc4.4.0

Post by doublemax »

Use the source, Luke!
Baskit
In need of some credit
In need of some credit
Posts: 3
Joined: Thu Mar 17, 2011 2:50 pm
Location: Vienna

Re: OnExceptionInMainLoop not called in wx2.8.11/gcc4.4.0

Post by Baskit »

Solved. Thanks to VZ who answered on stackoverflow =D>

maybe this old news to most of you,
but as it turns out one has to use sjlj exception handling for exceptions to pass through the windows-api correctly

mingw uses dwarf/dwarf2 as default for quite some time now.
as a result any wxWidgets build made with a basic mingw/msys installation (using mingw-get or the installer) will suffer form this issue
I am a bit surprised that it seems i am the first who stumbled onto this issue.

luckily the mingw-build project provides an relatively easy way to get a sjlj version of mingw-gcc