Potential memory leak?
NothingSpecific opened this issue · 9 comments
I'm using ImGuiFileDialog as part of a project I recently started, and couldn't help but notice LSAN is reporting a memory leak. I'm not sure where the leak is coming from, but it's definitely leaking memory every time an ImGuiFileDialog is opened.
I'm using g++ to compile, and passing the build options -fexceptions -pthread -ldl -lGL -Wall -Werror -g -fsanitize=undefined -fno-sanitize-recover -fsanitize=float-cast-overflow -fsanitize=leak -fsanitize=address -fsanitize-address-use-after-scope -fstack-protector -fstack-protector-all -fstack-check
.
Output from running the compiled binary (with LSAN tooling):
$ bin/debug/Perplexed
=================================================================
==5799==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 32816 byte(s) in 1 object(s) allocated from:
#0 0x7f6c5ab3be8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x7f6c59c3ab76 in __alloc_dir ../sysdeps/posix/opendir.c:118
Direct leak of 920 byte(s) in 5 object(s) allocated from:
#0 0x7f6c5ab3c037 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
#1 0x7f6c566704d5 (<unknown module>)
Direct leak of 520 byte(s) in 13 object(s) allocated from:
#0 0x7f6c5ab3be8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x7f6c5668a441 (<unknown module>)
Direct leak of 62 byte(s) in 3 object(s) allocated from:
#0 0x7f6c5ab3be8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x7f6c56681c1f (<unknown module>)
Direct leak of 24 byte(s) in 1 object(s) allocated from:
#0 0x7f6c5ab3be8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x7f6c566839c1 (<unknown module>)
Indirect leak of 1933 byte(s) in 9 object(s) allocated from:
#0 0x7f6c5ab3c1f8 in __interceptor_realloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:164
#1 0x7f6c56683e14 (<unknown module>)
Indirect leak of 40 byte(s) in 1 object(s) allocated from:
#0 0x7f6c5ab3be8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x7f6c56684033 (<unknown module>)
Indirect leak of 24 byte(s) in 1 object(s) allocated from:
#0 0x7f6c5ab3be8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x7f6c566839c1 (<unknown module>)
Indirect leak of 24 byte(s) in 1 object(s) allocated from:
#0 0x7f6c5ab3be8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x7f6c56683a15 (<unknown module>)
SUMMARY: AddressSanitizer: 36363 byte(s) leaked in 35 allocation(s).
Only the first one is an actual memory leak (Direct leak of 32816 byte(s) in 1 object(s) allocated from <...>
). The others are one-time allocations from the initial setup of Dear ImGui. I've concluded that the first line is coming from somewhere in ImGuiFileDialog because it shows up if and only if my program ends up calling to ImGuiFileDialog. I've also concluded that if I open 3 dialogs, I get a line like this:
Direct leak of 98448 byte(s) in 3 object(s) allocated from:
#0 0x7fbcd8971e8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x7fbcd7a70b76 in __alloc_dir ../sysdeps/posix/opendir.c:118
Some relevant notes:
- Even though your README.md gives me the strong impression that the singleton pattern is generally preferred, I'm instantiating dialogs as objects, not using the singleton pattern. See: file_open_dialog.cpp from my project.
- I'm using the singleton pattern with another project that also uses (an older version of) ImGuiFileDialog, and no leak occurs. I'm unsure whether this is because the other project uses the singleton pattern, or possibly that the older version doesn't have the same leak.
- I'm developing my project on x86_64 GNU+Linux (Debian-based).
Hello,
I not notices any leaks on my side, but its Always possible.
Btw your code not use igfd in the good way.
You have mixed many code.
You consider your code is working well ?
You sée the dialog opening and Closing quickly no ?
As best as I could tell, I'm using IGFD as it's meant to be used. All the examples are for the singleton pattern, so I was sort of guessing that the code would be the same using instantiated objects. The code I have is basically just the simple dialog example.
It seems to be working without issue, and the dialog opens/closes immediately.
ok there was an error in the Simple dialog code.
the idea is to open the dialog when you click on the button. and constantly call the Display method for display the dialog.
in your example, you constantly open and display the dialog.
the good code is :
void drawGui() {
// open Dialog Simple
if (ImGui::Button("Open File Dialog")) {
IGFD::FileDialogConfig config;config.path = ".";
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Choose File", ".cpp,.h,.hpp", config);
}
// display
if (ImGuiFileDialog::Instance()->Display("ChooseFileDlgKey")) {
if (ImGuiFileDialog::Instance()->IsOk()) { // action if OK
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
std::string filePath = ImGuiFileDialog::Instance()->GetCurrentPath();
// action
}
// close
ImGuiFileDialog::Instance()->Close();
}
}
in more you define filestyle via the singleton but are opening and displaying without.
so the filestsyle is not defined when you open the dialog..
you know there is a sample app in the DemoApp branch, where you can see many more use case
btw this not explian why you have memory leaks with the object and not with the singleton, or maybe a special produced by the infinite, "close and open, display"
only explained if your other use case with the singleton is functionnal, so not like here, where
the dialog open and close quickly.
will check that
so your code must be something like that :
ImGuiFileDialog dialog;
void init_file_dialog() { // must be called one time for the instance
dialog.SetFileStyle(IGFD_FileStyleByFullName, ".", ImVec4(0.3f, 0.3f, 0.3f, 1), ICON_FK_CIRCLE);
dialog.SetFileStyle(IGFD_FileStyleByFullName, "..", ImVec4(0.8f, 0.8f, 0.8f, 1), ICON_FK_LEVEL_UP);
}
void open_file_dialog() { // must be called one time when you need to open the dialog
IGFD::FileDialogConfig config;
config.flags = ImGuiFileDialogFlags_DisableCreateDirectoryButton |
ImGuiFileDialogFlags_DontShowHiddenFiles;
dialog.OpenDialog("OpenFileDialog", "Open File", ".*", config);
}
bool show_file_open_dialog(){ // must be called in your render loop before the ImGui::Render()
bool res = true;
ImVec2 min_size = max_size / 2.0f;
ImVec2 max_size = ImVec2( // Half the display area
(io->DisplaySize.x - (style->FramePadding.x * 2.0f) - (style->FrameBorderSize * 2.0f)),
(io->DisplaySize.y - (style->FramePadding.y * 2.0f) - (style->FrameBorderSize * 2.0f))
);
ImGui::PushFont(font::icon_font_karla_regular_forkawesome);
if (dialog.Display("OpenFileDialog", ImGuiWindowFlags_NoCollapse, min_size, max_size)){
if (dialog.IsOk()){
open(dialog.GetFilePathName());
}
dialog.Close();
res = false;
}
ImGui::PopFont();
return res;
to note, its funny, not a problem, but you are coding in c++ like if it was some c language.
by ex, you return false so 0 where all is ok like in c hihi
That's not an error code at all, it's telling the render loop whether to attempt to draw the dialog next frame.
I did some pretty significant refactoring to my code to allow multiple files to be opened at once. Included in the refactoring are the fixes you suggested to my usage of ImGuiFileDialog. Though they don't solve the memory leak.
no ! it was an error code since you do Open Dialog then display in the same function...
i have no acces to sanitize tools, so maybe you can try to find the bug yourself and propose a PR.
The problem I have with that is LSAN isn't telling me anything about where in ImGuiFileDialog's code it's actually leaking the data. I figured since you're the original developer you'd know more about ImGuiFileDialog's internals.
I'll see what I can do. Perhaps Valgrind will be more helpful.
another user have propsoed a PR for fix one when dirent is used. it seems this is the one who was reported by you, and yes this issue is recent. since the file system interface commit
I can confirm PR #162 fixed the memory leak I was noticing.