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