[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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.