ChildWindow closed event

Started by glagan, 13 August 2018, 21:11:05

glagan

Hi, when you set a callback to the "closed" event of a ChildWindow, the program just crash.
This code doesn't work :
auto child = tgui::ChildWindow::create();
child->connect("closed", [&](tgui::ChildWindow::Ptr window) {
    std::cout << "callback" << std::endl;
});
gui.add(child); // Closing the window make the program crash.

However, this only happen when the "-O2" flag is set when compiling, when there is no "-O" flag and the "-g" flag is set the program works fine, so i can't enter debug mode either to know what's happening...  :-\

texus

I can't reproduce this.
Only having it in release mode might indicate trying to use invalid memory, but I checked with valgrind and there are no problems with memory access.

Does it happen in a minimal example, just a main function with the minimal code for TGUI and where you only create a ChildWindow which has an empty lambda as callback?
Whether it still happens then or not, you should provide a small sample code that I can just copy-paste and run here to test under as identical circumstances as possible.

What OS and compiler are you using?

glagan

The code I posted on a new empty project with only it inside produce the same output.
But here's a full main.cpp alone that crash for me : https://pastebin.com/uFSefVMq (And the .cbp project https://pastebin.com/mYqkF3v7)

I'm using Windows 10 Enterprise 1709 (16299.492), and my compiler is GCC-6.3.0-1 (The default one that come with MinGW).
I also compiled both SFML and TGUI myself using the same compiler.
I compile with that in the linker:
mingw32
user32
gdi32
winmm
dxguid
libtgui
sfml-graphics
sfml-window
sfml-system

And I don't even need the -O2 flag in the clean project to make it crash.

I tried to compile on another computer, same compiler but different Windows version (Windows 10 Professional 1511, 10586.1176), and the same compiler and it does the same (crash).
It does work on Ubuntu 18.04 with GCC-7.3.0-16ubuntu3.
So I tried to compile using GCC-7.3.0 (x86_64-win32-seh-rev0) that come with MinGW-64 by default but it still doesn't work :-/

texus

#3
I didn't actually try the project yet (I am going to do so today), but I already noticed a mistake in debug mode. Are you only testing in release mode? I assumed that when you were talking about the -O2 and -g flags you were just talking about Debug/Release modes, but are you perhaps using the same mode and just messing with the flags?
In the debug settings you are linking to the static version of TGUI but to the dynamic version of SFML, they are not compatible. The '-std=c++14' option also seems lacking in debug mode. I noticed that even in release mode you use "libtgui" instead of just "tgui", but I guess that doesn't make a difference.

Are you doing anything special to build 64-bit, because mixing 32 and 64 bit could also create issues. And despite the name "MinGW-64", it still works 32-bits by default. I'm just checking since the TGUI and SFML folders end with a "_64" postfix. Although since you said you build SFML and TGUI yourself with the same compiler, it's unlikely that you would be mixing these versions.

Edit: I can't reproduce it with MinGW either (although I only tested with a different MinGW version so far). Just to double check: you did replace the dlls next to the exe after rebuilding SFML/TGUI, right?

glagan

The flag -std=c++14 is set globally for both Release and Debug mode, then I append the -g flag only in Debug mode and the -O2 and -s flags only in Release mode.
And the same for the linker, everything is set for both and then I set libtgui and sfml with '-d' only in debug mode and without '-d' in release mode, i did not make it static and i updated the .dll and rebuild the whole project each time I changed anything.

The _64 is not a 64-bit version it's just when I was trying to build with GCC-7.3.0 I used MinGW-64 and SFML and TGUI were in the same folder, so I put the _64 suffix to differentiate them.

And sorry everything wasn't set at it's real values in the .cbp project, I guess I played with it and didn't save it before sending it, here it is with good values that still don't work: https://pastebin.com/j3dqji1z
I also just tried to compile a static version but the result is the same :-/

texus

I still have no clue on what the issue could be and I'm starting to run out of ideas on what to test.

There is only one thing remaining that I could check. Would it be possible for you to create a complete bundle of the project and dependencies? Zip all SFML, TGUI files and your project, including the libraries and dlls that you build so that I can execute the exact same thing (you don't have to move the SFML and TGUI folders into your own project, I can put them on the right place on my pc manually). If it just runs here then it must be something about your computer, but if it doesn't then I can start replacing files with working copies from my pc until it works to find out where it is going wrong.

glagan

I uploaded the clean project (with everything fixed), TGUI and SFML : https://www.dropbox.com/s/ipddlbaxwgu3qx5/TestChildWindow.7z?dl=1
I didn't move the .dll to the bin folder of the project.

texus

Alright, I managed to reproduce it with the libraries you sent.
I already figured out that it doesn't crash if the lambda parameter takes a "const tgui::ChildWindow::Ptr &" as parameter (instead of "tgui::ChildWindow::Ptr").

texus

This turned out to be a bug in TGUI. The kind of bug that makes you wonder how it could possibly have worked on linux and in debug mode.

A ChildWindow** was basically casted to a void* which later got cast to a std::shared_ptr<ChildWindow>*. Accessing the pointer of the shared_ptr would still work because this is the first part of the shared_ptr class, but accessing the reference count would access memory that doesn't belong to the variable. My best guess as to why it works in debug mode is because the reference count part would have been NULL so that it just ignores it. In release mode it would contain garbage and crash when it tries to dereference it. That would also explain why a const reference fixed it: it wouldn't have to access the reference count in that situation.

Anyway, if you download the latest version from github then it should work.

glagan

Everything works now ! Thanks, seems like it was a tricky yet simple problem :)