Am Mittwoch, 14. Juni 2006 19:34 schrieb Peter Kümmel:
> Under Windows it crahes here when leaving Lyx:
> 
> src/lyx_main.C
> #else
>       if (err_sig == SIGSEGV || !getEnv("LYXDEBUG").empty())
> #endif
>               lyx::support::abort();
>       exit(0);  <-------------------- line 442

Sorry, that happens here too, I accidentally tested the wrong executable.
I begin to understand more and more: We may not delete a QtView (which is 
derived from QmainWindow) after the main QApplication does not exist 
anymore.
Does this patch work for you?


Georg
Index: src/main.C
===================================================================
--- src/main.C	(Revision 14110)
+++ src/main.C	(Arbeitskopie)
@@ -44,6 +44,5 @@ int main(int argc, char * argv[])
 	// initialize for internationalized version *EK*
 	locale_init();
 
-	LyX::exec(argc, argv);
-	return 0;
+	return LyX::exec(argc, argv);
 }
Index: src/frontends/gtk/lyx_gui.C
===================================================================
--- src/frontends/gtk/lyx_gui.C	(Revision 14110)
+++ src/frontends/gtk/lyx_gui.C	(Arbeitskopie)
@@ -100,7 +100,7 @@ int getDPI()
 } // namespace anon
 
 
-void lyx_gui::exec(int & argc, char * argv[])
+int lyx_gui::exec(int & argc, char * argv[])
 {
 	new Gtk::Main(argc, argv);
 
@@ -113,7 +113,7 @@ void lyx_gui::exec(int & argc, char * ar
 	// must do this /before/ lyxrc gets read
 	lyxrc.dpi = getDPI();
 
-	LyX::ref().exec2(argc, argv);
+	return LyX::ref().exec2(argc, argv);
 }
 
 
@@ -122,8 +122,9 @@ void lyx_gui::parse_lyxrc()
 }
 
 
