Seite 1 von 1

QApplication::notify() reimplementieren

Verfasst: 31. Oktober 2009 15:05
von D.Cent
Ich benutze ein paar selbstgeschriebene Bibliotheken, die Fehler ausschließlich throwen. Nun wollte ich gerne QApplication::notify() reimplementieren, da man laut Qt keine exceptions catchen kann.

Zum Test habe ich das ganze mal so aufgebaut und in meinem mainloop anstatt QApplication verwendet:

Code: Alles auswählen

class applicationClass : public QApplication

 {

  public: 

   applicationClass(int _argc, char **_argv): QApplication(_argc, _argv)

    { 

    }

    

  bool notify(QObject *receiver, QEvent *e)

    {

      cout << "Notify()!" << endl;

      return false;

    } 

 };
Doch nun stürzt er mit einem Speicherzugriffsfehler ab. Valgrind verfolgt das ganze so:

Code: Alles auswählen

==30637== Invalid read of size 1                                                                       
==30637==    at 0x40284E8: strlen (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)               
==30637==    by 0x4B91CE6: XSetCommand (in /usr/lib/libX11.so.6.2.0)                                   
==30637==    by 0x4B965CB: XSetWMProperties (in /usr/lib/libX11.so.6.2.0)                              
==30637==    by 0x4249BA0: QWidgetPrivate::create_sys(unsigned long, bool, bool) (in /usr/lib/libQtGui.so.4.5.3)
==30637==    by 0x420F63B: QWidget::create(unsigned long, bool, bool) (in /usr/lib/libQtGui.so.4.5.3)           
==30637==    by 0x420A8B2: QWidgetPrivate::createWinId(unsigned long) (in /usr/lib/libQtGui.so.4.5.3)           
==30637==    by 0x420EFDA: QWidgetPrivate::setWindowTitle_helper(QString const&) (in /usr/lib/libQtGui.so.4.5.3)
==30637==    by 0x420F431: QWidget::setWindowTitle(QString const&) (in /usr/lib/libQtGui.so.4.5.3)              
==30637==    by 0x8059700: xdog::retranslateUi() (xdog.cpp:295)                                                 
==30637==    by 0x805A944: xdog::setupUi() (xdog.cpp:271)                                                       
==30637==    by 0x80526D3: xdog::xdog() (xdog.h:156)                                                            
==30637==    by 0x805153A: main (main.cpp:133)
==30637==  Address 0x1 is not stack'd, malloc'd or (recently) free'd
==30637==
==30637== Process terminating with default action of signal 11 (SIGSEGV)
==30637==  Access not within mapped region at address 0x1
==30637==    at 0x40284E8: strlen (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==30637==    by 0x4B91CE6: XSetCommand (in /usr/lib/libX11.so.6.2.0)
==30637==    by 0x4B965CB: XSetWMProperties (in /usr/lib/libX11.so.6.2.0)
==30637==    by 0x4249BA0: QWidgetPrivate::create_sys(unsigned long, bool, bool) (in /usr/lib/libQtGui.so.4.5.3)
==30637==    by 0x420F63B: QWidget::create(unsigned long, bool, bool) (in /usr/lib/libQtGui.so.4.5.3)
==30637==    by 0x420A8B2: QWidgetPrivate::createWinId(unsigned long) (in /usr/lib/libQtGui.so.4.5.3)
==30637==    by 0x420EFDA: QWidgetPrivate::setWindowTitle_helper(QString const&) (in /usr/lib/libQtGui.so.4.5.3)
==30637==    by 0x420F431: QWidget::setWindowTitle(QString const&) (in /usr/lib/libQtGui.so.4.5.3)
==30637==    by 0x8059700: xdog::retranslateUi() (xdog.cpp:295)
==30637==    by 0x805A944: xdog::setupUi() (xdog.cpp:271)
==30637==    by 0x80526D3: xdog::xdog() (xdog.h:156)
==30637==    by 0x805153A: main (main.cpp:133)
Die besagte Zeile xdog.cpp:295 enthält jediglich ein setWindowTitle, und wenn ich das weglasse, tritt der gleiche Fehler woanders auf ( QWidget::show() ).

Was mache ich hier falsch?

Verfasst: 31. Oktober 2009 15:42
von Christian81
1. argc muss eine Referenz sein
2. Wo rufst du nicht QApplication::notify() auf? Reimplementieren heisst icht dass die Base-Class nicht aufgerufen werden muss...

Verfasst: 31. Oktober 2009 16:06
von D.Cent
Ok danke - jetzt geht es.

Verfasst: 6. November 2009 10:48
von plip
Ich hab das gleiche Problem.
Mir ist nur nicht klar, wie ich dann in der notify Funktion eine Exception abfange. Wie hast Du das gemacht?

Verfasst: 6. November 2009 11:13
von plip
Habe das hier gefunden


Let's give you an example:

bool MyApplication::notify( QObject *o, QEvent *e )
{
try
{
return QApplication::notify(o, e);
}
catch(...)
{
// error box
}
}

notify is a fine place for catching exceptions, but between throwing the
exception and MyApplication::notify the exception has to pass
QApplication::notify what is in the Qt lib which is compiled without
exception handling -> segfault.

Throw/catch with gcc only works if there is nothing in between on the stack,
compiled without exception handling. But in a framework like Qt you will
always pass code of the base classes.
Funktioniert bei mir aber nicht. Wenn ich aus einem Plugin (.dll) eine Exception schmeiße, schmiert meine Applikation ab.