Solved 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! -
Hi,
Do you mean that it doesn't happen in debug mode ?
What else are you doing with that QSharedMemory ?
-
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 ofchar *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?
-
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 thechar *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. :)
-
Excellent eye!
Cheers! -
@ambershark You are right! Many thanks, very good input. Using
int & argc
in my constructor solves the problem. -
@ambershark
Thank you for spotting this one. I have recently faced this same crash and your suggestion helped fixing it.