theta
theta

Reputation: 11

QProcess: Destroyed while process is still running

I am using Qt for developing a custom control interface to xmgrace, a 2D plotting library. I have 3 components in my project:

  1. A GUI made in Qt
  2. A QThread which runs some shared object code from C in a background thread.
  3. An xmgrace window connected to both the above using a pipe. (Using the grace_np library)

Communication from (1) --> (2) is done by changing status of some global variables declared in the shared object code.

Communication from (1) --> (3) & (2) --> (3) is using built in functions provided by the grace_np library.

Now, communication from (2) --> (1) is what is causing problems. I tried 2 possible ways I could think of: a) Declaring a shared object in Qt code which emits a Qt Signal and is called within the C code. b) Returning from the thread and using the return value to perform some operation and then restart the thread.

Both these methodologies have given unreliable results. My GUI gets stuck/causes segmentation fault and I get the message:

QProcess: Destroyed while process is still running

I am not using the QProcess class anywhere in my code. So this has become a mystery. Please provide some info on what could be the possible causes for this.

PS: The pipe to (3) is one way and is required that way only.

Edit 1:

FYI I'm using Qt 4.2, So I can't use the QObject approach and then use a movetothread() I'm sorry for not putting the code, as I can't due to company policies and also because I don't know what to put (Its too huge). The shared c code is 400k+ lines

I believe I have found the culprit to my problem. It seems that using the class QMessageBox is causing this problem. I was initially using static function of QMessageBox. Now I have tried declaring it over both the stack and the heap, but the problem still persists. But I have found that removing all calls to QMessageBox from my code solves the problem. But then the problem now is, how do I show messages? I am just speculating here, but is it possible that the modal nature of QMessageBox is blocking the pipe existing between my program and xmgrace and subsequently causing it to quit? Then creating a custom QMessageBox (non modal) might solve this issue.

Edit 2:

I'm not calling the QMessageBox from the worker thread. Plus the way I'm using the worker thread, it never returns unless I close the program. To give an idea my QThread::run function is of the form:

QThread_Object::run()
{
  c_init();
  c_main();
}

where c_init & c_run are functions linked from shared c code. So it is impossible to call a QMessageBox from within these directly. For now I'm planning on doing away with the QMessageBox and using the QMainWindow status bar instead. But then it doesn't give the entire functionality. I suppose this could be a bug in Qt 4.2

Edit 3:

I mentioned earlier that communication from (2) --> (1) was what was causing problems. Now I have done away with this communication completely and have discovered more precisely that the problem is caused by invoking QMessageBox anytime after starting the worker thread. Earlier the communication mentioned above was causing Qt to emit a signal indirectly and invoke a QMessageBox which I believe was the culprit.

Edit 4:

Ok, I forgot to mention the biggest mystery surrounding this problem since the beginning. I basically work(Place A) via ssh on a workstation(Place B) on which I code and run this program. B is connected on 2 physical networks. A is connected to B through Network 1. Now this problem has never occured while working from my terminal at A (ie on ssh via Network 1). But it consistently occurs when I access B directly or through ssh over Network 2. Please note that every time the code is executed on B only. Both these networks are used by hundereds.

Edit 5

Finally, I have solved my problem by sub-classing QDialog and making a custom MessageBox as I don't really require the extended functionality of QMessageBox. I still don't know what precisely within QMessageBox was causing the problem. I suppose some bug within Qt which will always remain a mystery.

Upvotes: 1

Views: 3394

Answers (1)

Phlucious
Phlucious

Reputation: 3843

Since there's no code I'm shooting in the dark a little here, but it sounds like your QProcess was created on the stack, intentionally or not, or your QThread is getting destroyed prematurely. I'd put money on your QThread objects being launched incorrectly. It's hard to blame you since the documentation is (or was until recently) screwy. Consider reading this thread and this thread and don't sub-class QThread at all.

Edit: If QMessageBox is your culprit, then I'm guessing that you're displaying it from the child thread. From the documentation:

In GUI applications, the main thread is also called the GUI thread because it's the only thread that is allowed to perform GUI-related operations.

There are several ways to display messages from a child thread. Personally, I use qt's error reporting scheme and redirect qCritical, qDebug, etc to stderr. Another easier way to do it would be for you to emit a QString signal from your worker thread that's caught by your GUI thread, which then displays/collects the error. I like to have my MainWindow collect the errors and then display them all at once when the worker thread finishes.

Edit 2: Since the problem seems to be QMessageBox being modal (i.e., blocking your main thread while the worker thread moves forward), you can easily solve this by using QMessageBox in its non-modal modes. Simply pass 0 as the parent widget in the QMessageBox constructor/static function. Processing will continue without waiting for the user to exit the window--this might also result in multiple message boxes being open at the same time. If that helps you avoid the error, go over your code carefully to make sure the windows are properly destroyed after closing.

Upvotes: 1

Related Questions