PDA

View Full Version : QThread stack overflow when exiting



jakamph
10th May 2006, 20:24
Hi all. I'm using QT 3.3.1 on Windows and have an application with a QThread object. An exit command could come from 2 different places: the user closing the window or an external application that I'm hooking to exiting.

The child thread is responsible for communicating with the external app and posting when the exit has occurred. I have 2 booleans to indicate where the exit command has come from. If the exit command came from the GUI, then guiCommandedExit is set to true. If the exit came from the external app, then externalCommandedExit is set to true. Before checking/setting either of those flags, I do a myMutex.lock( ). After the check/set, I do myMutex.unlock( ).

The problem that I'm running into is that when the exit event occurs (through the GUI), I'm getting a large number of "First-chance exception in [my_app].exe" along with a stack overflow notice. This is the first time I've done anything with threads since Operating Systems 1 in college, so forgive me if I'm missing something obvious. Any help that can be provided is appreciated. Thanks in advance.




class MyThread
{

public:
void run( );

};

MyThread::run( )
{

while ((!/*externally commanded exit*/) && (!guiCommandedExit))
{

/* communicate with the external app */

}/* end while no exit */

myMutex.lock( );

if (!guiCommandedExit)
{

/* post to close the GUI */
externalCommandedExit = true;

}

myMutex.unlock( );

}/* end ::run */

void
MainGui::closeEvent( QCloseEvent* event )
{

myMutex.lock( );

if (!externalCommandedExit)
{

guiCommandedExit = true;

myMutex.unlock( );

myThread->wait( );

}

QApplication::exit( 0 );

event->accept( );

}/* end ::closeEvent */

wysota
11th May 2006, 00:18
Hard to say, as this code doesn't do much, but you have (at least) one mistake here:


MainGui::closeEvent( QCloseEvent* event )
{
myMutex.lock( );
if (!externalCommandedExit)
{
guiCommandedExit = true;
myMutex.unlock( );
myThread->wait( );
}
QApplication::exit( 0 );
event->accept( );
}/* end ::closeEvent */
What happens if externalCommandedExit is true? mutex will never be unlocked... The thread locks the mutex too, so it might create a deadlock (on MyThread->wait()).

But as I said, hard to say without seeing the rest of the code.

BTW. Think about redesigning your code, there are surely simpler ways to do what you want.

jakamph
11th May 2006, 14:13
Hard to say, as this code doesn't do much, but you have (at least) one mistake here:


MainGui::closeEvent( QCloseEvent* event )
{
myMutex.lock( );
if (!externalCommandedExit)
{
guiCommandedExit = true;
myMutex.unlock( );
myThread->wait( );
}
QApplication::exit( 0 );
event->accept( );
}/* end ::closeEvent */
What happens if externalCommandedExit is true? mutex will never be unlocked... The thread locks the mutex too, so it might create a deadlock (on MyThread->wait()).

But as I said, hard to say without seeing the rest of the code.

BTW. Think about redesigning your code, there are surely simpler ways to do what you want.

Thanks for the reply. You are correct that I had that line wrong. Thanks for pointing it out. However, I haven't been trying to kill the program through the external application yet, so that shouldn't be coming into play. I built and ran on UNIX and it exited without a problem.

wysota
11th May 2006, 16:21
I guess you shouldn't call QApplication::exit() from the close event. If you accept the event and make sure the app gets closed when this particular window closes, you'll achieve the same effect.

jakamph
11th May 2006, 17:56
After much beating of heads against walls, I found that I was reaching my return statement at the end of my main function and the exceptions being thrown occurr in one of the Windows DLL's. With the help of a friend of mine here at work, we compared Makefiles between a multi-threaded application that wasn't QT and the qmake-generated Makefile. It turns out that the qmake-generated Makefile had the compiler option set for it to have been built as a DLL instead of an executable, so we changed the CFLAGS and CXXFLAGS from -MDd to -MTd along with adding /nodefaultlib:"msvcrt.lib" to the LFLAGS. This seemed to fix the problem. Is this a known problem? I do have TEMPLATE: app in my .pro.

Thanks for your help.