Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Error when running application with 'sudo' which doesn't appear when run as a normal user



  • I have a cross-compilation workflow setup with my QtCreator, which is working nicely. I'm currently building some lower level functionality in my application, which requires root-level access to the target device's hardware (/dev/mem on RPi2). In testing whether the /dev/mem functions I've written are working, I've ssh'ed into my RPi2, and tried running the application directly as root:

    sudo ./application
    

    The application instantly produces an ASSERT failure:

    QList<T>::at: "index out of range"
    

    If I run the application as a normal user (either from QtCreator or via ./application on the RPi directly), the application runs perfectly without any assertions (if I comment out the /dev/mem functions obviously).

    Why am I receiving sudo-specific assertions/errors?


  • Moderators

    @jars121 said in Error when running application with 'sudo' which doesn't appear when run as a normal user:

    The application instantly produces an ASSERT failure:

    QList<T>::at: "index out of range"
    

    Get a stack trace. What function calls lead to this bad call to QList::at()?

    If I run the application as a normal user (either from QtCreator or via ./application on the RPi directly), the application runs perfectly without any assertions (if I comment out the /dev/mem functions obviously).

    What happens if you comment out the /dev/mem functions AND run it under sudo?

    Do you have a desktop Linux machine that you can test this on?



  • Thanks for your input. I'm going through the possible QList::at() calls at the moment. Unfortunately I don't have a stack trace as such when it's run natively on the RPi.

    The /dev/mem functions have no impact on the QList::at() assertion on the RPi. I've just built and run the application as sudo on my Desktop Linux development machine, and it doesn't produce the QList::at() assertion, nor does it have any issues with the /dev/mem functions. Very interesting!



  • Ok I seem to have found this issue. I use an external .ini file to store application settings, which are loaded in on application start using QSettings. I initialise all the variables (int, QString, QList, QVector, etc.) as either zero or empty (in the case of QLists, QVectors, etc.), and then replace each of the zeros with the value in the .ini file with QSettings.

    For whatever reason, QSettings doesn't work when I run the application on the RPi with sudo. If I run as a normal user (e.g. ./application), QSettings reads from the .ini file and assigns values to variables (confirmed with qDebug() prints). If I run as sudo (e.g. sudo ./application), all the .ini variables in the application are zero/empty, which I've confirmed by qDebug() printing a QList of known non-zero values (as printed when run under normal user conditions), which results in an empty QList, which is obviously why the QList::at() is failing.

    I added a qDebug() for QSettings::status() and the application doesn't have any QSettings-specific errors, either in normal or sudo modes.

    Why on earth is QSettings not saving values to memory under sudo??



  • A quick update; I appear to have sorted this issue.

    In case anyone is reading this in the future, here's the process I've been through.

    I had defined my QSettings fileName and format in my configuration class, as such:

    QSettings settings(fileName, QSettings::IniFormat)
    

    This worked nicely for non-sudo execution. However, I did some further reading, and found that QSettings works even better if setup in main.cpp, using the default path, as such:

    //main.cpp
    QSettings::setDefaultFormat(QSettings::IniFormat);
    app.setOrganizationName("Org");
    app.setApplicationName("App");
    

    With this done, the QSettings can be read from and written to from anywhere in the application, as simply as this:

    QSettings settings;
    settings.value(...)
    settings.setValue(...)
    

    If using this approach and not defining a fileName, QSettings will use the default file location and name for your platform. In my case (Unix), that is /etc/xdg, and the file name is set to the application name you defined in main.cpp (set as 'App' in the example code above). Hence, my QSettings .ini file is at /etc/xdg/App.ini.

    Now that I've implemented the above changes, my application seems to run perfectly in both normal and sudo modes :)


  • Moderators

    Good sleuthing!


Log in to reply