forked from Mirrors/openclonk
Make console destruction more deterministic
This fixes a crash on Linux when exiting the editor. It was caused by C4Console::~C4Console being called by the C++ runtime after after main() returned. The C4Console destructor then goes and deletes all the Qt resources (QApplication and friends), and that caused a segfault, maybe because some of the static Qt structures have already been deallocated. Fix this by making the destruction of the Qt components deterministic. Add a function "DeleteConsoleWindow" which deletes all the Qt components, and call this function in C4Console::Clear.console-destruction
parent
a56d2fecdb
commit
2d324c10e0
|
@ -368,15 +368,18 @@ void C4Console::Default()
|
|||
|
||||
void C4Console::Clear()
|
||||
{
|
||||
if (pSurface) delete pSurface;
|
||||
pSurface = 0;
|
||||
|
||||
C4Window::Clear();
|
||||
C4ConsoleGUI::DeleteConsoleWindow();
|
||||
|
||||
EditCursor.Clear();
|
||||
ToolsDlg.Clear();
|
||||
PropertyDlgClose();
|
||||
ClearViewportMenu();
|
||||
ClearPlayerMenu();
|
||||
ClearNetMenu();
|
||||
if (pSurface) delete pSurface;
|
||||
pSurface = 0;
|
||||
#ifndef _WIN32
|
||||
Application.Quit();
|
||||
#endif
|
||||
|
@ -622,6 +625,7 @@ bool C4ConsoleGUI::CreateConsoleWindow(C4AbstractApp * pApp)
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
void C4ConsoleGUI::DeleteConsoleWindow() {}
|
||||
void C4ConsoleGUI::DisplayInfoText(C4ConsoleGUI::InfoTextType, StdStrBuf&) {}
|
||||
void C4ConsoleGUI::DoEnableControls(bool) {}
|
||||
bool C4ConsoleGUI::DoUpdateHaltCtrls(bool) {return 0;}
|
||||
|
|
|
@ -73,6 +73,10 @@ bool C4ConsoleGUI::CreateConsoleWindow(C4AbstractApp *application)
|
|||
return true;
|
||||
}
|
||||
|
||||
void C4ConsoleGUI::DeleteConsoleWindow()
|
||||
{
|
||||
}
|
||||
|
||||
void C4ConsoleGUI::Out(const char* message)
|
||||
{
|
||||
C4EditorWindowController* controller = ctrler(this);
|
||||
|
|
|
@ -123,6 +123,7 @@ public:
|
|||
void SetInputFunctions(std::list<const char*> &functions);
|
||||
|
||||
bool CreateConsoleWindow(C4AbstractApp *application);
|
||||
void DeleteConsoleWindow();
|
||||
void Out(const char* message);
|
||||
bool ClearLog();
|
||||
void DisplayInfoText(InfoTextType type, StdStrBuf& text);
|
||||
|
|
|
@ -90,6 +90,15 @@ bool C4ConsoleGUI::CreateConsoleWindow(C4AbstractApp *application)
|
|||
return true;
|
||||
}
|
||||
|
||||
void C4ConsoleGUI::DeleteConsoleWindow()
|
||||
{
|
||||
if (Active)
|
||||
{
|
||||
state->DeleteConsoleWindow();
|
||||
Active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void C4ConsoleGUI::Out(const char* message)
|
||||
{
|
||||
// Log text: Add to log window
|
||||
|
|
|
@ -734,6 +734,46 @@ bool C4ConsoleGUIState::CreateConsoleWindow(C4AbstractApp *app)
|
|||
return true;
|
||||
}
|
||||
|
||||
void C4ConsoleGUIState::DeleteConsoleWindow()
|
||||
{
|
||||
// Reset to a state before CreateConsoleWindow was called
|
||||
action_object = C4VNull;
|
||||
is_object_selection_updating = false;
|
||||
|
||||
editcursor_mode = C4CNS_ModePlay;
|
||||
drawing_tool = C4TLS_Brush;
|
||||
landscape_mode = LandscapeMode::Dynamic;
|
||||
net_enabled = false;
|
||||
recording = false;
|
||||
enabled = false;
|
||||
|
||||
window_menu_separator = nullptr;
|
||||
status_cursor = status_framecounter = status_timefps = nullptr;
|
||||
|
||||
while (!viewports.empty())
|
||||
{
|
||||
auto vp = viewports.front();
|
||||
viewports.erase(viewports.begin());
|
||||
|
||||
vp->deleteLater();
|
||||
viewport_area->removeDockWidget(vp);
|
||||
}
|
||||
|
||||
client_actions.clear();
|
||||
player_actions.clear();
|
||||
viewport_actions.clear();
|
||||
viewport_area = nullptr;
|
||||
|
||||
disable_shortcut_filter.reset(nullptr);
|
||||
definition_list_model.reset(nullptr);
|
||||
object_list_model.reset(nullptr);
|
||||
property_name_delegate.reset(nullptr);
|
||||
property_delegate_factory.reset(nullptr);
|
||||
property_model.reset(nullptr);
|
||||
window.reset(nullptr);
|
||||
application.reset(nullptr);
|
||||
}
|
||||
|
||||
void C4ConsoleGUIState::Execute(bool redraw_only)
|
||||
{
|
||||
// Nothing to do - Qt's event loop is handling everything.
|
||||
|
|
|
@ -220,6 +220,7 @@ public:
|
|||
|
||||
void AddToolbarSpacer(int space);
|
||||
bool CreateConsoleWindow(C4AbstractApp *app);
|
||||
void DeleteConsoleWindow();
|
||||
void Execute(bool redraw_only=false);
|
||||
void Redraw() { Execute(true); }
|
||||
void UpdateActionStates();
|
||||
|
|
|
@ -830,6 +830,10 @@ bool C4ConsoleGUI::CreateConsoleWindow(C4AbstractApp *application)
|
|||
return true;
|
||||
}
|
||||
|
||||
void C4ConsoleGUI::DeleteConsoleWindow()
|
||||
{
|
||||
}
|
||||
|
||||
void C4ConsoleGUI::DoEnableControls(bool fEnable)
|
||||
{
|
||||
// Set button images (edit modes & halt controls)
|
||||
|
|
Loading…
Reference in New Issue