Important: Please read the Qt Code of Conduct -

Read stderr output from own process

  • Hi there,

    currently i'm writing a gui application which uses the external c library "libssh": . This library prints log messages (of adjustable verbosity) on stderr. I would like display them "live" in my gui. So i want the process to read it's own stderr.

    First, some clarifications:
    The libssh stuff runs (blocking) in a QThread since i don't use callback functions.
    libssh is a pure c library, so i'm looking for stderr, not std::cerr.
    The platform is Linux.

    My research/approaches so far:


    If understood correctly, it only works with qDebug(), qWarning()... thus useless.

    Run the application in a QProcess:

    At first i thought QProcess::readAllStandardError() was the solution, but apparently you can only run external programs in QProcess. I cannot run run my MainWindow Class from main.cpp as a QProcess, right? Because that would probably work, i think, otherwise it's infeasible.

    I've read a few threads about redirecting stdout/stderr to a file, but i didn't find a way to read into a TextStream, and using a file as buffer is not feasible aswell.

    Any ideas? Thanks in advance :)
    Regards, Alex

  • If libssh does not have any configuration option to redirect error log to a file or to a pipe you may try to do it yourself before making a call to libssh
    You may use "freopen()": or use "dup()":

  • Moderators

    You can also redirect stderr through custom buffer:
    char buffer[BUFSIZ];
    setbuf(stderr, buffer);

  • Thanks for the answers! I tested Chris suggestion and i appeared to be working. However, i couldn't get it working in my program as i intended to. I will give you an update next week.

  • Ok, so i wrote a class wich uses setvbuf() to emit the libssh stderr output periodically as QString signal. This works perfect, for Linux, here is the code:

    @#ifndef ERRORLOGGER_H
    #define ERRORLOGGER_H

    #include <QObject>
    #include <QTimer>
    #include <QDebug>

    #include <iostream>
    #include <stdio.h>

    #define BUFFERSIZE 655360


    • This class catches the stderr console output (from libssh) and emits it as signal.
    • The stderr stream is buffered in errorBuffer. logErrors() checks the buffer periodically, invoked by a QTimer (every 500ms). If there is content available it is sent via the errorMessage signal to the gui.
      class ErrorLogger : public QObject
      explicit ErrorLogger(QObject *parent = 0);

    void errorMessage(QString message);

    public slots:
    void logErrors();

    char errorBuffer[BUFFERSIZE];
    QTimer *timer;


    #endif // ERRORLOGGER_H

    #include "errorlogger.h"

    ErrorLogger::ErrorLogger(QObject *parent) :
    // redirect stderr to errorBuffer
    memset(errorBuffer, 0, sizeof(errorBuffer));
    setvbuf(stderr, errorBuffer, _IOLBF, sizeof(errorBuffer));

    // set up QTimer to call logErrors periodically
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(logErrors()));


    void ErrorLogger::logErrors()

    // if there is stuff in the buffer, send it as errorMessage signal and clear the buffer
    if(strlen(errorBuffer) > 0){
        emit errorMessage(errorBuffer);        // send buffer content to gui
        memset(errorBuffer, 0, sizeof(errorBuffer));


    The thing is, i need this for Windows as well. Under Windows, it compiles without a warning, but it doesn't work properly. If i have something like fprintf(stderr, "test"); in my code, it is caught by the class, however, the whole output from libssh is not.
    Does anyone have an idea why? Maybe because the libssh stuff runs in an extra thread?

  • On Windows you need to be sure that your software and 3rd-party library use the same CRT library. If they don't then you will read nothing as every CRT version has separated std-objects instances. "Read this for more details":

  • Wow, that was the actual problem, thanks Bogdan! I used a precompiled libssh dll from the internet, which was apparently compiled with Visual Studio 2013. I then compiled my own version of libssh with Visual Studio 2012 (which is a huge pain btw) and it worked. The code is even platfrom independent.
    Thanks you all for your support!

    P.s.: For anyone else ever encountering this problem: You can figure out with wich version of Visual Studio your dll has been compiled with the following way: Open the dll with the program Dependency Walker and watch out for msvcr1X0.dll
    msvcr120.dll is VS 2013, msvcr110.dll is VS 2012.

Log in to reply