QMainWindow::show() crashes if QSharedMemory object was created



  • Hi all and happy Christmas coding!
    I see strange behavior if I include shared memory in my application. main.ccp is straight forward:

    int main(int argc, char *argv[])
    {
    	pi_at_home::PiaApp a(argc, argv);
    	a.setApplicationName("PiAtHome");
    	a.setOrganizationName("me");
    	a.setOrganizationDomain("here.there");
    	pi_at_home::MainWindow w;
    	w.show();
    	return a.exec();
    }
    

    with MainWindow deriving from QMainWindow in the usual way:

    namespace Ui
    {
    	class MainWindow;
    }
    
    namespace pi_at_home
    {
    class MainWindow : public QMainWindow
    {
    	Q_OBJECT
    public:
    	explicit MainWindow(QWidget *parent = 0);
    	~MainWindow();
    private slots:
    	void about();
    private:
    	Ui::MainWindow *ui;
    	QTextEdit *central;
    };
    }
    
    

    In PiaApp I would like to use a QSharedMemory object and I do

    class QSharedMemory;
    namespace pi_at_home
    {
    class PiaApp : public QApplication
    {
    	Q_OBJECT
    public:
        PiaApp(int argc, char *argv[]);
        virtual ~PiaApp();
        virtual bool notify ( QObject * receiver, QEvent * event );
    	//bool attachIpc();
    private:
    	QSharedMemory *shm;
    };
    } 
    

    implementation:

    #include "piaapp.h"
    #include <QSharedMemory>
    #include "piai.h"
    
    PiaApp::PiaApp(int argc, char *argv[]) : QApplication(argc, argv), shm(new QSharedMemory("PiAtHomeIPC", this))
    {
    	qDebug()<<"shared error (ctor): "<<shm->errorString();
    }
    
    PiaApp::~PiaApp()
    {
    	if(shm && shm->isAttached())
    		shm->detach();
    }
    
    bool PiaApp::notify ( QObject * receiver, QEvent * event )
    {
    	bool res=true;
    	try
    	{
    		return QApplication::notify(receiver, event);
        }
    	catch(Ex & ex)
    	{
    		qDebug()<<"Exception catched: "<<ex.getCode()<<" "<<ex.getMessage();
    	}
    	catch(...)
    	{
    		qDebug()<<"unknwon exception catched";
    	}
        return res;
    }
    
    

    This application crashed in main when entering w.show() with SIGSEGV. Qt is a release build, so I can't debug into show().

    Starting /home/me/SW/devel/Pi_at_home/build-pia-Desktop-Debug/pia...
    shared error (ctor):  ""
    DataContainer created
    command id base  "00:24:54:FF:FF:FF"   1482666682
    The program has unexpectedly finished.
    /home/me/SW/devel/Pi_at_home/build-pia-Desktop-Debug/pia crashed.
    

    The funny this is, if I initialize shm with nullptr

    PiaApp::PiaApp(int argc, char *argv[]) : QApplication(argc, argv), shm(nullptr) // new QSharedMemory("PiAtHomeIPC", this)
    {
    	//qDebug()<<"shared error (ctor): "<<shm->errorString();
    }
    
    

    everything works fine!
    There is not a single reference to the pointer shm anywhere in my application and it's private in PiaApp anyway.
    Does anyone have an idea what's going wrong here?
    Qt5.6.2 on Ubuntu 16.04
    Thanks!


  • Lifetime Qt Champion

    Hi,

    Do you mean that it doesn't happen in debug mode ?

    What else are you doing with that QSharedMemory ?


  • Qt Champions 2016

    To add to @SGaist, could you please attach the backtrace from the crash. That usually helps in deducing what the problem is.



  • @kshegunov: This is the backtrace - somewhere deep inside window creation

    1  strlen                                                     strlen.S 106 0x7ffff57e4b96 
    2  QCoreApplication::arguments()                                           0x7ffff632b54d 
    3  ??                                                                      0x7fffeed3f74f 
    4  QXcbIntegration::wmClass() const                                        0x7fffeed3fc1e 
    5  QXcbWindow::create()                                                    0x7fffeed540ab 
    6  QXcbIntegration::createPlatformWindow(QWindow *) const                  0x7fffeed3f4c1 
    7  QWindowPrivate::create(bool)                                            0x7ffff6e675dd 
    8  QWidgetPrivate::create_sys(unsigned long long, bool, bool)              0x7ffff76ec893 
    9  QWidget::create(unsigned long long, bool, bool)                         0x7ffff76ec019 
    10 QWidget::setVisible(bool)                                               0x7ffff76f7ea2 
    11 main                                                       main.cpp 13  0x409d62       
    
    


  • @stryga42 said in QMainWindow::show() crashes if QSharedMemory object was created:

    @kshegunov: This is the backtrace - somewhere deep inside window creation

    1  strlen                                                     strlen.S 106 0x7ffff57e4b96 
    2  QCoreApplication::arguments()                                           0x7ffff632b54d 
    3  ??                                                                      0x7fffeed3f74f 
    4  QXcbIntegration::wmClass() const                                        0x7fffeed3fc1e 
    5  QXcbWindow::create()                                                    0x7fffeed540ab 
    6  QXcbIntegration::createPlatformWindow(QWindow *) const                  0x7fffeed3f4c1 
    7  QWindowPrivate::create(bool)                                            0x7ffff6e675dd 
    8  QWidgetPrivate::create_sys(unsigned long long, bool, bool)              0x7ffff76ec893 
    9  QWidget::create(unsigned long long, bool, bool)                         0x7ffff76ec019 
    10 QWidget::setVisible(bool)                                               0x7ffff76f7ea2 
    11 main                                                       main.cpp 13  0x409d62       
    
    

    Well according to this the crash doesn't have anything to do with the shared memory but instead with the argv pointer. Try taking arguments of char **argv instead of char *argv[] for your application and passing it in that way instead of creating an array with it.

    If that fails, qDebug the value of argv and argc and let us see those at your PiApp level.



  • @SGaist: No, the app crashes in debug and release mode. It only depends on the construction of the QSharedMemory Object. That's the funny thing - I do not do anything with the QSharedMemory instance except creating it - it it still makes the QMainWindow::show crash although these two objects look totally unconnected to me.
    A weired idea: Maybe the QXcb... is internbally messing with shared memory a can for some reason not deal with my object created earlier.

    I also tried to initialize the QSharedMemory * memenber with an intentinally invalid pointer like reinterpret_cast<QSharedMemory *>(1234). No problem, app starts and runs fine. As expected, since I never use / dereference the pointer.



  • @ambershark : Moving to **argv did not help, but trying to qDebug() the values was the (partial) jackpot:
    As soon as i write the values of argv to the debug console and run in debug mode, the app start fine. qDebug() in release mode prints the same values but the app crashes. The argv values are quite uninteresting, just the executable path, as usual:

    Starting /home/me/SW/devel/Pi_at_home/build-pia-Desktop-Debug/pia...
    PiaApp ctor: argc  1
    argv[ 0 ] /home/me/SW/devel/Pi_at_home/build-pia-Desktop-Debug/pia
    DataContainer created
    command id base  "00:24:54:EC:D5:C3"   1482867947000000000
    ...more messages while the app runs...
    

    when stared in release mode:

    Starting /home/me/SW/devel/Pi_at_home/build-pia-Desktop-Release/pia...
    PiaApp ctor: argc  1
    argv[ 0 ] /home/me/SW/devel/Pi_at_home/build-pia-Desktop-Release/pia
    DataContainer created
    command id base  "00:24:54:EC:D5:C3"   1482868156000000000
    The program has unexpectedly finished.
    /home/dwk/SW/devel/Pi_at_home/build-pia-Desktop-Release/pia crashed.
    

    And if i do a strlen(argv[0]); during startup, it even runs in release mode. No idea why. A bug inside the handling of command line arguments? Do these args use shared memory?


  • Lifetime Qt Champion

    What if you move the QSharedMemory handling any our main function rather than in your QApplication subclass ?



  • @stryga42 Also, what happens if you create the shared memory object without a key.. i.e. new QSharedMemory().

    Since the argv stuff is working on strlen outside the arguments() call i'd guess that #3 in your backtrace is your stack being smashed. So the stuff following that isn't accurate any more anyway. Just a guess but it makes sense with the ?? and the fact that crashes are happening on things that are definitely tested valid.



  • @stryga42 I found the issue I think.. You are passing an int that is destroyed through to QCoreApplication. Here is the definition of that function:

    QCoreApplication(int &argc, char **argv)

    So it takes a reference to an int, and according to the docs that int must remain valid throughout the life of the program. As soon as your custom app constructor exits your int is no longer valid. Then QSharedMemory is using the arguments() function which tries to use the argc that is no longer valid. Crash!

    Make sure you pass by reference from the argc in main and it should be ok. I would change your pointers for argv to char **argv as well rather than using the char *argv[].

    As for QCoreApplication using an int reference, I don't like that one bit. Not quite sure why they designed it that way.

    That should fix it for you. :)


  • Qt Champions 2016

    Excellent eye!
    Cheers!



  • @ambershark You are right! Many thanks, very good input. Using int & argc in my constructor solves the problem.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.