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. QT deployed executable crashes on some computers
Forum Updated to NodeBB v4.3 + New Features

QT deployed executable crashes on some computers

Scheduled Pinned Locked Moved Solved General and Desktop
42 Posts 9 Posters 9.7k Views 3 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.
  • L Lati
    26 Nov 2019, 13:56

    Ok. I decided to install the Qt on one of the computer where executable crashes. I copied the whole development folder and build the application. I can build the application in Debug and Release without any problem. However, when I try to start the debug with F5, I get following error:

    Capture.PNG

    Please note that Qt is installed on D drive. I tried few solutions offered by Google, like copying the Qt dll's in the debug folder which didn't help. I feel very desperate.

    @hskoglund
    Pc's are a bit far from each other :) I use remote desktop most of the time.

    @fcarney
    I checked that, it is v 5.12.1. I don't know how to be sure which version it should be.

    L Offline
    L Offline
    Lati
    wrote on 26 Nov 2019, 14:37 last edited by Lati
    #26

    Finally! I found where the problem is. I received source code of the one of the libraries I use. And there is following code in the library:

    programXRootDirectory = getenv("ProgramXROOT");
    

    And yes, if the environmental variable doesn't exist, executable crashes. Strangely, there is no sign about the crash caused by getenv.

    I will keep this thread, maybe someone else has the same problem.

    I would like to thank you everyone who tried to help me so far!

    Update:getenv is deprecated and _dupenv_s recommended instead. More information about _dupenv_s

    P 1 Reply Last reply 26 Nov 2019, 15:47
    2
    • L Lati
      26 Nov 2019, 14:37

      Finally! I found where the problem is. I received source code of the one of the libraries I use. And there is following code in the library:

      programXRootDirectory = getenv("ProgramXROOT");
      

      And yes, if the environmental variable doesn't exist, executable crashes. Strangely, there is no sign about the crash caused by getenv.

      I will keep this thread, maybe someone else has the same problem.

      I would like to thank you everyone who tried to help me so far!

      Update:getenv is deprecated and _dupenv_s recommended instead. More information about _dupenv_s

      P Offline
      P Offline
      Pablo J. Rogina
      wrote on 26 Nov 2019, 15:47 last edited by
      #27

      @Lati said in QT deployed executable crashes on some computers:

      Strangely, there is no sign about the crash caused by getenv.

      Well, it looks like the culprit isn't getenv() but the way the return value from that function is used within the DLL later on. From man getvenv:

      The getenv() function returns a pointer to the value in the environment, or NULL if there is no match.

      so programXRootDirectory becomes NULL when the variable is not set, and the world ends...

      Upvote the answer(s) that helped you solve the issue
      Use "Topic Tools" button to mark your post as Solved
      Add screenshots via postimage.org
      Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

      L 1 Reply Last reply 26 Nov 2019, 21:33
      3
      • L Lati
        26 Nov 2019, 13:56

        Ok. I decided to install the Qt on one of the computer where executable crashes. I copied the whole development folder and build the application. I can build the application in Debug and Release without any problem. However, when I try to start the debug with F5, I get following error:

        Capture.PNG

        Please note that Qt is installed on D drive. I tried few solutions offered by Google, like copying the Qt dll's in the debug folder which didn't help. I feel very desperate.

        @hskoglund
        Pc's are a bit far from each other :) I use remote desktop most of the time.

        @fcarney
        I checked that, it is v 5.12.1. I don't know how to be sure which version it should be.

        J Offline
        J Offline
        JonB
        wrote on 26 Nov 2019, 17:40 last edited by JonB
        #28

        @Lati
        That file error screenshot is in Qt5Cored.dll. Note the d at the end of the name. That is the version compiled for debug (plus the message). Why are you deploying debug DLLs?

        It would be interesting to see whether the problem across different PCs even occurs any more if you compiled & released for Release instead?

        getenv does not crash when an environment variable does not exist, it returns NULL. If the code fails to deal with that (e.g. dereferences), that's a different matter, and is the only way it could "crash". So you have verified that the environment variable named ProgramXROOT does not/does exist on the machines which crash/don't crash respectively?

        1 Reply Last reply
        1
        • P Pablo J. Rogina
          26 Nov 2019, 15:47

          @Lati said in QT deployed executable crashes on some computers:

          Strangely, there is no sign about the crash caused by getenv.

          Well, it looks like the culprit isn't getenv() but the way the return value from that function is used within the DLL later on. From man getvenv:

          The getenv() function returns a pointer to the value in the environment, or NULL if there is no match.

          so programXRootDirectory becomes NULL when the variable is not set, and the world ends...

          L Offline
          L Offline
          Lati
          wrote on 26 Nov 2019, 21:33 last edited by Lati
          #29

          @Pablo-J-Rogina
          Exactly! No-one would guess the crash is due to getenvsince all indications were showing that it was either false libraries or graphic card issue.

          @JonB
          I am not deploying anything on that screen. The screenshot is after I clicked on F5 to debug the code and the path of the Qt5Cored.dll is from Qt's installation directory (Qt is installed on D: drive, as I mentioned). getenv crashes on my computer, as well as the deployed executable crashes on the computers if the environmental variable doesn't exist. It is very easy to test by writing a small application.

          J 1 Reply Last reply 26 Nov 2019, 21:43
          0
          • L Lati
            26 Nov 2019, 21:33

            @Pablo-J-Rogina
            Exactly! No-one would guess the crash is due to getenvsince all indications were showing that it was either false libraries or graphic card issue.

            @JonB
            I am not deploying anything on that screen. The screenshot is after I clicked on F5 to debug the code and the path of the Qt5Cored.dll is from Qt's installation directory (Qt is installed on D: drive, as I mentioned). getenv crashes on my computer, as well as the deployed executable crashes on the computers if the environmental variable doesn't exist. It is very easy to test by writing a small application.

            J Offline
            J Offline
            JonB
            wrote on 26 Nov 2019, 21:43 last edited by JonB
            #30

            @Lati said in QT deployed executable crashes on some computers:

            It is very easy to test by writing a small application.

            char *p = getenv("ProgramXROOT");
            // or
            char *p = getenv("AnythingElseWhichDoesntExist");
            

            won't crash. It will set p to NULL/nullptr.

            If the program continues and does not check for that, assuming that p will not be null, it may crash. That is all @Pablo-J-Rogina and I are saying.

            P 1 Reply Last reply 27 Nov 2019, 00:01
            0
            • F Offline
              F Offline
              fcarney
              wrote on 26 Nov 2019, 22:02 last edited by
              #31

              @Lati said in QT deployed executable crashes on some computers:

              programXRootDirectory

              It would be interesting to know what the data type is for this variable. I could not get QString to crash or misbehave.

              {
                      char* null = nullptr;
              
                      QString test = "hallo";
                      qInfo() << "before init null";
                      test = QString(null);
                      qInfo() << test;
                      qInfo() << "after init null";
              
                      QString test2 = "hallo again";
                      qInfo() << "before assign null";
                      test2 = null;
                      qInfo() << test2;
                      qInfo() << "after assign null";
                  }
              

              C++ is a perfectly valid school of magic.

              L 1 Reply Last reply 26 Nov 2019, 22:15
              0
              • F fcarney
                26 Nov 2019, 22:02

                @Lati said in QT deployed executable crashes on some computers:

                programXRootDirectory

                It would be interesting to know what the data type is for this variable. I could not get QString to crash or misbehave.

                {
                        char* null = nullptr;
                
                        QString test = "hallo";
                        qInfo() << "before init null";
                        test = QString(null);
                        qInfo() << test;
                        qInfo() << "after init null";
                
                        QString test2 = "hallo again";
                        qInfo() << "before assign null";
                        test2 = null;
                        qInfo() << test2;
                        qInfo() << "after assign null";
                    }
                
                L Offline
                L Offline
                Lati
                wrote on 26 Nov 2019, 22:15 last edited by Lati
                #32

                @fcarney
                You can reproduce the issue with the following example (at least it crashes on my computer:)):

                main.cpp

                #include "mainwindow.h"
                #include <QApplication>
                
                int main(int argc, char *argv[])
                {
                    QApplication a(argc, argv);
                    MainWindow w;
                    w.show();
                    return a.exec();
                }
                

                mainWindow.h:

                #ifndef MAINWINDOW_H
                #define MAINWINDOW_H
                
                #include <QMainWindow>
                
                QT_BEGIN_NAMESPACE
                namespace Ui { class MainWindow; }
                QT_END_NAMESPACE
                
                class MainWindow : public QMainWindow
                {
                    Q_OBJECT
                
                public:
                    MainWindow(QWidget *parent = nullptr);
                    ~MainWindow();
                
                    // Senex root directory
                    std::string notExistEnvVar;
                
                private:
                    Ui::MainWindow *ui;
                };
                #endif // MAINWINDOW_H
                

                mainWindow.cpp

                #include "mainwindow.h"
                #include "ui_mainwindow.h"
                
                MainWindow::MainWindow(QWidget *parent)
                    : QMainWindow(parent)
                    , ui(new Ui::MainWindow)
                {
                    ui->setupUi(this);
                
                    notExistEnvVar = getenv("notExistEnvVar");
                }
                
                MainWindow::~MainWindow()
                {
                    delete ui;
                }
                

                Compiled with MSVC2015 64bit.

                1 Reply Last reply
                0
                • F Offline
                  F Offline
                  fcarney
                  wrote on 26 Nov 2019, 22:21 last edited by fcarney
                  #33

                  You are getting an exception because you are assigning nullptr to std::string. Assign to

                  char* ptr = getenv("notExistEnvVar");
                  if(ptr != nullptr)
                    notExistEnvVar = ptr;
                  

                  getenv is not crashing

                  Edit:
                  or use QString

                  QString str = getenv("notExistEnvVar");
                  

                  C++ is a perfectly valid school of magic.

                  J L 2 Replies Last reply 26 Nov 2019, 22:23
                  2
                  • F fcarney
                    26 Nov 2019, 22:21

                    You are getting an exception because you are assigning nullptr to std::string. Assign to

                    char* ptr = getenv("notExistEnvVar");
                    if(ptr != nullptr)
                      notExistEnvVar = ptr;
                    

                    getenv is not crashing

                    Edit:
                    or use QString

                    QString str = getenv("notExistEnvVar");
                    
                    J Offline
                    J Offline
                    JonB
                    wrote on 26 Nov 2019, 22:23 last edited by
                    #34

                    @fcarney Thank you :)

                    1 Reply Last reply
                    1
                    • J Offline
                      J Offline
                      JonB
                      wrote on 26 Nov 2019, 22:30 last edited by
                      #35

                      For std::string s = nullptr, see https://stackoverflow.com/questions/10771864/assign-a-nullptr-to-a-stdstring-is-safe/10771938. Accepted answer:

                      Requires: s shall not be a null pointer.

                      Since the standard does not ask the library to throw an exception when this particular requirement is not met, it would appear that passing a null pointer provoked undefined behavior.

                      1 Reply Last reply
                      2
                      • F Offline
                        F Offline
                        fcarney
                        wrote on 26 Nov 2019, 22:50 last edited by
                        #36

                        @JonB said in QT deployed executable crashes on some computers:

                        undefined

                        !!!UNDEFINED!!!
                        The end is nigh!

                        Good find!

                        C++ is a perfectly valid school of magic.

                        1 Reply Last reply
                        0
                        • J JonB
                          26 Nov 2019, 21:43

                          @Lati said in QT deployed executable crashes on some computers:

                          It is very easy to test by writing a small application.

                          char *p = getenv("ProgramXROOT");
                          // or
                          char *p = getenv("AnythingElseWhichDoesntExist");
                          

                          won't crash. It will set p to NULL/nullptr.

                          If the program continues and does not check for that, assuming that p will not be null, it may crash. That is all @Pablo-J-Rogina and I are saying.

                          P Offline
                          P Offline
                          Pablo J. Rogina
                          wrote on 27 Nov 2019, 00:01 last edited by
                          #37

                          @JonB said in QT deployed executable crashes on some computers:

                          won't crash. It will set p to NULL/nullptr.

                          The problem is not the assignment... the problem comes once you have assigned NULL to the pointer and then you try using it

                          Upvote the answer(s) that helped you solve the issue
                          Use "Topic Tools" button to mark your post as Solved
                          Add screenshots via postimage.org
                          Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

                          1 Reply Last reply
                          1
                          • F fcarney
                            26 Nov 2019, 22:21

                            You are getting an exception because you are assigning nullptr to std::string. Assign to

                            char* ptr = getenv("notExistEnvVar");
                            if(ptr != nullptr)
                              notExistEnvVar = ptr;
                            

                            getenv is not crashing

                            Edit:
                            or use QString

                            QString str = getenv("notExistEnvVar");
                            
                            L Offline
                            L Offline
                            Lati
                            wrote on 27 Nov 2019, 08:05 last edited by Lati
                            #38

                            @fcarney

                            Obviously, the person who wrote the library didn't know this (to be honest, I didn't know it as well, I have never used getenv). And this is how bugs happened, right? :)

                            But interesting thing is that there is no sign about the crash and no-one had an idea about it (including me). I would still look at the error somewhere else if I wouldn't test the code on one of the problem computer.

                            Anyway, thank you for the clarification.

                            J 1 Reply Last reply 27 Nov 2019, 08:28
                            0
                            • L Lati
                              27 Nov 2019, 08:05

                              @fcarney

                              Obviously, the person who wrote the library didn't know this (to be honest, I didn't know it as well, I have never used getenv). And this is how bugs happened, right? :)

                              But interesting thing is that there is no sign about the crash and no-one had an idea about it (including me). I would still look at the error somewhere else if I wouldn't test the code on one of the problem computer.

                              Anyway, thank you for the clarification.

                              J Offline
                              J Offline
                              JonB
                              wrote on 27 Nov 2019, 08:28 last edited by
                              #39

                              @Lati
                              For the record, getenv() has been in the C runtime libraries since the 1970s(!) There has to be a way for it to tell you that the selected environment variable does not exist (without crashing!), and that is of course by returning 0. I and millions of other coders have been using that behaviour ever since :)

                              In your case, whoever wrote the code which does not check for that will doubtless have been working in an environment where that ProgramXROOT variable did always exist, and hence never witnessed the unanticipated behaviour.

                              OOI, how have you resolved this? Did you actually change that library's code to fix and recompile, or have you just told your end users they must have that environment variable defined?

                              J L 2 Replies Last reply 27 Nov 2019, 08:31
                              1
                              • J JonB
                                27 Nov 2019, 08:28

                                @Lati
                                For the record, getenv() has been in the C runtime libraries since the 1970s(!) There has to be a way for it to tell you that the selected environment variable does not exist (without crashing!), and that is of course by returning 0. I and millions of other coders have been using that behaviour ever since :)

                                In your case, whoever wrote the code which does not check for that will doubtless have been working in an environment where that ProgramXROOT variable did always exist, and hence never witnessed the unanticipated behaviour.

                                OOI, how have you resolved this? Did you actually change that library's code to fix and recompile, or have you just told your end users they must have that environment variable defined?

                                J Offline
                                J Offline
                                jsulm
                                Lifetime Qt Champion
                                wrote on 27 Nov 2019, 08:31 last edited by
                                #40

                                @JonB @Lati
                                Yes, "man getenv" shows this:
                                "RETURN VALUE
                                The getenv() function returns a pointer to the value in the environment, or NULL if there is no match."
                                It is the responsibility of the caller to check its return value and reacting accordingly...

                                https://forum.qt.io/topic/113070/qt-code-of-conduct

                                1 Reply Last reply
                                2
                                • J JonB
                                  27 Nov 2019, 08:28

                                  @Lati
                                  For the record, getenv() has been in the C runtime libraries since the 1970s(!) There has to be a way for it to tell you that the selected environment variable does not exist (without crashing!), and that is of course by returning 0. I and millions of other coders have been using that behaviour ever since :)

                                  In your case, whoever wrote the code which does not check for that will doubtless have been working in an environment where that ProgramXROOT variable did always exist, and hence never witnessed the unanticipated behaviour.

                                  OOI, how have you resolved this? Did you actually change that library's code to fix and recompile, or have you just told your end users they must have that environment variable defined?

                                  L Offline
                                  L Offline
                                  Lati
                                  wrote on 27 Nov 2019, 09:03 last edited by Lati
                                  #41

                                  @JonB I am not one of that millions of coders (or even if I used it, I never had problems).

                                  In the code, I replaced the getenv part using _dupenv_s as following (which will be valid with the next release):

                                      char* buf = nullptr;
                                      size_t sz = 0;
                                      if (_dupenv_s(&buf, &sz, "programXROOT") == 0 && buf != nullptr)
                                      {
                                          programXRootDirectory = buf;
                                          free(buf);
                                      }
                                      else
                                      {
                                          QMessageBox msgBox;
                                          msgBox.setText("Environmental variable is missing!");
                                          msgBox.exec();
                                      }
                                  

                                  Actually, after installation of this application, user has to create this environmental variable before starting the application. And seems like all the users have created the variable and there was no issue so far. But if a user would forget about this, it would be nightmare to find out the reason.

                                  J 1 Reply Last reply 27 Nov 2019, 09:13
                                  0
                                  • L Lati
                                    27 Nov 2019, 09:03

                                    @JonB I am not one of that millions of coders (or even if I used it, I never had problems).

                                    In the code, I replaced the getenv part using _dupenv_s as following (which will be valid with the next release):

                                        char* buf = nullptr;
                                        size_t sz = 0;
                                        if (_dupenv_s(&buf, &sz, "programXROOT") == 0 && buf != nullptr)
                                        {
                                            programXRootDirectory = buf;
                                            free(buf);
                                        }
                                        else
                                        {
                                            QMessageBox msgBox;
                                            msgBox.setText("Environmental variable is missing!");
                                            msgBox.exec();
                                        }
                                    

                                    Actually, after installation of this application, user has to create this environmental variable before starting the application. And seems like all the users have created the variable and there was no issue so far. But if a user would forget about this, it would be nightmare to find out the reason.

                                    J Offline
                                    J Offline
                                    JonB
                                    wrote on 27 Nov 2019, 09:13 last edited by JonB
                                    #42

                                    @Lati
                                    Again for the record, the _dupenv_s (which btw is MSVC-only) you mention has nothing to do with the issue you are talking about. The extra parameters it takes are to do with copying the value, if found, into your own buffer. If it's not found:

                                    If the variable is not found, then buffer is set to NULL, numberOfElements is set to 0, and the return value is 0 because this situation is not considered to be an error condition.

                                    So the issue will rear its head again if code later tries to dereference the buf from the &buf passed in. Just as with the return result from getenv().

                                    Purely as a by-the-by, I presume you are aware in the code you show (which perhaps is only intended as an example):

                                            programXRootDirectory = buf;
                                            free(buf);
                                    

                                    This would not be a good idea --- programXRootDirectory is left pointing to freed memory! You'll get a different error/crash/behaviour if you then dereference that :)

                                    1 Reply Last reply
                                    2

                                    35/42

                                    26 Nov 2019, 22:30

                                    • Login

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