-void lyx_gui::start(string const & batch, std::vector<string> const & files,
-		    unsigned int width, unsigned int height, int posx, int posy, bool)
+int lyx_gui::start(string const & batch, std::vector<string> const & files,
+                   unsigned int width, unsigned int height, int posx,
+                   int posy, bool)
 {
 	boost::shared_ptr<GView> view_ptr(new GView);
 	LyX::ref().addLyXView(view_ptr);
@@ -151,6 +152,7 @@ void lyx_gui::start(string const & batch
 	// FIXME: breaks emergencyCleanup
 	delete lyxsocket;
 	delete lyxserver;
+	return EXIT_SUCCESS;
 }
 
 
Index: src/frontends/qt3/lyx_gui.C
===================================================================
--- src/frontends/qt3/lyx_gui.C	(Revision 14110)
+++ src/frontends/qt3/lyx_gui.C	(Arbeitskopie)
@@ -96,6 +96,10 @@ map<int, shared_ptr<socket_callback> > s
 
 void cleanup()
 {
+	// Delete all views.
+	// QMainWindow::~QMainWindow() will be called after the main
+	// QApplication does not exist anymore, and that results in a crash.
+	LyX::ref().removeLyXViews();
 	delete lyxsocket;
 	lyxsocket = 0;
 	delete lyxserver;
@@ -161,7 +165,7 @@ namespace lyx_gui {
 bool use_gui = true;
 
 
-void exec(int & argc, char * argv[])
+int exec(int & argc, char * argv[])
 {
 	// Force adding of font path _before_ QApplication is initialized
 	FontLoader::initFontPath();
@@ -213,7 +217,7 @@ void exec(int & argc, char * argv[])
 
 	LoaderQueue::setPriority(10,100);
 
-	LyX::ref().exec2(argc, argv);
+	return LyX::ref().exec2(argc, argv);
 }
 
 
@@ -221,8 +225,9 @@ void parse_lyxrc()
 {}
 
 
-void start(string const & batch, vector<string> const & files,
-	   unsigned int width, unsigned int height, int posx, int posy, bool maximize)
+int start(string const & batch, vector<string> const & files,
+          unsigned int width, unsigned int height, int posx, int posy,
+          bool maximize)
 {
 	// this can't be done before because it needs the Languages object
 	initEncodings();
@@ -233,7 +238,7 @@ void start(string const & batch, vector<
 	QtView & view = *view_ptr.get();
 
 	view.init();
-		
+
 	view.setGeometry(posx, posy, width, height);
 
 	if (maximize)
@@ -255,10 +260,11 @@ void start(string const & batch, vector<
 		view.getLyXFunc().dispatch(lyxaction.lookupFunc(batch));
 	}
 
-	qApp->exec();
+	int const status = qApp->exec();
 
 	// FIXME
 	cleanup();
+	return status;
 }
 
 
@@ -277,13 +283,7 @@ void sync_events()
 void exit(int status)
 {
 	cleanup();
-
-	// we cannot call QApplication::exit(status) - that could return us
-	// into a static dialog return in the lyx code (for example,
-	// load autosave file QMessageBox. We have to just get the hell
-	// out.
-
-	::exit(status);
+	QApplication::exit(status);
 }
 
 
Index: src/frontends/qt3/QtView.C
===================================================================
--- src/frontends/qt3/QtView.C	(Revision 14110)
+++ src/frontends/qt3/QtView.C	(Arbeitskopie)
@@ -87,11 +87,6 @@ QtView::QtView(unsigned int width, unsig
 }
 
 
-QtView::~QtView()
-{
-}
-
-
 void QtView::setWindowTitle(string const & t, string const & it)
 {
 	setCaption(toqstr(t));
Index: src/frontends/qt3/QtView.h
===================================================================
--- src/frontends/qt3/QtView.h	(Revision 14110)
+++ src/frontends/qt3/QtView.h	(Arbeitskopie)
@@ -39,8 +39,6 @@ public:
 	/// create a main window of the given dimensions
 	QtView(unsigned int w, unsigned int h);
 
-	~QtView();
-
 	/// show - display the top-level window
 	void show();
 
Index: src/frontends/qt4/lyx_gui.C
===================================================================
--- src/frontends/qt4/lyx_gui.C	(Revision 14110)
+++ src/frontends/qt4/lyx_gui.C	(Arbeitskopie)
@@ -96,6 +96,10 @@ map<int, shared_ptr<socket_callback> > s
 
 void cleanup()
 {
+	// Delete all views.
+	// QMainWindow::~QMainWindow() will be called after the main
+	// QApplication does not exist anymore, and that results in a crash.
+	LyX::ref().removeLyXViews();
 	delete lyxsocket;
 	lyxsocket = 0;
 	delete lyxserver;
@@ -162,16 +166,12 @@ namespace lyx_gui {
 bool use_gui = true;
 
 
-void exec(int & argc, char * argv[])
+int exec(int & argc, char * argv[])
 {	
 	// Force adding of font path _before_ QApplication is initialized
 	FontLoader::initFontPath();
 
-#ifdef Q_WS_WIN
-	static LQApplication app(argc, argv);
-#else
 	LQApplication app(argc, argv);
-#endif
 
 	// install translation file for Qt built-in dialogs
 	// These are only installed since Qt 3.2.x
@@ -219,7 +219,7 @@ void exec(int & argc, char * argv[])
 
 	LoaderQueue::setPriority(10,100);
 
-	LyX::ref().exec2(argc, argv);
+	return LyX::ref().exec2(argc, argv);
 }
 
 
@@ -227,8 +227,9 @@ void parse_lyxrc()
 {}
 
 
-void start(string const & batch, vector<string> const & files,
-	   unsigned int width, unsigned int height, int posx, int posy, bool maximize)
+int start(string const & batch, vector<string> const & files,
+          unsigned int width, unsigned int height, int posx, int posy,
+          bool maximize)
 {
 	// this can't be done before because it needs the Languages object
 	initEncodings();
@@ -239,7 +240,7 @@ void start(string const & batch, vector<
 	QtView & view = *view_ptr.get();
 
 	view.init();
-		
+
 	view.setGeometry(posx, posy, width, height);
 
 	if (maximize)
@@ -261,10 +262,11 @@ void start(string const & batch, vector<
 		view.getLyXFunc().dispatch(lyxaction.lookupFunc(batch));
 	}
 
-	qApp->exec();
+	int const status = qApp->exec();
 
 	// FIXME
 	cleanup();
+	return status;
 }
 
 
@@ -281,13 +283,7 @@ void sync_events()
 void exit(int status)
 {
 	cleanup();
-
-	// we cannot call QApplication::exit(status) - that could return us
-	// into a static dialog return in the lyx code (for example,
-	// load autosave file QMessageBox. We have to just get the hell
-	// out.
-
-	::exit(status);
+	QApplication::exit(status);
 }
 
 
Index: src/frontends/qt4/QtView.C
===================================================================
--- src/frontends/qt4/QtView.C	(Revision 14110)
+++ src/frontends/qt4/QtView.C	(Arbeitskopie)
@@ -103,10 +103,6 @@ QtView::QtView(unsigned int width, unsig
 }
 
 
-QtView::~QtView()
-{
-}
-
 void QtView::updateMenu(QAction *action)
 {
 	menubar_->update();
Index: src/frontends/qt4/QtView.h
===================================================================
--- src/frontends/qt4/QtView.h	(Revision 14110)
+++ src/frontends/qt4/QtView.h	(Arbeitskopie)
@@ -49,8 +49,6 @@ public:
 	/// create a main window of the given dimensions
 	QtView(unsigned int w, unsigned int h);
 
-	~QtView();
-
 	/// show - display the top-level window
 	void show();
 
Index: src/frontends/xforms/lyx_gui.C
===================================================================
--- src/frontends/xforms/lyx_gui.C	(Revision 14110)
+++ src/frontends/xforms/lyx_gui.C	(Arbeitskopie)
@@ -153,7 +153,7 @@ namespace lyx_gui {
 bool use_gui = true;
 
 
-void exec(int & argc, char * argv[])
+int exec(int & argc, char * argv[])
 {
 	setDefaults();
 
@@ -199,7 +199,7 @@ void exec(int & argc, char * argv[])
 
 	LoaderQueue::setPriority(10,100);
 
-	LyX::ref().exec2(argc, argv);
+	return LyX::ref().exec2(argc, argv);
 }
 
 
@@ -255,8 +255,8 @@ void parse_lyxrc()
 }
 
 
-void start(string const & batch, vector<string> const & files,
-	   unsigned int width, unsigned int height, int posx, int posy, bool)
+int start(string const & batch, vector<string> const & files,
+          unsigned int width, unsigned int height, int posx, int posy, bool)
 {
 	int const geometryBitmask =
 		XParseGeometry(geometry, &posx, &posy, &width, &height);
@@ -316,7 +316,7 @@ void start(string const & batch, vector<
 	// FIXME: breaks emergencyCleanup
 	delete lyxsocket;
 	delete lyxserver;
-	::exit(exit_status);
+	return exit_status;
 }
 
 
Index: src/frontends/lyx_gui.h
===================================================================
--- src/frontends/lyx_gui.h	(Revision 14110)
+++ src/frontends/lyx_gui.h	(Arbeitskopie)
@@ -56,13 +56,14 @@ void parse_lyxrc();
  * Start the main event loop, after executing the given
  * batch commands, and loading the given documents
  */
-void start(std::string const & batch, std::vector<std::string> const & files,
-           unsigned int width, unsigned int height, int posx, int posy, bool maximize);
+int start(std::string const & batch, std::vector<std::string> const & files,
+          unsigned int width, unsigned int height, int posx, int posy,
+          bool maximize);
 
 /**
  * Enter the main event loop (\sa LyX::exec2)
  */
-void exec(int & argc, char * argv[]);
+int exec(int & argc, char * argv[]);
 
 /**
  * Synchronise all pending events.
@@ -70,7 +71,8 @@ void exec(int & argc, char * argv[]);
 void sync_events();
 
 /**
- * quit running LyX
+ * Quit running LyX. This may either quit directly or record the exit status
+ * and only stop the event loop.
  */
 void exit(int);
 
Index: src/lyxtextclasslist.C
===================================================================
--- src/lyxtextclasslist.C	(Revision 14110)
+++ src/lyxtextclasslist.C	(Arbeitskopie)
@@ -217,15 +217,16 @@ LyXTextClassList textclasslist;
 
 
 // Reads the style files
-void LyXSetStyle()
+bool LyXSetStyle()
 {
 	lyxerr[Debug::TCLASS] << "LyXSetStyle: parsing configuration..." << endl;
 
 	if (!textclasslist.read()) {
 		lyxerr[Debug::TCLASS] << "LyXSetStyle: an error occured "
 			"during parsing.\n             Exiting." << endl;
-		exit(1);
+		return false;
 	}
 
 	lyxerr[Debug::TCLASS] << "LyXSetStyle: configuration parsed." << endl;
+	return true;
 }
Index: src/lyxtextclasslist.h
===================================================================
--- src/lyxtextclasslist.h	(Revision 14110)
+++ src/lyxtextclasslist.h	(Arbeitskopie)
@@ -24,7 +24,7 @@
 class LyXLayout;
 
 /// Reads the style files
-extern void LyXSetStyle();
+extern bool LyXSetStyle();
 
 ///
 class LyXTextClassList : boost::noncopyable {
Index: src/lyx_main.C
===================================================================
--- src/lyx_main.C	(Revision 14110)
+++ src/lyx_main.C	(Arbeitskopie)
@@ -113,6 +113,7 @@ void lyx_exit(int status)
 	// guarantees a return to the system, no application cleanup.
 	// This may cause troubles with not executed destructors.
 	if (lyx_gui::use_gui)
+		// lyx_gui::exit may return and only schedule the exit
 		lyx_gui::exit(status);
 	exit(status);
 }
@@ -123,7 +124,6 @@ void showFileError(string const & error)
 	Alert::warning(_("Could not read configuration file"),
 		   bformat(_("Error while reading the configuration file\n%1$s.\n"
 		     "Please check your installation."), error));
-	lyx_exit(EXIT_FAILURE);
 }
 
 
@@ -143,7 +143,7 @@ void reconfigureUserLyXDir()
 
 boost::scoped_ptr<LyX> LyX::singleton_;
 
-void LyX::exec(int & argc, char * argv[])
+int LyX::exec(int & argc, char * argv[])
 {
 	BOOST_ASSERT(!singleton_.get());
 	// We must return from this before launching the gui so that
@@ -151,7 +151,7 @@ void LyX::exec(int & argc, char * argv[]
 	// LyX::ref and LyX::cref.
 	singleton_.reset(new LyX);
 	// Start the real execution loop.
-	singleton_->priv_exec(argc, argv);
+	return singleton_->priv_exec(argc, argv);
 }
 
 
@@ -194,6 +194,12 @@ void LyX::addLyXView(boost::shared_ptr<L
 }
 
 
+void LyX::removeLyXViews()
+{
+	views_.clear();
+}
+
+
 Buffer const * const LyX::updateInset(InsetBase const * inset) const
 {
 	if (!inset)
@@ -211,7 +217,7 @@ Buffer const * const LyX::updateInset(In
 }
 
 
-void LyX::priv_exec(int & argc, char * argv[])
+int LyX::priv_exec(int & argc, char * argv[])
 {
 	// Here we need to parse the command line. At least
 	// we need to parse for "-dbg" and "-help"
@@ -222,13 +228,13 @@ void LyX::priv_exec(int & argc, char * a
 
 	// Start the real execution loop.
 	if (lyx_gui::use_gui)
-		lyx_gui::exec(argc, argv);
+		return lyx_gui::exec(argc, argv);
 	else
-		exec2(argc, argv);
+		return exec2(argc, argv);
 }
 
 
-void LyX::exec2(int & argc, char * argv[])
+int LyX::exec2(int & argc, char * argv[])
 {
 	// check for any spurious extra arguments
 	// other than documents
@@ -236,14 +242,16 @@ void LyX::exec2(int & argc, char * argv[
 		if (argv[argi][0] == '-') {
 			lyxerr << bformat(_("Wrong command line option `%1$s'. Exiting."),
 				argv[argi]) << endl;
-			exit(1);
+			return EXIT_FAILURE;
 		}
 	}
 
 	// Initialization of LyX (reads lyxrc and more)
 	lyxerr[Debug::INIT] << "Initializing LyX::init..." << endl;
-	init();
+	bool const success = init();
 	lyxerr[Debug::INIT] << "Initializing LyX::init...done" << endl;
+	if (!success)
+		return EXIT_FAILURE;
 
 	if (lyx_gui::use_gui)
 		lyx_gui::parse_lyxrc();
@@ -296,7 +304,7 @@ void LyX::exec2(int & argc, char * argv[
 			bool success = false;
 			if (last_loaded->dispatch(batch_command, &success)) {
 				quitLyX(false);
-				lyx_exit(!success);
+				return !success;
 			}
 		}
 		files.clear(); // the files are already loaded
@@ -335,11 +343,11 @@ void LyX::exec2(int & argc, char * argv[
 			if (!val.empty())
 				posy = convert<int>(val);
 		}
-		lyx_gui::start(batch_command, files, width, height, posx, posy, maximize);
+		return lyx_gui::start(batch_command, files, width, height, posx, posy, maximize);
 	} else {
 		// Something went wrong above
 		quitLyX(false);
-		lyx_exit(EXIT_FAILURE);
+		return EXIT_FAILURE;
 	}
 }
 
@@ -451,7 +459,7 @@ void LyX::printError(ErrorItem const & e
 }
 
 
-void LyX::init()
+bool LyX::init()
 {
 #ifdef SIGHUP
 	signal(SIGHUP, error_handler);
@@ -482,7 +490,8 @@ void LyX::init()
 	//
 
 	// This one may have been distributed along with LyX.
-	readRcFile("lyxrc.dist");
+	if (!readRcFile("lyxrc.dist"))
+		return false;
 
 	// Set the PATH correctly.
 #if !defined (USE_POSIX_PACKAGING)
@@ -504,7 +513,8 @@ void LyX::init()
 	}
 
 	// This one is generated in user_support directory by lib/configure.py.
-	readRcFile("lyxrc.defaults");
+	if (!readRcFile("lyxrc.defaults"))
+		return false;
 
 	// Query the OS to know what formats are viewed natively
 	formats.setAutoOpen();
@@ -516,14 +526,18 @@ void LyX::init()
 	system_lcolor = lcolor;
 
 	// This one is edited through the preferences dialog.
-	readRcFile("preferences");
+	if (!readRcFile("preferences"))
+		return false;
 
-	readEncodingsFile("encodings");
-	readLanguagesFile("languages");
+	if (!readEncodingsFile("encodings"))
+		return false;
+	if (!readLanguagesFile("languages"))
+		return false;
 
 	// Load the layouts
 	lyxerr[Debug::INIT] << "Reading layouts..." << endl;
-	LyXSetStyle();
+	if (!LyXSetStyle())
+		return false;
 
 	if (lyx_gui::use_gui) {
 		// Set up bindings
@@ -532,7 +546,8 @@ void LyX::init()
 		toplevel_keymap->read(lyxrc.bind_file);
 
 		// Read menus
-		readUIFile(lyxrc.ui_file);
+		if (!readUIFile(lyxrc.ui_file))
+			return false;
 	}
 
 	if (lyxerr.debugging(Debug::LYXRC))
@@ -558,7 +573,7 @@ void LyX::init()
 		// close to zero. We therefore don't try to overcome this
 		// problem with e.g. asking the user for a new path and
 		// trying again but simply exit.
-		lyx_exit(EXIT_FAILURE);
+		return false;
 	}
 
 	if (lyxerr.debugging(Debug::INIT)) {
@@ -567,6 +582,7 @@ void LyX::init()
 
 	lyxerr[Debug::INIT] << "Reading session information '.lyx/session'..." << endl;
 	session_.reset(new lyx::Session(lyxrc.num_lastfiles));
+	return true;
 }
 
 
@@ -724,7 +740,7 @@ bool LyX::queryUserLyXDir(bool explicit_
 }
 
 
-void LyX::readRcFile(string const & name)
+bool LyX::readRcFile(string const & name)
 {
 	lyxerr[Debug::INIT] << "About to read " << name << "... ";
 
@@ -733,16 +749,19 @@ void LyX::readRcFile(string const & name
 
 		lyxerr[Debug::INIT] << "Found in " << lyxrc_path << endl;
 
-		if (lyxrc.read(lyxrc_path) < 0)
+		if (lyxrc.read(lyxrc_path) < 0) {
 			showFileError(name);
+			return false;
+		}
 	} else
 		lyxerr[Debug::INIT] << "Not found." << lyxrc_path << endl;
+	return true;
 
 }
 
 
 // Read the ui file `name'
-void LyX::readUIFile(string const & name)
+bool LyX::readUIFile(string const & name)
 {
 	enum Uitags {
 		ui_menuset = 1,
@@ -769,7 +788,7 @@ void LyX::readUIFile(string const & name
 				    << "' has been read already. "
 				    << "Is this an include loop?"
 				    << endl;
-		return;
+		return false;
 	}
 
 	lyxerr[Debug::INIT] << "About to read " << name << "..." << endl;
@@ -779,7 +798,7 @@ void LyX::readUIFile(string const & name
 	if (ui_path.empty()) {
 		lyxerr[Debug::INIT] << "Could not find " << name << endl;
 		showFileError(name);
-		return;
+		return false;
 	}
 	uifiles.push_back(name);
 
@@ -800,7 +819,8 @@ void LyX::readUIFile(string const & name
 		case ui_include: {
 			lex.next(true);
 			string const file = lex.getString();
-			readUIFile(file);
+			if (!readUIFile(file))
+				return false;
 			break;
 		}
 		case ui_menuset:
@@ -822,34 +842,37 @@ void LyX::readUIFile(string const & name
 			break;
 		}
 	}
+	return true;
 }
 
 
 // Read the languages file `name'
-void LyX::readLanguagesFile(string const & name)
+bool LyX::readLanguagesFile(string const & name)
 {
 	lyxerr[Debug::INIT] << "About to read " << name << "..." << endl;
 
 	string const lang_path = libFileSearch(string(), name);
 	if (lang_path.empty()) {
 		showFileError(name);
-		return;
+		return false;
 	}
 	languages.read(lang_path);
+	return true;
 }
 
 
 // Read the encodings file `name'
-void LyX::readEncodingsFile(string const & name)
+bool LyX::readEncodingsFile(string const & name)
 {
 	lyxerr[Debug::INIT] << "About to read " << name << "..." << endl;
 
 	string const enc_path = libFileSearch(string(), name);
 	if (enc_path.empty()) {
 		showFileError(name);
-		return;
+		return false;
 	}
 	encodings.read(enc_path);
+	return true;
 }
 
 
Index: src/lyx_main.h
===================================================================
--- src/lyx_main.h	(Revision 14110)
+++ src/lyx_main.h	(Arbeitskopie)
@@ -46,9 +46,9 @@ public:
 	 * objects lead either to harmless error messages on exit
 	 * ("Mutex destroy failure") or crashes (OS X).
 	 */
-	static void exec(int & argc, char * argv[]);
+	static int exec(int & argc, char * argv[]);
 	/// Execute LyX (inner execution loop, \sa exec)
-	void exec2(int & argc, char * argv[]);
+	int exec2(int & argc, char * argv[]);
 	static LyX & ref();
 	static LyX const & cref();
 
@@ -59,6 +59,8 @@ public:
 	lyx::Session const & session() const;
 
 	void addLyXView(boost::shared_ptr<LyXView> const & lyxview);
+	/// Delete all views.
+	void removeLyXViews();
 
 	/** redraw \c inset in all the BufferViews in which it is currently
 	 *  visible. If successful return a pointer to the owning Buffer.
@@ -69,10 +71,10 @@ private:
 	static boost::scoped_ptr<LyX> singleton_;
 
 	LyX();
-	void priv_exec(int & argc, char * argv[]);
+	int priv_exec(int & argc, char * argv[]);
 
 	/// initial LyX set up
-	void init();
+	bool init();
 	/// set up the default key bindings
 	void defaultKeyBindings(kb_keymap * kbmap);
 	/// set up the default dead key bindings if requested
@@ -85,13 +87,13 @@ private:
 	 */
 	bool queryUserLyXDir(bool explicit_userdir);
 	/// read lyxrc/preferences
-	void readRcFile(std::string const & name);
+	bool readRcFile(std::string const & name);
 	/// read the given ui (menu/toolbar) file
-	void readUIFile(std::string const & name);
+	bool readUIFile(std::string const & name);
 	/// read the given languages file
-	void readLanguagesFile(std::string const & name);
+	bool readLanguagesFile(std::string const & name);
 	/// read the given encodings file
-	void readEncodingsFile(std::string const & name);
+	bool readEncodingsFile(std::string const & name);
 	/// parsing of non-gui LyX options. Returns true if gui
 	bool easyParse(int & argc, char * argv[]);
 	/// shows up a parsing error on screen

Reply via email to