0

I want to write a simple application (i.e. starter) that starts my main application and further monitors its state and restarts it, if it crashes/exits.

Its very simple. I use the QProcess for this purpose and run the main application (app1) and handle its stateChanged signal.

To test it, i have written a very small console app that would print out its name and then just return via exit(-1) (simulating the case where the program has exited for some reason).

Everything goes as expected for the first time and the stateChanged signal is emmited in every stage. App1 would immediately exit after its launch, again causing the staeChanged signal to be emitted for the 2nd time.

The problem is that after APP1 is launced for the 2nd time (and consequently exited) the stateChanged signal is not emmited anymore !!!

What have i done wrong? Should i re-connect the signals each each time i start the application via QProcess OR ...???

Note: I see this case both under windows and linux.

starter::starter(QObject *parent) : QObject(parent)
{
    m_process = new QProcess(this);
    m_process->setProcessChannelMode(QProcess::ProcessChannelMode::ForwardedChannels);
    connect(m_process, &QProcess::stateChanged, this, &starter::onStateChanged);

    m_process->setProgram("myapp1");
    m_process->setArguments(QStringList());

    startProcess();
}

void starter::onStateChanged(const QProcess::ProcessState &state)
{
    qDebug() << "state changed to : " << state;

    if(state == QProcess::ProcessState::NotRunning){
        this->startProcess();
    }
}


void starter::startProcess()
{
    qDebug() << "start process App1";
    m_process->start();
    if(m_process->waitForStarted(1000)){
        qDebug() << "[+] App started";
    }
    else{
        qDebug() << "[!] Failed to start app";
    }
}

output:

C:\myapp1-release>starter.exe
start process : "myapp1"
state changed to :  QProcess::Starting
state changed to :  QProcess::Running
[+] App started
state changed to :  QProcess::NotRunning
start process : "myapp1"
state changed to :  QProcess::Starting
state changed to :  QProcess::Running
[+] App started

*NO FURTHER REACTION TO THE EXIT OF APP1*
qwa
  • 123
  • 10
  • 1
    remove `waitForStarted` – eyllanesc Feb 07 '21 at 16:02
  • I removed the ``waitForStarted`` and it did not help. The same problem persists (app1 emits the signal only 2 times). – qwa Feb 08 '21 at 05:45
  • terminate process at end "m_process->terminate();" – SajadBlog Feb 08 '21 at 06:10
  • What do you mean by "end"? I put ``m_process->terminate()`` at ``onStateChanged`` when application not running is sensed. But it did not help. My real program switches between 2 apps (based on user request) and uses ``terminate()`` for this. In this case i have no problem and i get the signals every time i close the apps). **The problem is seen when the app is killed manually or crashes/exits by itself.** – qwa Feb 08 '21 at 06:33
  • Further Observation: If i make the sample "myapp1" to not exit and block on ``app.exec()`` and instead kill it manually (e.g. kill -9 pid) the same problem is observed (i.e. the ``stateChanged`` signal is emmited only the first time the app1 is killed manually) – qwa Feb 08 '21 at 06:34

1 Answers1

0

My (not so good) solution: I delete the old QProcess object and instantiate it again when i detect an application crash/exit.

This way the signal is emmited for all other and consequent app's crashes/exits.

m_process->deleteLater();//delete the old instance - I hope its signal/slot connections are cleared automatically by Qt ??!!
m_process = new QProcess(this);
m_process->setProcessChannelMode(QProcess::ProcessChannelMode::ForwardedChannels);
connect(m_process, &QProcess::stateChanged, this, &starter::onStateChanged);//make connections for the new instance

The hint to take this approach came from Qt's documentation for QProcess::close():

Closes all communication with the process and kills it. After calling this function, QProcess will no longer emit readyRead(), and data can no longer be read or written.

Has Qt's documentation missed to mention that if qprocess application exits or gets killed manually the stateChanged signal will not be emitted any more? Or probably i am missing sth.

Any comment on the correctness of this approach is highly appreciated.

qwa
  • 123
  • 10