Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Read stderr output from own process
Forum Updated to NodeBB v4.3 + New Features

Read stderr output from own process

Scheduled Pinned Locked Moved General and Desktop
7 Posts 4 Posters 4.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    AlexanderL
    wrote on last edited by
    #1

    Hi there,

    currently i'm writing a gui application which uses the external c library "libssh":http://www.libssh.org . 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:

    qInstallMessageHandler():

    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

    1 Reply Last reply
    0
    • A Offline
      A Offline
      andreyc
      wrote on last edited by
      #2

      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()":http://www.cplusplus.com/reference/cstdio/freopen/ or use "dup()":http://stackoverflow.com/a/956269

      1 Reply Last reply
      0
      • Chris KawaC Offline
        Chris KawaC Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on last edited by
        #3

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

        1 Reply Last reply
        0
        • A Offline
          A Offline
          AlexanderL
          wrote on last edited by
          #4

          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.

          1 Reply Last reply
          0
          • A Offline
            A Offline
            AlexanderL
            wrote on last edited by
            #5

            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:

            errorlogger.h
            @#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
              {
              Q_OBJECT
              public:
              explicit ErrorLogger(QObject *parent = 0);

            signals:
            void errorMessage(QString message);

            public slots:
            void logErrors();

            private:
            char errorBuffer[BUFFERSIZE];
            QTimer *timer;

            };

            #endif // ERRORLOGGER_H
            @

            errorlogger.cpp
            @
            #include "errorlogger.h"

            ErrorLogger::ErrorLogger(QObject *parent) :
            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);
            timer->start(500);
            connect(timer, SIGNAL(timeout()), this, SLOT(logErrors()));
            

            }

            void ErrorLogger::logErrors()
            {
            fflush(stderr);

            // 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?

            1 Reply Last reply
            0
            • B Offline
              B Offline
              bodzio131
              wrote on last edited by
              #6

              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":http://www.syndicateofideas.com/posts/fighting-the-msvcrt-dll-hell

              1 Reply Last reply
              0
              • A Offline
                A Offline
                AlexanderL
                wrote on last edited by
                #7

                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.

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved