Results 1 to 12 of 12

Thread: My program crashes if QProcess is restarted directly when it has finished

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Nov 2011
    Posts
    51
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: My program crashes if QProcess is restarted directly when it has finished

    Quote Originally Posted by norobro View Post
    Why not connect the signal QProcess::finished(int) to your slot?
    That is one way to do it too, but now I wanted to use the stateChanged signal. It's possible that I'll change to using the finished signal later on if I notice that I don't need to know when it changes to states other than QProcess::NotRunning.

    Quote Originally Posted by ChrisW67 View Post
    You are saying the actual code posted above, with a minimal main() fails. You don't say what line 18 lists as the source file and line. Is it your code? Has your program been built in debug mode?
    What do you mean with line 18? There isn't any line 18 in the code I posted with code on it... Yes, this is my code and I have tried running it in debug mode (see my last post).

    Quote Originally Posted by ChrisW67 View Post
    The vast majority of segmentation faults are caused by programmers using dangling or uninitialised pointers (or undefined references). There are no pointers in your example code, except for a pointer to p that can only become invalid during program tear-down. It seems likely that the actual code you are running is more complex and is suffering a dangling pointer issue.
    I don't think I have any dangling pointer anywhere since I never use the keyword new (or malloc or anything like that), but maybe some pointer is created somewhere that I am not aware of. I had better post the entire code here:

    main.cpp:
    Qt Code:
    1. #include <QtGui/QApplication>
    2. #include "mainwindow.h"
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication a(argc, argv);
    7. MainWindow w;
    8. w.show();
    9.  
    10. return a.exec();
    11. }
    To copy to clipboard, switch view to plain text mode 

    mainwindow.h:
    Qt Code:
    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3.  
    4. #include <QMainWindow>
    5. #include "process_handler.h"
    6.  
    7. namespace Ui {
    8. class MainWindow;
    9. }
    10.  
    11. class MainWindow : public QMainWindow
    12. {
    13. Q_OBJECT
    14.  
    15. public:
    16. explicit MainWindow(QWidget *parent = 0);
    17. ~MainWindow();
    18.  
    19. private:
    20. Ui::MainWindow *ui;
    21. process_handler s;
    22. };
    23.  
    24. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 

    mainwindow.cpp:
    Qt Code:
    1. #include <QTimer>
    2. #include "mainwindow.h"
    3. #include "ui_mainwindow.h"
    4.  
    5. MainWindow::MainWindow(QWidget *parent) :
    6. QMainWindow(parent),
    7. ui(new Ui::MainWindow)
    8. {
    9. ui->setupUi(this);
    10.  
    11. /* Begin start processes when the windows has finished loading */
    12. QTimer::singleShot(0, &s, SLOT(start_process()));
    13. }
    14.  
    15. MainWindow::~MainWindow()
    16. {
    17. delete ui;
    18. }
    To copy to clipboard, switch view to plain text mode 

    process_handler.h:
    Qt Code:
    1. #ifndef PROCESS_HANDLER_H
    2. #define PROCESS_HANDLER_H
    3.  
    4. #include <QProcess>
    5.  
    6. class process_handler : public QObject
    7. {
    8. Q_OBJECT
    9.  
    10. public:
    11. process_handler(QObject *parent = 0);
    12.  
    13. private:
    14.  
    15. public slots:
    16. void start_process();
    17.  
    18. private slots:
    19. void process_state_changed();
    20. };
    21.  
    22. #endif // PROCESS_HANDLER_H
    To copy to clipboard, switch view to plain text mode 

    process_handler.cpp:
    Qt Code:
    1. #include <iostream>
    2. using std::cout;
    3. using std::endl;
    4. #include <QTimer>
    5. #include "process_handler.h"
    6.  
    7. process_handler::process_handler(QObject *parent) :
    8. QObject(parent)
    9. {
    10. connect(&p, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(process_state_changed()));
    11. }
    12.  
    13. void process_handler::process_state_changed()
    14. {
    15. if (p.state() == QProcess::Starting) {
    16. cout << endl;
    17. cout << "Process is starting up..." << endl;
    18. }
    19. if (p.state() == QProcess::Running) {
    20. cout << "Process is now running." << endl;
    21. }
    22. if (p.state() == QProcess::NotRunning) {
    23. cout << "Process is finished running." << endl;
    24.  
    25. /* Start a new process */
    26. start_process();
    27. //QTimer::singleShot(0, this, SLOT(start_process()));
    28. }
    29. }
    30.  
    31. void process_handler::start_process()
    32. {
    33. //p.start("program");
    34. p.start("ls");
    35. }
    To copy to clipboard, switch view to plain text mode 

    As can be seen, main.cpp is unmodified, and only one line each has been added to mainwindow.cpp and two lines to mainwindow.h, dealing with the process_handler object. As I said before, it is possible to make a workaround by using a QTimer::SingleShot (substitude line 27 in process_handler.cpp for line 26), but this is a hack I would definitely prefer not having to use.

    Quote Originally Posted by d_stranz View Post
    Not true. See QObject::sender().
    Thanks! I didn't know about that function, it seems handy.
    Last edited by Yes; 17th September 2012 at 15:13.

  2. #2
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: My program crashes if QProcess is restarted directly when it has finished

    Quote Originally Posted by Yes View Post
    . . . but now I wanted to use the stateChanged signal. . . .
    Then connecting both signals should work:
    Qt Code:
    1. process_handler::process_handler(QObject *parent) :
    2. QObject(parent)
    3. {
    4. connect(&p, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(process_state_changed(QProcess::ProcessState)));
    5. connect(&p, SIGNAL(finished()), this, SLOT(start_process()));
    6. }
    7.  
    8. void process_handler::process_state_changed(QProcess::ProcessState state)
    9. {
    10. if (state == QProcess::Starting) {
    11. cout << endl;
    12. cout << "Process is starting up..." << endl;
    13. }
    14. if (state == QProcess::Running) {
    15. cout << "Process is now running." << endl;
    16. }
    17. if (state == QProcess::NotRunning) {
    18. cout << "Process is finished running." << endl;
    19.  
    20. /* Start a new process */
    21. // start_process();
    22. //QTimer::singleShot(0, this, SLOT(start_process()));
    23. }
    24. }
    25.  
    26. . . .
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Nov 2011
    Posts
    51
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: My program crashes if QProcess is restarted directly when it has finished

    Quote Originally Posted by norobro View Post
    Then connecting both signals should work
    Yes, but I don't want to start a new process every time an old process has finished. Basically, I want to run processes untill some condition is reached, and then I want to stop running processes, so start_process() shouldn't be directly connected to the finished signal since then I wouldn't be able to stop running processes. The question is still why my program crashes if I call start_process() directly from process_state_changed() without using a QTimer::SingleShot...

  4. #4
    Join Date
    Feb 2008
    Posts
    491
    Thanks
    12
    Thanked 142 Times in 135 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: My program crashes if QProcess is restarted directly when it has finished

    Apparently notRunning != finished(). On Linux I get the following warning on the command line:
    QSocketNotifier: Multiple socket notifiers for same socket 15 and type Read
    Try the following code:
    Qt Code:
    1. #include <QCoreApplication>
    2. #include <QProcess>
    3. #include <QDebug>
    4. #include <QTimer>
    5.  
    6. class process_handler : public QObject
    7. {
    8. Q_OBJECT
    9. public:
    10. process_handler() {
    11. connect(&p, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(process_state_changed(QProcess::ProcessState)));
    12. connect(&p, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(process_finished(int, QProcess::ExitStatus)));
    13. start_process();
    14. }
    15. public slots:
    16. void process_state_changed(QProcess::ProcessState state) {
    17. if (state == QProcess::Starting)
    18. qDebug() << "Process is starting up...";
    19. if (state == QProcess::Running)
    20. qDebug() << "Process is now running." ;
    21. if (state == QProcess::NotRunning){
    22. qDebug() << "Process is finished running.";
    23. start_process();
    24. //QTimer::singleShot(0, this, SLOT(start_process()));
    25. }
    26. }
    27. void process_finished(int , QProcess::ExitStatus ){
    28. qDebug() << "received finished signal";
    29. }
    30. void start_process() {
    31. p.start("ping 1.1.1.1 -c 1 -W 3"); // from your previous thread
    32. }
    33. private:
    34. };
    35.  
    36. int main(int argc, char *argv[]) {
    37. QCoreApplication app(argc, argv);
    38. process_handler ph;
    39. app.exec();
    40. }
    41. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 
    The output on my box is:
    Process is starting up...
    Process is now running.
    Process is finished running.
    QSocketNotifier: Multiple socket notifiers for same socket 15 and type Read
    Process is starting up...
    received finished signal
    I haven't looked at the source code but what appears to happen is the new process assigns a QSocketNotifier to the same
    socket as the old process and the old process deletes the socket. My app just idles in the event loop after the output
    above. Maybe Windows segfaults?

  5. The following user says thank you to norobro for this useful post:

    Yes (18th September 2012)

  6. #5
    Join Date
    Nov 2011
    Posts
    51
    Thanks
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Thumbs up Re: My program crashes if QProcess is restarted directly when it has finished

    Okay, so maybe I need to wait untill I receive the finished signal before I can start up a new process.

    Yes, I'm using Windows XP and I do receive a segmentation fault message. The output of your code in the command prompt (the terminal in Windows) before the segfault message comes is

    Process is starting up...
    Process is now running.
    Process is finished running.
    Process is starting up...
    Process is now running.
    received finished signal
    I don't get the same QSocketNotifier message as you do, though. I still only get to see Qt files containing a lot of assembly code when backtracing.

    However, if I move the line containing start_process(); from the slot receiving the stateChanged signal to the slot receiving the finished signal, the program runs as expected. I think I will just stick to the QTimer::singleShot() workaround in my case, though. Anyway, thank you very much!

Similar Threads

  1. Replies: 2
    Last Post: 13th July 2011, 02:52
  2. Replies: 0
    Last Post: 26th August 2010, 10:44
  3. QProcess::finished problems again
    By mdicosimo in forum Qt Programming
    Replies: 2
    Last Post: 23rd January 2009, 21:43
  4. QProcess::finished()
    By T1c4L in forum Qt Programming
    Replies: 11
    Last Post: 9th July 2008, 20:06
  5. Replies: 4
    Last Post: 13th February 2006, 11:35

Tags for this Thread

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
  •  
Qt is a trademark of The Qt Company.