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. QSettings segfault on Linux

QSettings segfault on Linux

Scheduled Pinned Locked Moved General and Desktop
qt application
8 Posts 3 Posters 4.3k Views
  • 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.
  • F Offline
    F Offline
    fabienm
    wrote on 9 Mar 2015, 08:05 last edited by fabienm 3 Sept 2015, 14:14
    #1

    Hello,

    As the title says, if I create a temporary QSettings after the end of main() function, the application crashed with a segfault on QSettings constructor. A minimal code to get this is:

    #include <QtCore/QApplication>
    #include <QtCore/QSettings>
    
    void endMain()
    {
       QSettings settings("settings.ini", QSettings::IniFormat);
    }
    
    int main(int argc, char **argv)
    {
       atexit(endMain);
    
       QCoreApplication(argc, argv);
    
       QSettings otherSettings("otherSettings.ini", QSettings::IniFormat);
    
       return 0;
    }
    

    This piece of code makes my application crashes on Linux. However, on Windows, I don't get any problem, and my application ends normally.

    Thanks for your help

    Fabien MATHIEU

    F 2 Replies Last reply 9 Mar 2015, 14:49
    0
    • M Offline
      M Offline
      mcosta
      wrote on 9 Mar 2015, 08:27 last edited by
      #2
      This post is deleted!
      1 Reply Last reply
      0
      • M Offline
        M Offline
        mcosta
        wrote on 9 Mar 2015, 10:18 last edited by
        #3

        Please, attach a stack trace

        1 Reply Last reply
        0
        • M Offline
          M Offline
          msms
          wrote on 9 Mar 2015, 10:54 last edited by
          #4

          I believe QSettings queries QApplication for things like app name and developer identifier in order to find the location of configuration file (or registry key). Your signature doesn't make sense settings("settings.ini") as it seems to imply that you are passing a filename as the first parameter.

          As such I would make certain that you have a valid QApplication at any time you instantiate QSettings. Since it is customary to do something like

          int main(int argc, char** argv) {
              QApplication app(argc, argv);
              ...
          }
          

          your QApplication won't exist at the time of your atexit call.

          I would personally not use atexit with Qt code but you can try invoking QSettings like this:

          QSettings settings("Moose Tech", "Facturo-Pro");
          
          F 1 Reply Last reply 9 Mar 2015, 14:39
          0
          • M msms
            9 Mar 2015, 10:54

            I believe QSettings queries QApplication for things like app name and developer identifier in order to find the location of configuration file (or registry key). Your signature doesn't make sense settings("settings.ini") as it seems to imply that you are passing a filename as the first parameter.

            As such I would make certain that you have a valid QApplication at any time you instantiate QSettings. Since it is customary to do something like

            int main(int argc, char** argv) {
                QApplication app(argc, argv);
                ...
            }
            

            your QApplication won't exist at the time of your atexit call.

            I would personally not use atexit with Qt code but you can try invoking QSettings like this:

            QSettings settings("Moose Tech", "Facturo-Pro");
            
            F Offline
            F Offline
            fabienm
            wrote on 9 Mar 2015, 14:39 last edited by
            #5

            @msms said:

            I believe QSettings queries QApplication for things like app name and developer identifier in order to find the location of configuration file (or registry key). Your signature doesn't make sense settings("settings.ini") as it seems to imply that you are passing a filename as the first parameter.

            Please forgive my code. Maybe I wrote my post a bit fast. The fact is I don't use the constructor with only the QString parameter, I use the one with the QString and the format. Indeed, with my previous written, the first one in the documentation is used. To be clear, I want to write in a ini file.

            As such I would make certain that you have a valid QApplication at any time you instantiate QSettings. Since it is customary to do something like

            int main(int argc, char** argv) {
                QApplication app(argc, argv);
                ...
            }
            

            your QApplication won't exist at the time of your atexit call.

            According to the documentation, QApplication is needed to store the organization name and domain or application name in conjunction with the default QSettings constructor. It is not a requirement in the other case.

            I would personally not use atexit with Qt code but you can try invoking QSettings like this:

            QSettings settings("Moose Tech", "Facturo-Pro");
            

            The use of atexit in my post is only to simplify the undersatnding of my problem. In my application, I use singleton. The destructor of my Singleton occuring after the end of main, I got the crash.

            Moreover, I made a mistake about the real error. The crash occurs in the constructor of QSettings after the end of main function, if and only if, an other QSettings has been created during the main (directly or indirectly).

            @mcosta said:

            Please, attach a stack trace

            I don't think stack trace would be useful. Indeed, the crash occurs in QSetting constructor (with a QString and a format), and end up somewhere in the libQt5Core.so without any additional informations about line, function or class.

            I change my code in my first post according these remarks.

            1 Reply Last reply
            0
            • F fabienm
              9 Mar 2015, 08:05

              Hello,

              As the title says, if I create a temporary QSettings after the end of main() function, the application crashed with a segfault on QSettings constructor. A minimal code to get this is:

              #include <QtCore/QApplication>
              #include <QtCore/QSettings>
              
              void endMain()
              {
                 QSettings settings("settings.ini", QSettings::IniFormat);
              }
              
              int main(int argc, char **argv)
              {
                 atexit(endMain);
              
                 QCoreApplication(argc, argv);
              
                 QSettings otherSettings("otherSettings.ini", QSettings::IniFormat);
              
                 return 0;
              }
              

              This piece of code makes my application crashes on Linux. However, on Windows, I don't get any problem, and my application ends normally.

              Thanks for your help

              Fabien MATHIEU

              F Offline
              F Offline
              fabienm
              wrote on 9 Mar 2015, 14:49 last edited by
              #6

              Using valgrind on my minimal code (the one on my first post), it occurs that an invalid read happened. Without surprise, the errors seems to match with the stack trace.

              The stack trace is:

              0	??	/home/fabienm/Qt/5.4/gcc_64/lib/libQt5Core.so.5		0x7fca4e7cad6f	
              1	??	/home/fabienm/Qt/5.4/gcc_64/lib/libQt5Core.so.5		0x7fca4e7cb0bf	
              2	QSettings::QSettings(QString const&, QSettings::Format, QObject*)	/home/fabienm/Qt/5.4/gcc_64/lib/libQt5Core.so.5  0x7fca4e7cb254	
              3	endMain	main.cpp	6	0x400ac3	
              4	__run_exit_handlers		82	0x7fca4dcdd259	
              5	__GI_exit		104	0x7fca4dcdd2a5	
              6	__libc_start_main		321	0x7fca4dcc2ecc	
              7	_start			0x4009c9	
              

              The output of valgrind is:

              Invalid read of size 8
                dans endMain() dans /home/fabienm/QSettings_segfault/main.cpp:6
              Address 0x0 is not stack'd, malloc'd or (recently) free'd  
                1: /home/fabienm/Qt/5.4/gcc_64/lib/libQt5Core.so.5.4.1
                2: /home/fabienm/Qt/5.4/gcc_64/lib/libQt5Core.so.5.4.1
                3: QSettings::QSettings(QString const&amp;, QSettings::Format, QObject*) dans /home/fabienm/Qt/5.4/gcc_64/lib/libQt5Core.so.5.4.1
                4: endMain() dans /home/fabienm/QSettings_segfault/main.cpp:6
                5: __run_exit_handlers dans /build/buildd/eglibc-2.19/stdlib/exit.c:82
                6: exit dans /build/buildd/eglibc-2.19/stdlib/exit.c:104
                7: (below main) dans /build/buildd/eglibc-2.19/csu/libc-start.c:321
              

              We see in both case, the code stop somewhere libQt5Core.so, without more information. On my side, I will continue investigation hoping the memory leak is linked to the crash.

              1 Reply Last reply
              0
              • M Offline
                M Offline
                msms
                wrote on 9 Mar 2015, 21:19 last edited by
                #7

                It's hard to tell what could be the problem. I've had a lot of trouble with static singleton objects in Qt (the dreaded crash at application end), but I've had troubles with them in C++ in general. The destructors or such objects are called in an undefined order. For me things always went wrong when I used them. So, as a result, I advise, if possible to rewrite your program in such a way as not to use a static object, or to force it's destruction to occur before the end of main.

                For instance, instead of holding a static object like:

                Object obj;
                

                Keep a global pointer to it

                Object* obj;
                

                And control its lifetime in main:

                int main() {
                    obj = new Object...;
                    ...
                    delete obj;
                }       
                

                Alternatively, if you wish to track this further, you can try to look at the QSettings source.

                Here is a starting point:

                https://qt.gitorious.org/qt/qt/source/08c0f9cf858e7c2563c8b6c3b121d619989a92ee:src/corelib/io/qsettings.cpp#L2746

                I see some QCoreApplication event calls in that file. Those could crash your program for example (but maybe not).

                Cheers.

                1 Reply Last reply
                0
                • F fabienm
                  9 Mar 2015, 08:05

                  Hello,

                  As the title says, if I create a temporary QSettings after the end of main() function, the application crashed with a segfault on QSettings constructor. A minimal code to get this is:

                  #include <QtCore/QApplication>
                  #include <QtCore/QSettings>
                  
                  void endMain()
                  {
                     QSettings settings("settings.ini", QSettings::IniFormat);
                  }
                  
                  int main(int argc, char **argv)
                  {
                     atexit(endMain);
                  
                     QCoreApplication(argc, argv);
                  
                     QSettings otherSettings("otherSettings.ini", QSettings::IniFormat);
                  
                     return 0;
                  }
                  

                  This piece of code makes my application crashes on Linux. However, on Windows, I don't get any problem, and my application ends normally.

                  Thanks for your help

                  Fabien MATHIEU

                  F Offline
                  F Offline
                  fabienm
                  wrote on 10 Mar 2015, 16:45 last edited by
                  #8

                  So, I recompile Qt for Linux and Windows to be sure, and there is definitively a difference in the behaviour of QSettings. I tracked the crash in qsettings.cpp and I found the responsible line.

                  In the file, there is the class function QConfFile::fromName(const QString &fileName, bool _userPerms) on line 190. In this function, we try to get a ConfFileHash* on line 194. On Windows, the return value is valid, whereas on Linux, the value is null, that's why my application crash. However, I don't have any ideas to solve it.

                  I think the difference is on which order are resources destroyed. On Linux, after main ends, a resource has to be destroyed, whereas on Windows it isn't.

                  I post here the complete stack trace:

                  Thread 1 (Thread 0x7f5094b3c780 (LWP 7527)):
                  #0  0x00007f50945be5cc in QHash<QString, QConfFile*>::value (this=0x0, akey=...) at ../../include/QtCore/../../src/corelib/tools/qhash.h:618
                      node = 0x7fff71651dd0
                  #1  0x00007f50945b49d6 in QConfFile::fromName (fileName=..., _userPerms=true) at io/qsettings.cpp:200
                      absPath = {static null = {<No data fields>}, d = 0x2209520}
                      confFile = 0x0
                      locker = {val = 139984066867721}
                      usedHash = 0x0
                      unusedCache = 0x0
                  #2  0x00007f50945b8739 in QConfFileSettingsPrivate::QConfFileSettingsPrivate (this=0x2208da0, fileName=..., format=QSettings::IniFormat) at io/qsettings.cpp:1156
                  No locals.
                  #3  0x00007f50945b50cb in QSettingsPrivate::create (fileName=..., format=QSettings::IniFormat) at io/qsettings.cpp:294
                  No locals.
                  #4  0x00007f50945bbdfc in QSettings::QSettings (this=0x7fff71651ee0, fileName=..., format=QSettings::IniFormat, parent=0x0) at io/qsettings.cpp:2575
                  No locals.
                  #5  0x000000000040148d in endMain () at main.cpp:30
                      settings = {<QObject> = {_vptr.QObject = 0x7fff71651f00, static staticMetaObject = {d = {superdata = 0x0, stringdata = 0x7f50947ed240 <qt_meta_stringdata_QObject>, data = 0x7f50947ed360 <qt_meta_data_QObject>, static_metacall = 0x7f509468f702 <QObject::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)>, relatedMetaObjects = 0x0, extradata = 0x0}}, d_ptr = {d = 0x7f50945d1d1c <(anonymous namespace)::Q_QGS_qtLoggingRegistry::Holder::~Holder()+36>}, static staticQtMetaObject = {d = {superdata = 0x0, stringdata = 0x7f509483a740 <qt_meta_stringdata_Qt>, data = 0x7f5094844ac0 <qt_meta_data_Qt>, static_metacall = 0x0, relatedMetaObjects = 0x0, extradata = 0x0}}}, static staticMetaObject = {d = {superdata = 0x7f509493fb40 <QObject::staticMetaObject>, stringdata = 0x7f509484f900 <qt_meta_stringdata_QSettings>, data = 0x7f509484f940 <qt_meta_data_QSettings>, static_metacall = 0x7f5094718e20 <QSettings::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)>, relatedMetaObjects = 0x0, extradata = 0x0}}}
                  #6  0x00007f5093a7d259 in __run_exit_handlers (status=0, listp=0x7f5093dff6c8 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true) at exit.c:82
                      atfct = <optimized out>
                      onfct = <optimized out>
                      cxafct = <optimized out>
                      f = <optimized out>
                  #7  0x00007f5093a7d2a5 in __GI_exit (status=<optimized out>) at exit.c:104
                  No locals.
                  #8  0x00007f5093a62ecc in __libc_start_main (main=0x40153c <main(int, char**)>, argc=1, argv=0x7fff71652028, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fff71652018) at libc-start.c:321
                      result = <optimized out>
                      unwind_buf = {cancel_jmp_buf = {{jmp_buf = {0, -6701343962190558468, 4199168, 140735095840800, 0, 0, 6701050451662228220, 6746722540675549948}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x403b20 <__libc_csu_init>, 0x7fff71652028}, data = {prev = 0x0, cleanup = 0x0, canceltype = 4209440}}}
                      not_first_call = <optimized out>
                  #9  0x0000000000401329 in _start ()
                  No symbol table info available.
                  

                  @msms said:

                  I see some QCoreApplication event calls in that file. Those could crash your program for example (but maybe not).

                  Indeed, there are some QCoreApplication event calls. I haven't got into this calls, but these calls are static, so maybe the QCoreApplication isn't needed. The above stack trace seems exclude this theory.

                  In all case, thanks for your help

                  Cheers

                  1 Reply Last reply
                  0

                  6/8

                  9 Mar 2015, 14:49

                  • Login

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