Results 1 to 4 of 4

Thread: Problem using QProcess on Windows XP

  1. #1
    Join Date
    Apr 2010
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Problem using QProcess on Windows XP

    Hi, all

    I am trying to write a small program that allows running command line programs and places the standard input, standard output and standard error streams in three distinct QPlainTextEdit widgets for easy editing (I am using this as a simple utility for running different command line programs, e.g. gcc, make, sed etc.). What I do is arrange when a certain action occurs (a button press or hitting enter after a command to run has been entered) to create a new QProcess, I connect slots to get called when there is data on stdout or stderr, and another slot to get notified when the process finishes. I then start() the QProcess, and after having waitForStarted(), I write what I have in the stdin QPlainTextEdit pane to the QProcess, and then I closeWriteChannel(). Here are the guts of the code:

    Qt Code:
    1. void MainWindow::requestRun(void)
    2. {
    3. if (proc)
    4. return;
    5. proc = new QProcess(this);
    6. connect(proc, SIGNAL(finished(int)), this, SLOT(processFinished()));
    7. connect(proc, SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStdout()));
    8. connect(proc, SIGNAL(readyReadStandardError()), this, SLOT(readyReadStderr()));
    9. ui->pushButtonRun->setEnabled(false);
    10. proc->setWorkingDirectory(workdir.absolutePath());
    11. if (ui->checkBoxMergeOutputs->isChecked())
    12. proc->setProcessChannelMode(QProcess::MergedChannels);
    13.  
    14. proc->start(ui->comboCmdLine->currentText());
    15.  
    16. if (!proc->waitForStarted(-1))
    17. {
    18. ui->pushButtonRun->setEnabled(true);
    19. QMessageBox::critical(this, "error", "error running command");
    20. proc->deleteLater();
    21. proc = 0;
    22. return;
    23. }
    24. if (proc)
    25. {
    26. ui->plainTextEditStdout->clear();
    27. proc->write(ui->plainTextEditStdin->toPlainText().toAscii().constData());
    28. /*! \warning it is possible that the processFinished()
    29.   * slot gets invoked prior to returning from
    30.   * the QProcess::waitForBytesWritten(-1) call
    31.   * below; as processFinished() deletes the 'proc'
    32.   * variable (and resets it to a null pointer),
    33.   * the 'proc' pointer below must be checked if
    34.   * usable */
    35. /*! \todo strange... this below - if toggled between
    36.   * 'if (1) ...' / 'if (0) ...'
    37.   * causes some thread lockup in the qt code... strange thing
    38.   * is, on three different machines it behaves in three
    39.   * different ways; summarized:
    40.   *
    41.   * if (0) proc->waitForBytesWritten(-1);
    42.   *
    43.   * - on a core2 quad machine - does not hang
    44.   * - on a core2 duo machine - does not hang
    45.   * - on a single core pentium4 - DOES hang
    46.   *
    47.   * if (1) proc->waitForBytesWritten(-1);
    48.   *
    49.   * - on a core2 quad machine - DOES hang
    50.   * - on a core2 duo machine - does not hang
    51.   * - on a single core pentium4 - does not hang
    52.   *
    53.   * test platforms:
    54.   * - core2 quad - os windows xp pro, tested with qt2009.05 and qt2010.02.1
    55.   * - core2 duo - os windows xp pro, qt2009.05
    56.   * - single core pentium4 - os windows xp home, qt2009.05
    57.   *
    58.   * when gdb is attached (via qt-creator) to the locked-up process,
    59.   * all threads seem to be waiting on events (via waitforsingleobject()),
    60.   * only one thread seems to have invoked sleepex(), but unluckily
    61.   * gdb seems unable to unwind back to the program to see the locations
    62.   * of the calls in the source code; i tried single stepping on the
    63.   * core2 quad machine, and it seems the lock-up occurs when in
    64.   * qprocess.cpp, around line 820 - in qprocessprivate::cleanup() - when
    65.   * calling 'destroyPipe(stdinChannel.pipe);' - but take this as only a
    66.   * very rought estimate, i may well be very wrong... i really did not get
    67.   * any far when trying to debug this...
    68.   *
    69.   * i guess this all is some inter-thread synchronization problem, on the
    70.   * core2 quad it seems easiest to hang the program - just paste some text
    71.   * in the left textedit pane, enter some command in the combobox - i tested with
    72.   * 'gcc' and hold down the 'enter' button so that gcc is continuously invoked;
    73.   * the program hangs almost immediately... on the core2 duo i did not manage to
    74.   * hang the program, and on the single core the program hangs when it doesn't
    75.   * on the core2 quad... go figure... */
    76. if (1) proc->waitForBytesWritten(-1);
    77. if (!proc)
    78. {
    79. }
    80. else
    81. {
    82. proc->closeWriteChannel();
    83. }
    84. }
    85. }
    86.  
    87. void MainWindow::processFinished(void)
    88. {
    89. ui->pushButtonRun->setEnabled(true);
    90. while (!proc->atEnd())
    91. {
    92. //qDebug() << "waiting for end";
    93. //Sleep(500);
    94. }
    95. ui->plainTextEditStderr->appendPlainText(proc->readAllStandardError());
    96. ui->plainTextEditStdout->appendPlainText(proc->readAllStandardOutput());
    97. proc->deleteLater();
    98.  
    99. proc->write(ui->plainTextEditStdin->toPlainText().toAscii().constData());
    100.  
    101. proc = 0;
    102. }
    103.  
    104. void MainWindow::readyReadStdout(void)
    105. {
    106. ui->plainTextEditStdout->appendPlainText(proc->readAllStandardOutput());
    107. }
    108.  
    109. void MainWindow::readyReadStderr(void)
    110. {
    111. ui->plainTextEditStderr->appendPlainText(proc->readAllStandardError());
    112. }
    To copy to clipboard, switch view to plain text mode 

    You can find the complete project as an attachment to this message.

    Now, my problem is that on three different machines this code behaves in three different ways and I am absolutely at a loss at what I could be doing wrong... The program hangs on some machines (and on some doesn't) - how to hang the program is detailed in the comments in the code above.

    Any comments, advices and assistance on solving this problem are very much appreciated!

    Thanks!

    Stoyan Shopov
    Attached Files Attached Files

  2. #2
    Join Date
    Apr 2010
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Problem using QProcess on Windows XP

    Sorry, in the code I have posted, the line just above the big comment block reads:

    Qt Code:
    1. proc->write(ui->plainTextEditStdin->toPlainText().toAscii().constData());
    To copy to clipboard, switch view to plain text mode 

    But this is a non-nul terminated char * (as far as I know).

    I think it should be:
    Qt Code:
    1. proc->write(ui->plainTextEditStdin->toPlainText().toAscii());
    To copy to clipboard, switch view to plain text mode 

    (If you try to recompile the program, do not forget to make this change after extracting the sources.)

    But the problem still persists...

  3. #3
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Problem using QProcess on Windows XP

    Have you tried

    Qt Code:
    1. QString tmp = ui->plainTextEditStdin->toPlainText();
    2. proc->write(tmp.toAscii());
    To copy to clipboard, switch view to plain text mode 

    Otherwise you might be a victim of temporary class construction that is destroyed before your write method gets the data and this accesses invalid memory.

  4. #4
    Join Date
    Apr 2010
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Problem using QProcess on Windows XP

    Quote Originally Posted by fatjuicymole View Post
    Have you tried

    Qt Code:
    1. QString tmp = ui->plainTextEditStdin->toPlainText();
    2. proc->write(tmp.toAscii());
    To copy to clipboard, switch view to plain text mode 

    Otherwise you might be a victim of temporary class construction that is destroyed before your write method gets the data and this accesses invalid memory.
    Just tried this, unfortunately it still doesn't work... Maybe I will have to try deploying my own threads for monitoring the stdout/stderr pipes for data, and for looking if the child process has terminated and see if it works this way... But I still don't understand what the problem is - I mean, the code looks simple and innocent enough to 'just work', which it doesn't...

Similar Threads

  1. Problems launching a windows exe from Qt (using QProcess)
    By smacchia in forum Qt Programming
    Replies: 8
    Last Post: 21st March 2012, 10:05
  2. read stdout with QProcess under Windows
    By jlbrd in forum Qt Programming
    Replies: 4
    Last Post: 1st September 2006, 17:29
  3. need help for QProcess under windows
    By patcito in forum Qt Programming
    Replies: 4
    Last Post: 26th May 2006, 19:54
  4. Qprocess never end in MS windows
    By antonio.r.tome in forum Qt Programming
    Replies: 12
    Last Post: 23rd February 2006, 12:35
  5. QProcess problem with windows batch file
    By bood in forum Qt Programming
    Replies: 11
    Last Post: 6th January 2006, 08:08

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.