Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[SOLVED] Segmentation Fault with QProcess, but in console works all fine



  • Hi all,

    I would like to create a simple app what writes the windows processes.

    @#include <QtDebug>

    #include <QTimer>
    #include <QProcess>
    #include <QPlainTextEdit>
    #include <QString>
    #include <QStringList>

    #include "mainwindow.h"
    #include "ui_mainwindow.h"

    //
    // Global variables
    //
    QString p_stdout;

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    QProcess proc;
    runScript();

    //QTimer *timer = new QTimer(this);
    //connect(timer, SIGNAL(timeout()), this, SLOT(refreshList()));
    //timer->start(10000);
    
    ui->setupUi(this);
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void MainWindow::splitText(QString text)
    {
    QStringList list;

    list = text.split(QRegExp("\\s+"));
    
    for (int i = 0; i < list.size(); i += 3)
    {
        QString temp = list[i];
        temp.append(" ");
        temp.append(list[i+1]);
        temp.append(" ");
        temp.append(list[i+2]);
        temp.append("\n");
        ui->textBox->setPlainText(temp);
    }
    

    }

    void MainWindow::runScript()
    {
    //proc->setReadChannelMode(QProcess::SeparateChannels);
    proc.start("WMIC path win32_process get Caption,Processid,Commandline"); //this command list the processes
    //connect (proc,SIGNAL(finished(int)), this, SLOT(stopped()));
    connect(&proc,SIGNAL(readyReadStandardOutput()),this,SLOT(readyReadStandardOutput()));
    connect(&proc,SIGNAL(readyReadStandardError()),this,SLOT(readyReadStandardError()));

    proc.waitForFinished(-1); //here are the "Segmantation Fault"
    
    if (proc.exitStatus() == QProcess::NormalExit)
    {
        QApplication::beep();
    }
    else
        MainWindow::close();
    
    QByteArray p_stdout = proc.readAll();
    QString p_stderr = proc.readAllStandardError();
    splitText(p_stdout);
    
    /*if (!proc->waitForFinished())
    {
        ui->textBox->setPlainText(QString(proc->readAllStandardError()));
        qDebug() << QString(proc->readAllStandardOutput());
        qDebug() << proc->exitCode();
        qDebug() << proc->exitStatus();
    }
    else
    {
        qDebug() << proc->readAll();
        QByteArray result = proc->readAll();
    }*/
    

    }

    void MainWindow::readyReadStandardOutput(){
    qDebug() << proc.readAllStandardOutput();
    ui->textBox->setPlainText(proc.readAllStandardOutput());
    }

    void MainWindow::readyReadStandardError(){
    qDebug() << proc.readAllStandardError();
    ui->textBox->setPlainText(proc.readAllStandardError());
    }

    void MainWindow::refreshList()
    {
    runScript();
    ui->textBox->update();
    //ui->textBox->setPlainText(p_stdout);
    }

    void MainWindow::on_actionE_xit_triggered()
    {
    MainWindow::close();
    }
    @

    The code is actualy not complete, because I can not debug by the error.

    Thanks,
    I-sty



  • Hi.
    You declared local variable @proc@ in constructor and try to use it in another function! This code shouldn't compile.

    P.S. also take a look to "global QProcess...":http://www.qtcentre.org/threads/11696-QProcess-*proc-at-top-of-source-(global-)



  • @void MainWindow::runScript()
    {
    QProcess *proc = new QProcess();

    proc->start("WMIC path win32_process get Caption,Processid,Commandline");
    proc->waitForReadyRead();
    
    QString p_stdout = proc->readAll();
    QString p_stderr = proc->readAllStandardError();
    splitText(p_stdout);
    

    }@

    Thanks Aleksey.
    I declared local in constructor, I changed the wairForFinished() to waitForReadyRead() and now it's working :D


    But, ....

    @void MainWindow::splitText(QString text)
    {
    QStringList list;

    list = text.split(QRegExp("\\s+"));
    
    for (int i = 3; i < list.size(); i += 3)
    {
        QString temp = list[i];
        temp.append(" ");
        temp.append(list[i+1]);
        temp.append(" ");
        temp.append(list[i+2]);
        temp.append("\n");
        ui->textBox->setPlainText(temp); //here I give "Segmentation Fault"
    }
    

    }@

    I get a SegFault. Why?



  • Hi, normally you get the segmentation fault if you want to write or read data from a non-allocated memory location. Why don't you set a break point before the ui->... line and check if the ui pointer is there at all.
    Btw there is no check of a full list, so what happens if the list gives e.g. 20 results in stead of 21? The last index of the list will not be there causing the temp.append(list[i+2]) to read from unallocated or at least wrong data.
    greetz and enjoy live!



  • I changed the QPlainText to QTextEdit.

    @ for (int i = 3; i < list.size(); ++i)
    {
    /QString temp;
    temp.append(list[i]);
    temp.append(" ");
    temp.append(list[i+1]);
    temp.append(" ");
    temp.append(list[i+2]);
    temp.append("\n\r");
    /
    ui->textBox->setText("hello"); //SegFault
    }@

    But, I give segfault, anyway. :(



  • In which context do you call void MainWindow::refreshList() ? If you write to the ui not within the gui thread, you also can get a segment fault. This makes sense, since your console application does not fail.



  • Also, you have a memory leak in runScript() method.
    Do you really need to allocate proc in heap?



  • @void MainWindow::runScript()
    {
    proc->start("WMIC path win32_process get Caption,Processid,Commandline");
    proc->waitForReadyRead();
    QApplication::beep();
    //splitText(QString(proc->readAllStandardOutput()));
    }
    @

    I changed proc.

    @
    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    proc = new QProcess();
    
    ....
    

    }@



  • Memory leak still exists))

    try to change to:

    @
    proc = new QProcess(this);
    @

    Did you run your app in debug mode (e.g. via F5 shortcut)?


Log in to reply