PDA

View Full Version : Posting customeEvent using postEvent crashes Windows but works on Ubuntu Linux



cqubed
19th October 2012, 21:39
I have a simple Qt application with two threads a main thread and a worker thread. The main thread supports a QApplication, QMainWindow. The QMainWindow has a textEdit widget. I have sub-classed QEvent to create a MyCustomEvent. MyCustomEvent has a QString member. I have overridden "customEvent" in the QMainWindow object. My "customEvent" method uses insertPlainText to insert the text contained in the QString into the textEdit widget.

I am attempting use"QCoreApplication:: postEvent to post "MyCustomEvent"s from both the worker thread and the main thread.

My problem is: This works really nicely when the program is compiled and run on Ubuntu Linux. It crashes on every exit from my customEvent mentod when compiled and run as a 32-bit windows app from Visual Studion 2010 Qt add-in on 64 bit Windows 7.

The crash occurs after the overridden customEvent method is called. It occurs immediately after the destructor for MyCustomEvent is called. The crash occurs in PostMessageEvent::~PostMessageEvent() short after PostMessageEvent::'scalar deleting destructor', operator delete:, _RTC_CheckEsp.

I have checked my allocation of MyCustomeEvent carefully. It is allocated on the heap, NOT on the stack. The QString it contains is allocated on the heap and is deleted by ~MyCustomEvent.

