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