Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-115199

Improve errno handling in Qt

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.7
    • Core: Other
    • None
    • e8909dcfd (dev)

    Description

      Stemming from https://codereview.qt-project.org/c/qt/qtbase/+/490802/2 , there's a number of problems regaring the usage of errno in Qt:

      Code that uses errno "too late", directly or indirectly.

      errno is supposed to be used immediately If one does anything between detecting an error and using errno, chances are that the value has been overwritten by an intervening call into libc. Examples:

      int ret = libc_function(param);
      if (!ret) { // failed
         // all wrong:
         fprintf(stderr, "Something %s failed: %d", qPrintable(param), errno); //  1
         qWarning() << "Something failed:" << errno; // 2
         qWarning("Something failed: %s", errno); // 3
      }
      

      All of these are wrong because there's code intervening before errno is used.

      1. Arguments in a function call are evaluated in an unspecified order. There's no guarantee that qPrintable doesn't run before reading errno. Although that order is almost always right-to-left so the code may look like it works in practice, there's no guarantee, and adding a further argument or rearranging the order risks breaking the call (i.e. the code is fragile).
      2. Same story: operator<< is left-associative, so the expression is parsed as:
        operator<<(operator<<(QDebug, const char *), int)
        

        There's no guarantee in which order arguments of the outer operator are evaluated.

      3. Curveball: Qt logging uses macros. qWarning expans to QMessageLogger(...).warning, meaning there's code that will run before we read errno.

      Grepping for errno into qtbase reveals dozens of broken usages.

      We lack a portable thread-safe version of strerror

      strerror (~47 usages in qtbase) should never be used because it's thread unsafe. On UNIX we're supposed to use stderror_r (to further complicate things, there's a GNU-incompatible version), and on Windows strerror_s.

      We need to wrap it and make it portable. There's already groundwork for this laid in QSystemError.

      qErrnoWarning is a misnomer on Windows (QTBUG-9948)

      On Windows qErrnoWarning calls qt_error_string, which calls FormatMessage. That's the API for formatting Win32 errors (obtained by GetLastError), not the API for C library errors (errno). This means we don't have a portable errno-printing facility.
      The Win32 functionality should be split and usages should be ported away. (This is all private API, but QTBUG-2779 asks to make them public, so this work would be a prerequisite.)

      No errno-printing function should read errno internally

      qt_error_string can be called with -1, and it will read errno on its own. That's a bad idea. Always force the user to pass errno to it; the goal is to let the developer / reviewers realize that errno is dirty by the time the function is called and tries to print it.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            thiago Thiago Macieira
            peppe Giuseppe D'Angelo
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There are no open Gerrit changes