Closed SaschaKoch closed 10 months ago
Hello,
Thanks for the feedback, I'll try to reproduce your issue as soon as possible. Yes child handling changes are probably the culprit in this issue...
Regards, Ludovic
@SaschaKoch
From my understanding, the issue seems to be when adding a Frame with a child to another Frame. I tried the code below, but I didn't get any error:
int main(int argc, char** argv)
{
egt::Application app(argc, argv);
egt::TopWindow window;
egt::Frame parent;
egt::expand(parent);
window.add(parent);
egt::Frame child;
egt::expand(child);
egt::Button btn("test");
child.add(btn);
parent.add(child);
window.show();
return app.run();
}
Could you share a minimal piece of code that is not working?
Regards, Ludovic
Sorry for the late reply, took me a while to reconstruct the original. Be aware the example probably doesn't display anything because I didn't take care of the show/hide functions for it. For me its not even getting through the main but aborting. Code worked in exactly that way with EGT 1.6 (at least I didn't change anything knowingly).
The issue occurs when adding a first frame (holding several widgets as children) to second frame as child, where the second frame is an array element and itself child of a third frame which is child of a topwindow.
I have three files involved:
Main.cpp (not sure if all includes are necessary for this example):
#include <egt/ui>
#include <iostream>
#include "MSGhandler.h"
using namespace std;
using namespace egt;
int main(int argc, const char ** argv)
{
Application app;
cout << "Setting up windows" << endl;
TopWindow mainWin;
TopWindow settingWin(mainWin, Rect(0, 0, XSize, YSize));
settingWin.name("SettingWindow");
cout << "Checkpoint 1" << endl;
initializeTest(&mainWin);
cout << "Checkpoint 8" << endl;
addTestMSG((USER_TESTMESSAGE)1);
cout << "Checkpoint 11" << endl;
mainWin.show();
return app.run();
}
MSGhandler.h
#ifndef MSGHANDLER_H_
#define MSGHANDLER_H_
#include <egt/ui>
using namespace std;
using namespace egt;
typedef enum
{
TEST_MSG1=0,
TEST_MSG2,
} USER_TESTMESSAGE;
void initializeTest(egt::TopWindow* mainWin);
void addTestMSG(USER_TESTMESSAGE msg);
egt::Frame* decodeMSGTest(USER_TESTMESSAGE msg);
#endif /* MSGHANDLER_H_ */
MSGhandler.cpp
#include "MSGhandler.h"
#include <egt/ui>
using namespace egt;
void initializeTest(egt::TopWindow* mainWin)
{
auto win = mainWin->find_child<TopWindow>("SettingWindow");
for (int i = 0; i < 5; i++)
{
MSG_FrameArr[i] = Frame(Rect(0,0,100,50));
MSG_FrameArr[i].name("MSGArrayElem_" + to_string(i));
}
cout << "Checkpoint 2" << endl;
auto MSG_Label1 = std::make_shared<Label>( "Text1", Rect(0,0,100,50), AlignFlag::left);
MSG_Label1->name("MSG_Label1");
auto MSG_Rect1 = std::make_shared<RectangleWidget>(Rect(50,0,50,50));
MSG_Rect1->color(Palette::ColorId::button_bg, Color(0,0,0,0));
MSG_Rect1->name("MSG_Rect1");
cout << "Checkpoint 3" << endl;
MSG_Test1.add(MSG_Label1);
MSG_Test1.add(MSG_Rect1);
cout << "Checkpoint 4" << endl;
auto MSG_Label2 = std::make_shared<Label>( "Text2", Rect(0,0,100,50), AlignFlag::left);
MSG_Label2->name("MSG_Label2");
auto MSG_Rect2 = std::make_shared<RectangleWidget>(Rect(50,0,50,50));
MSG_Rect2->color(Palette::ColorId::button_bg, Color(0,0,0,0));
MSG_Rect2->name("MSG_Rect2");
cout << "Checkpoint 5" << endl;
MSG_Test2.add(MSG_Label2);
MSG_Test2.add(MSG_Rect2);
cout << "Checkpoint 6" << endl;
for (int i = 0; i < 5; i++)
{
MSG_GeneralFrameTest.add(MSG_FrameArr[i]);
}
MSG_GeneralFrameTest.name("MSG_GeneralFrame");
win->add(MSG_GeneralFrameTest);
cout << "Checkpoint 7" << endl;
};
void addTestMSG(USER_TESTMESSAGE msg)
{
cout << "Checkpoint 9" << endl;
MSG_FrameArr[0].add(*decodeMSGTest(msg));
cout << "Checkpoint 10" << endl;
};
egt::Frame* decodeMSGTest(USER_TESTMESSAGE msg)
{
cout << "Checkpoint decoder" << endl;
switch (msg)
{
case 0:
{
cout << "Decoded MSG1" << endl;
return &MSG_Test1;
break;
}
case 1:
{
cout << "Decoded MSG2" << endl;
return &MSG_Test2;
break;
}
default:
{
cout << "Decoded default" << endl;
return nullptr;
}
}
};
The console output result is the following:
Setting up windows
Checkpoint 1
Checkpoint 2
Checkpoint 3
Checkpoint 4
Checkpoint 5
Checkpoint 6
Checkpoint 7
Checkpoint 8
Checkpoint 9
Checkpoint decoder
Decoded MSG2
then the program aborts with segmentation fault (core dump)
So I think the line with MSG_FrameArr[0].add(*decodeMSGTest(msg));
would cause the fault.
Thanks for you help already!
Hello,
Thanks for sharing code to reproduce the issue, but I'm not able to build this code. I did quick fixes, but I get a segfault earlier than you. How MSG_Test1, MSG_Test2 and MSG_GeneralFrameTest are declared?
Regards, Ludovic
Sorry, my fault. The Frames are declared in the MSGhandler.cpp right after the namespace:
MSGhandler.cpp
...
using namespace egt;
Frame MSG_GeneralFrameTest(Rect(118, 151, 575, 300));
Frame MSG_FrameArr[5];
Frame MSG_Test1(Rect(0,0, msg_width,msg_height));
Frame MSG_Test2(Rect(0,0, msg_width,msg_height));
void initializeTest(egt::TopWindow* mainWin)
{
....
Hi,
I did a copy/paste of your code and did this changes to make it compile:
diff --git a/MSGhandler.cpp b/MSGhandler.cpp
index 5cc4d8f..5afbf86 100644
--- a/MSGhandler.cpp
+++ b/MSGhandler.cpp
@@ -1,9 +1,13 @@
#include "MSGhandler.h"
#include <egt/ui>
+#include <iostream>
+using namespace std;
using namespace egt;
Frame MSG_GeneralFrameTest(Rect(118, 151, 575, 300));
Frame MSG_FrameArr[5];
+const int msg_width = 400;
+const int msg_height = 400;
Frame MSG_Test1(Rect(0,0, msg_width,msg_height));
Frame MSG_Test2(Rect(0,0, msg_width,msg_height));
diff --git a/main.cpp b/main.cpp
index 8d1bec6..b5ea779 100644
--- a/main.cpp
+++ b/main.cpp
@@ -5,6 +5,9 @@
using namespace std;
using namespace egt;
+const int XSize = 800;
+const int YSize = 480;
+
int main(int argc, const char ** argv)
{
Application app;
I hit check point 11. I have a segfault when closing the app but that's another story, I have not checked if it's due to the app or the library.
EGT_DEBUG=1 ./test
[info] EGT Version 1.7
[info] EGT Git Version d47fe51c
[info] X11 Screen
Setting up windows
[debug] window.cpp:306 Window8 backend is BasicWindow
[debug] window.cpp:306 Window9 backend is BasicWindow
Checkpoint 1
Checkpoint 2
Checkpoint 3
[debug] font.cpp:146 allocating font using Fontconfig: Free Sans
[debug] font.cpp:200 Font "Free Sans" not found: using default FreeSans font
Checkpoint 4
Checkpoint 5
Checkpoint 6
Checkpoint 7
Checkpoint 8
Checkpoint 9
Checkpoint decoder
Decoded MSG2
Checkpoint 10
Checkpoint 11
Hi, thanks for your help. I will have to further investigate what is different on my system. Will report if I find it.
I found a way of making it work. Seems like the culprit was in the function void initializeTest(egt::TopWindow* mainWin)
In the first for loop I assign Frames to each element of the MSG_FrameArr[] even though those elements are technically seen already Frames by declarationFrame MSG_FrameArr[5];
. If I do not assign new Frames to the elements but rather just resize and reposition of the existing elements to my needs (since the assigning is used for nothing else) the issue seems to be resolved and the program executes without any fault.
This is what I changed in the void initializeTest(egt::TopWindow* mainWin)
within the MSGhandler.cpp:
for (int i = 0; i < 5; i++)
{
//MSG_FrameArr[i] = Frame(Rect(0,0,100,50));
MSG_FrameArr[i].resize(Size(100,50));
MSG_FrameArr[i].move(Point(0,0));
MSG_FrameArr[i].name("MSGArrayElem_" + to_string(i));
}
I had a deeper look into it and the widget ID (read out with the function widgetid()) of each element of MSG_FrameArr would have change in the old implementation. In the new implementation where I only resize and move the elements they keep their initial ID of course. I have no idea why this worked with egt 1.6 and not with 1.7 nor how either of the two methods impact the overall program in such a way. My understanding of the egt or even C++ might simply be not sufficient.
If you have any idea about this issue I would be highly interested in learning about it. If not, its also okay, the program seems to run stable again :-)
Thanks again for your help !
Regards Sascha
Hello,
IDs changed because you constructed the Frames when you created your array, then you assigned new Frames to your array.
I can't tell you why it worked with 1.6 and no longer with 1.7. Regarding the change you did to make it work, I suspect an issue when moving Frames, maybe the default move is no longer appropriate and some members are not in the expected state after a move is done.
If you are able to compile EGT with debug symbols, could you share the backtrace when the segfault happened?
Regards, Ludovic
Hi,
I wont be able to do this for the next 4 weeks. So It's okay for me to put this issue on hold and I will get back to it in August.
Regards Sascha
Hi Ludovic,
sorry I never got back to this (and forgot about it). But the problem was solved sufficiently and didn't create any issues anymore.
Regards Sascha
Hi all,
for some display message handling I use an array of type Frame. Each element contains a Frame, specifying the position and Size. Each message I pre-defined consists again out of a Frame and several child widgets. Whenever I want to display one of those pre-defined messages I add() it to a Frame element in the array that has not yet any other children. This worked flawlessly up to EGT 1.6 and throws a segmentation fault now as soon as the I add() a message Frame to one of the Frames in the array.
The Frame array is defined as:
egt::Frame MSG_FrameArray[numOfFrames];
initialized with:
a typical message Frame is defeined as:
egt::Frame MSG_example(egt::Rect(...));
and initialized with:
However, as soon as I attach (add()) a message Frame now to the Frame array, my program crashes:
MSG_FrameArray[0].add(MSG_example);
I assume something must have changed a tiny little bit with the moving of the child handling from Frame to Widget with 1.7 which throws off my current code.
Regards Sascha