c++gccc++17std-filesystemgcc9

c++ - double free when using std::filesystem::path in a vector


I'm working on a bare-bones file browser using DearImgui. For this i'm using std::filesystem with g++-9 and am currently testing on Kubuntu 19.04. For the most part the program works as expected. A button is used to descend into the parent directory and a child directory can be opened by double clicking on it. Most of the time i can navigate through the entire filesystem without issues, however certain combinations of commands cause the program to abort. The exact error message varies but is always related to a double free error.

Before adding std::filesystem to my application i was using g++-8 (Ubuntu 8.3.0-6ubuntu1). However the program kept segfaulting after calling something filesystem related. This appears to be a known issue and should be fixed with 8.3.0-7 (source). In the meantime i decided to use g++-9 (Ubuntu 9.1.0-2ubuntu2~19.04). I am not sure if this might be the cause of my problem.

Here is the code that causes the abort:

namespace fs = std::filesystem;
struct FileBrowser {

    fs::path currentPath = fs::current_path();
    std::vector<fs::path> files;

    void UpdateFiles() {
        files.clear();
        for (auto& entry : fs::directory_iterator(currentPath))
            files.push_back(entry.path()); // Leak_DefinitelyLost
    }

    void DrawContent() {
        if (BackButtonPressed && currentPath.has_parent()) {
            currentPath = currentPath.parent_path(); // Jump depends on uninitialised value
            UpdateFiles();
        }

        static bool invalidate = false;
        for (auto& entry : files) {
            if (ClickedOnThisEntry && fs::is_directory(entry)) {
                currentPath = entry; // InvalidRead
                invalidate = true;
            }
        }
        if (invalidate) {
            UpdateFiles();
            invalidate = true;
        }
    }

};

When running the program with Valgrind it reports a leak when updating the path vector and an uninitialised condition. The main error seems to be the Invalid Read when trying to copy the selected path into the current path.

A reproducable example would require SDL2 and imgui. I can post one if somebody is interested.

What's interesting is that when i run the program in gdb and trigger an abort i can no longer use my mouse to click on anything (even unrelated applications like firefox). I can still use the keyboard and kill gdb through the command line. Something like that has not happened before in this project and i can't reproduce it in an unrelated part of the program. This could be caused by Imgui but i doubt it.


Solution

  • I found a solution for the problem. Updating currentPath with the assign(...) function instead of the assignment operator = seems to fix the problem.