Note I originally tried using cross thread slots and signals to achieve the communication between the worker thread and gui thread, but again on Windows it crashed every time. I switched to posted events to try and get a working app.
:(

wysota
19th October 2012, 21:57
What does the worker thread do?

cqubed
19th October 2012, 22:11
The worker thread reads a file (Rockwell PLC program file in L5K format), parses it and writes an output file.
postEvent crashes customEvent handler even when called from gui thread.

wysota
20th October 2012, 00:17
Can we see the event handler? Are you sure you are not deleting the event object yourself?

cqubed
20th October 2012, 01:16
To anyone who might be able to help.
Here is the code.

I repeat, this runs fine when build under Ubuntu Linux.
It givers SIGSEGV on first exit from customEvent when built on Windows 7 64 bit machine as a 32 bit windows app using Visual Studio 2010, Qt OpenSource 4.8.3, Qt Visual Studio-Addin 1.1.11.

The SIGSEGV comes from the event destructor, but I can't figure out why its happening and why it doesn't happen on Linux.

wysota
20th October 2012, 08:55
Why are you storing a pointer to a string in the event? Why not a real object? There is a good chance that if you correct this, your program will stop crashing.

cqubed
20th October 2012, 12:05
Thanks for the tip, but I've already tested that. In one version of the program I removed QString* and everything else from the event. It still crashes.
Note, in version I posted the QString is allocated on the heap and I delete it in the destructor of my over-riding virtual customEvent method. That delete doesn't crash.
The crash seems to be occurring when the Qt library deletes the event. This crash occurs even if I declare my custom event to be exactly like a standard event.

wysota
20th October 2012, 12:48
Note, in version I posted the QString is allocated on the heap and I delete it in the destructor of my over-riding virtual customEvent method.
What if one calls setMsg more than once?


The crash seems to be occurring when the Qt library deletes the event. This crash occurs even if I declare my custom event to be exactly like a standard event.

Please post a minimal compilable example reproducing the problem.

BTW. Isn't your thread accessing the main window subclass?

cqubed
20th October 2012, 13:02
What if one calls setMsg more than once?
Please post a minimal compilable example reproducing the problem. BTW. Isn't your thread accessing the main window subclass?

If setMsg is called more than once, application will leak memory, but this won't cause crash.
Is my worker thread accessing main window subclass?
I'll check, but don't think so.

wysota
20th October 2012, 13:41
Is my worker thread accessing main window subclass?
It is.

Furthermore if you pass a string pointer to the constructor of the event, it will potentially cause a double delete because you are storing a pointer to the string as-is, without making a copy of the string that you later delete in the destructor.

I suggest you simplify your code as much as possible, then it will be much simpler to find the problem. For instance this:


void writeWin(QString *msg) {
if (( m_PtrWorkerThread != NULL) && (QThread::currentThread()== m_PtrWorkerThread)) {
while(m_MustWait) {
#ifdef WIN32
Sleep(1);
#else
usleep(10);//1,000,000 in sec
#endif
}
{
m_MustWait = true;
m_PtrMsg = msg;
PostMessageEvent *ptr_msgEvent = new(PostMessageEvent);
ptr_msgEvent->m_ptrPostingThread=QThread::currentThread();
ptr_msgEvent->setMsg(msg);
QCoreApplication::postEvent ( this, ptr_msgEvent);

}
} else
{
// m_MustWait = true;
PostMessageEvent *ptr_msgEvent = new(PostMessageEvent);
ptr_msgEvent->m_ptrPostingThread=QThread::currentThread();
ptr_msgEvent->setMsg(msg);
QCoreApplication::postEvent ( this, ptr_msgEvent);

}
};

can be written as this (I don't know why you sleep for a couple of seconds here so I ignored that part):


void writeWin(const QString& msg) {
PostMessageEvent *ptr_msgEvent = new(PostMessageEvent);
ptr_msgEvent->setMsg(msg);
ptr_msgEvent->m_ptrPostingThread=QThread::currentThread(); // optionally, if you really need it
QCoreApplication::postEvent ( this, ptr_msgEvent);
};

or better yet just use signals and slots (properly). If you have to "wait", then use a wait condition instead of a busy loop.

cqubed
20th October 2012, 16:40
:confused:
Just for jollies, I took my test program (previously posted on this thread) and created an MS install package. I then installed the test program on an old lap top I have running Windows XP. Guess what it ran perfectly. No issues. So the crash only happens when the program is run on Windows 7 64 bit in WOW64, the x86 emulator that allows 32-bit Windows-based programs to run in 64-bit OS.

I'm off to the gym to tone my body and clear my head and then I'll revisit this.

wysota
20th October 2012, 17:22
Try this:


#include <QtCore>

class Event : public QEvent {
public:
Event() : QEvent(QEvent::User) {}
};

class Thread : public QThread {
public:
Thread() : QThread() {}
void run() {
forever {
sleep(1);
QCoreApplication::postEvent(qApp, new Event);
}
}
};

class Application : public QCoreApplication {
public:
Application(int &argc, char **argv) : QCoreApplication(argc, argv) {}
protected:
void customEvent(QEvent *e) {
if(e->type() == QEvent::User) { qDebug() << "Received event";}
QCoreApplication::customEvent(e);
}
};

int main(int argc, char **argv) {
Application app(argc, argv);
Thread t;
t.start();
return app.exec();
}

cqubed
20th October 2012, 19:32
:o I consider this resolved. Thanks.
a. I'll clean up my code and try your snippit.
b. The crash only occurs under WOW64 so I'm going to attribute it to a problem in WOW64 or Qt libraries in that environment.
c. It may be there is some heap corruption in the application so I'll continue to clean up and slim down the test case.

In the mean time if anyone else see's SIGSEGV or other funny behavior running 32-bit Qt 4.8.3 Windows apps in WOW64 please post the circumstances.

cqubed
22nd October 2012, 16:23
I think my issue may be related to this Qt bug

[#QTBUG-17230] QPlainTextEdit corruption/crash after scrolling

This bug is reported for WOW64.

My crash does involves a textEdit object. It doesn't specifically involve scrolling, but possibly they are related.

wysota
22nd October 2012, 17:08
Try posting a debugger backtrace. Maybe we can fix it somehow.

cqubed
9th November 2012, 19:07
:) I resolved the problem.
Issue was caused by Input property on Visual Studio 2010 property page being set incorrectly. Somehow I had mixed Windows Qt debug libraries and non-debug libraries in the same link. When I cleaned this up, ie. used all debug libraries in debug configuration and all non-debug libraries in release configuration my program started running perfectly in WOW64. I'm a little mystified. I can see how mixing libraries might cause a crash but I'm somewhat mystified as to why it worked in XP and other Win-32 environments and crashed in WOW64.
Anyway it was definitely my problem and not a Windows or Qt problem. So far I'm very impressed with cross platform features of Qt. Its a great framework.