QProcess killed with SIGPIPE
-
I did the following two replacements:
@
// emit frameReady(); // will eventually invoke frameHandler()
QTimer::singleShot(0, this, SLOT(frameHandler()));
@
and
@
// emit wantNewFrame(); // will eventually invoke readFrame()
QTimer::singleShot(0, this, SLOT(readFrame()));
@The problem persists.
-
Another test came to my mind: to check whether I had any problems with the way I'm using signals and slots, I replaced QProcess with QFile and opened /dev/zero directly. This worked fine. I also tried opening a FIFO (named pipe) that had a "cat /dev/zero" running on the other end. This also worked fine.
I am beginning to think that I might have hit some kind of a bug in QProcess.
-
Thank you for the suggestion, but I think that one should resort to ignoring signals only when there exists a good reason for doing so. In my opinion, ignoring SIGPIPE in this particular case would just serve to cover up a potentially deeper problem.
Besides that, it does not work. I tried substituting the "cat /dev/zero" process with the following small program:
@
#include <cstdio>
#include <csignal>int main() {
signal(SIGPIPE, SIG_IGN);
while (true)
putc('A', stdout);
return 0;
}
@The proces does not die in this case (because it ignores SIGPIPE), but after outputting a few frames, putc() suddenly fails with EPIPE (i.e., "Broken pipe").
The essential problem therefore does not lie in the process being killed with SIGPIPE, but rather in Qt closing the pipe to the subprocess, which causes SIGPIPE to be sent. However, the question remains: why does Qt close the pipe?
-
What QProcess::ProcessChannelMode have you set? Maybe try a different one then?
http://qt-project.org/doc/qt-4.8/qprocess.html#ProcessChannelMode-enum
-
I did not set the channel mode explicitly, because it is set to QProcess::SeparateChannels by default; and that's exactly what I need. The other two modes are not suitable for me: I need to capture the data on process' stdout (which rules out QProcess::ForwardedChannels) and not mix in anything else (which rules out QProcess::MergedChannels).
-
As I said, this is a minimal non-working example intended to demonstrate an issue that I am facing in the context of a larger application. It is not meant to do anything useful. The "cat /dev/zero" command only serves here as a convenient source of data; in reality, this command would be replaced with another process that outputs raw video frames.
Since I need to capture the command's output, there is no point in setting QProcess::ForwardedChannels as that would cause the output of the QProcess to be forwarded directly to the standard output of the parent application. There would be no way of capturing it then.
-
[quote author="alajovic" date="1365361656"]It is not meant to do anything useful.[/quote]
Okay, I see.
[quote author="alajovic" date="1365361656"]there is no point in setting QProcess::ForwardedChannels as that would cause the output of the QProcess to be forwarded directly to the standard output of the parent application. There would be no way of capturing it then.[/quote]
The point is not to get your program working, but to track down the problem. Then, if it turns out something is wrong inside Qt, get the bug fixed. I think it would be interesting to know whether this is related to redirecting the standard streams...
-
Okay, it's an easy test anyway.
I tried putting
@
process.setProcessChannelMode(QProcess::ForwardedChannels);
@before process.start(). The subprocess then ran uninterrupted and its standard output was forwarded to the standard output of the test application. Meanwhile, the application itself was blocking on process.waitForReadyRead() call (line 40 in my original post).