Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Ini file gets empty : QSettings problem ?
Forum Updated to NodeBB v4.3 + New Features

Ini file gets empty : QSettings problem ?

Scheduled Pinned Locked Moved Mobile and Embedded
7 Posts 6 Posters 7.5k 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.
  • F Offline
    F Offline
    f.vanalmetelevic.com
    wrote on last edited by
    #1

    On our embedded device (with i.MX27 processor, running Linux), we use an ini file to store information. Therefor, we use an object that inherits from QSettings. Sometimes (in fact very rarely), when powering off the device, we notice that the ini file gets empty. First we taught that the ini file was missing, but that's not the case. The file obviously remains available but gets empty. We only write to the file at the very beginning of our application, for the rest we only read it.
    Can this be a problem of QSettings ? (maybe the way QSettings implements ini file handling ?). Or would this be more related to the file-system (we are using UBI filesystem) ? Someone experienced similar problems ?

    1 Reply Last reply
    0
    • R Offline
      R Offline
      RazZziel
      wrote on last edited by
      #2

      Did you ever found an answer for this question? I'm struggling with it, both in Embedded and x86 Linux/Windows...

      1 Reply Last reply
      0
      • D Offline
        D Offline
        dbzhang800
        wrote on last edited by
        #3

        [quote author="RazZziel" date="1338665406"] I'm struggling with it, both in Embedded and x86 Linux/Windows...[/quote]
        If you can reproduce it under PC linux/Window, I think it will be easy to resolve , even it's a bug of Qt.

        1 Reply Last reply
        0
        • R Offline
          R Offline
          RazZziel
          wrote on last edited by
          #4

          I've found the error a lot of times, usually followed by clients calling us in rage after the data loss, but I can't really tell when this is happening

          1 Reply Last reply
          0
          • I Offline
            I Offline
            idle
            wrote on last edited by
            #5

            Users of my program also report similar problem which I never noticed myself. I tried to reproduce it with the following program:

            cat >empty.cpp <<EOF
            @
            #include <QCoreApplication>
            #include <QSemaphore>
            #include <QSettings>
            #include <QStringList>
            #include <QThread>

            struct Settings : public QSettings
            {
            Settings(const QString &_name) : QSettings(_name, QSettings::IniFormat) {}
            };

            static QString getIniName()
            {
            QStringList args = QCoreApplication::arguments();
            return ((args.size() > 1) ? args.at(1) : "/tmp/empty.ini");
            }

            static bool canChangeIni()
            {
            QStringList args = QCoreApplication::arguments();
            return ((args.size() > 2) ? true : false);
            }

            static void initValue(const QString &_iniName, const char *_key, const QVariant &_val)
            {
            Settings s(_iniName);
            if (s.contains(_key))
            return;
            qWarning("key %s is missing", _key);
            s.setValue(_key, _val);
            }

            struct IniThread : public QThread
            {
            IniThread(const QString &_iniName, bool _changeIni) : QThread(), m_iniName(_iniName), m_changeIni(_changeIni) {}

            void run()
            {
            

            Settings s(m_iniName);
            while (true) {
            if (!m_changeIni) {
            volatile int oneVal = s.value("one/val", 1).toInt();
            volatile QString twoVal = s.value("two/val", "2").toString();
            &oneVal;
            &twoVal;
            }
            else {
            s.setValue("one/val", s.value("one/val", 1).toInt()+1);
            s.sync();
            s.setValue("two/val", nextTwoVal(s.value("two/val", "2").toString()));
            s.sync();
            }
            }
            }

            QString nextTwoVal(const QString &_val)
            {
            

            return QString::number(_val.toInt() + 1);
            }

            QString m_iniName;
            bool m_changeIni;
            

            };

            int main(int _argc, char *_argv[])
            {
            QCoreApplication app(_argc, _argv);

            QString iniName = getIniName();
            bool changeIni = canChangeIni();
            
            // fill ini file with default values
            initValue(iniName, "one/val", 1);
            initValue(iniName, "two/val", "2");
            
            // start thread to update ini file
            IniThread thread(iniName, changeIni);
            thread.start();
            
            // wait a little, then terminate while ini file is accessed
            QSemaphore sem;
            sem.tryAcquire(1, 1000);
            
            return 0;
            

            }
            @
            EOF

            cat >empty.pro <<EOF
            @
            QT += core
            QT -= gui
            CONFIG += console
            CONFIG += warn_on

            TARGET = empty
            TEMPLATE = app

            SOURCES += empty.cpp
            @

            EOF

            Basically, it runs thread which constantly changes ini file and then process exits without stopping writer thread. Once in 3-5 invocations it produces empty ini file. Might be run as following in sh shell:

            while ( true ); do ./empty /tmp/empty.ini 1; if [ ! -s /tmp/empty.ini ]; then break; fi; done

            In my program I'm using wrapper around QSettings, so I can just add flag to block writing when program finishes. It might still produce empty ini file if program crashes while ini is updated, so I can write into temporary file and then replace original one, or save original before writing values - at least there will be backup ini file.

            1 Reply Last reply
            0
            • J Offline
              J Offline
              JulienMaille
              wrote on last edited by
              #6

              Did anyone found a solution to this?

              1 Reply Last reply
              0
              • V Offline
                V Offline
                vish
                wrote on last edited by
                #7

                Quite late but somthing could help,
                From past 3 days I was facing the same issue. The problem is qsettings keeps writing file in event loop. Hence this file will be always be present in ur kernel buffer. After writing changes in the next event loop it wll again put file in kernel buffer. And whn ur app crash or power off with out writing buffer kernel makes tht file zero byte. Some system providers will have capacitors to keep system up for tiny amount of time so tht kernel can clear buffer but most small embedded wil not have tht facility.. I actually fixed this problem by using normal qfile read and write function. after write flush i do QProcess::execute("sync"). This will clear buffer. hence ur file is not more in kernel buffer. And safe. But in this case u can lost file whn sync is going on and ur power goes off.. Its not atomic.

                Development is possible at any level.

                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