【问题标题】:Qt GUI app unexpectedly endingQt GUI 应用程序意外结束
【发布时间】:2012-03-14 11:27:10
【问题描述】:

您好,我在 Linux 上工作,我正在尝试创建一个 GUI 应用程序来配合我制作的可执行文件。

由于某种原因,它意外地结束了。没有错误消息,它只是在 Qt 控制台窗口中说它以退出代码 0 意外结束。

谁能帮我看看。我在 Linux 上工作。

我也会把代码贴在这里。

void MainWindow::on_pushButton_clicked()
{
    QString stringURL = ui->lineEdit->text();

    ui->labelError->clear();
    if(stringURL.isEmpty() || stringURL.isNull()) {
        ui->labelError->setText("You have not entered a URL.");
        stringURL.clear();
        return;
    }

    std::string cppString = stringURL.toStdString();
    const char* cString = cppString.c_str();

    char* output;

    //These arrays will hold the file id of each end of two pipes
    int fidOut[2];
    int fidIn[2];

    //Create two uni-directional pipes
    int p1 = pipe(fidOut);                //populates the array fidOut with read/write fid
    int p2 = pipe(fidIn);                 //populates the array fidIn  with read/write fid
    if ((p1 == -1) || (p2 == -1)) {
        printf("Error\n");
        return;
    }

    //To make this more readable - I'm going to copy each fileid
    //into a semantically more meaningful name
    int parentRead  = fidIn[0];
    int parentWrite = fidOut[1];
    int childRead   = fidOut[0];
    int childWrite  = fidIn[1];

    //////////////////////////
    //Fork into two processes/
    //////////////////////////
    pid_t processId = fork();

    //Which process am I?
    if (processId == 0) {
        /////////////////////////////////////////////////
        //CHILD PROCESS - inherits file id's from parent/
        /////////////////////////////////////////////////
        ::close(parentRead);      //Don't need these
        ::close(parentWrite);     //

        //Map stdin and stdout to pipes
        dup2(childRead,  STDIN_FILENO);
        dup2(childWrite, STDOUT_FILENO);

        //Exec - turn child into sort (and inherit file id's)
        execlp("htmlstrip", "htmlstrip", "-n", NULL);

    } else {
        /////////////////
        //PARENT PROCESS/
        /////////////////
        ::close(childRead);       //Don't need this
        ::close(childWrite);      //

        //Write data to child process
        //char strMessage[] = cString;
        write(parentWrite, cString, strlen(cString));
        ::close(parentWrite);     //this will send an EOF and prompt sort to run

        //Read data back from child
        char charIn;
        while ( read(parentRead, &charIn, 1) > 0 ) {
            output = output + (charIn);
            printf("%s", output);
        }
        ::close(parentRead);      //This will prompt the child process to quit
    }

    return;
}

编辑:: 调试结果

我运行了调试器,这是我收到的错误:

The inferior stopped because it received a signal from the Operating System.

Signal name : SIGSEGV
Signal meaning : Segmentation fault

【问题讨论】:

  • 你试过在调试器中运行它吗?它可能会帮助您找出问题所在,最重要的是哪里出了问题。
  • 除了找到原因(信号)之外,您还应该能够让调试器在该点中断执行并查看有问题的行。基本调试技能。
  • 在这种情况下要粘贴的是'bt'的输出(回溯)

标签: c++ c qt pipe


【解决方案1】:

您尚未初始化“输出”变量。在代码的最后几行,您可以这样做:

while ( read(parentRead, &charIn, 1) > 0 ) {
    output = output + (charIn);
    printf("%s", output);
}

这会做一些讨厌的事情,因为您将从子进程读取的字节添加到输出变量,这是一个包含垃圾的指针,然后将“输出”变量地址的内容打印为字符串。您可能希望“输出”为std::string,这样您的代码才有意义:

std::string output;
/* ... */
while ( read(parentRead, &charIn, 1) > 0 ) {
    output += (charIn);
}
std::cout << output;

一旦您读取了您的子进程生成的所有数据,您就可以将其写入标准输出。

编辑:由于要将“输出”的内容设置为 QPlainTextEdit,因此可以使用 QPlainTextEdit::setPlainText:

while ( read(parentRead, &charIn, 1) > 0 ) {
    output += (charIn);
}
plainTextEdit.setPlainText(output.c_str());

【讨论】:

  • 您好,感谢您的回答。我现在没有收到错误。但是你知道我如何将输出打印到 plainTextEdit 中吗?
  • 我已经编辑了我的答案,现在检查一下。
  • 所以答案是调试器已经彻底坏掉了,并且给你nothing任何东西来找出问题所在的代码行。我正在经历同样的事情。
  • @doug65536 不,问题是您通过做错事触发了所谓的“未定义行为”。如果您使用的是 linux,我建议您使用 valgrind,它在这些情况下非常有用。
  • @mfontanini std::cout &lt;&lt; "Hello world" &lt;&lt; std::endl; 是未定义的行为吗?如果你断点 hello-world 程序的唯一行,调试器将完全失败,并出现“意外信号”。如果你删除断点,它运行良好。打断点是UB?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-08
  • 2013-12-21
  • 2018-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多