1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 17:47:44 +00:00

HackStudio: Don't store a global RefPtr to the HackStudioWidget

Previously, we stored a RefPtr to the HackStudioWidget in the
global scope.

This led to a destruction-order related use-after-free bug, where the
global HackStudioWidget instance destructed after the static-local
GUI::Clipboard instance.
When HackStudioWidget destructs it attempts to use the global Clipboard
instance, which had already been freed.

This caused the Hack Studio process to spin endlessly on exit because
it attempted to access the HashTable of the freed Clipboard object.

We now store a global WeakPtr to the HackStudioWidget instead, and
limit the lifetime of the object to the main function scope.
This commit is contained in:
Itamar 2022-02-18 17:18:22 +02:00 committed by Andreas Kling
parent 895a050e04
commit 4d2357f8f3

View file

@ -27,7 +27,7 @@
using namespace HackStudio;
static RefPtr<HackStudioWidget> s_hack_studio_widget;
static WeakPtr<HackStudioWidget> s_hack_studio_widget;
static bool make_is_available();
static void notify_make_not_available();
@ -63,24 +63,25 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
if (argument_absolute_path.is_null() || mode_coredump)
project_path = Core::File::real_path_for(".");
s_hack_studio_widget = TRY(window->try_set_main_widget<HackStudioWidget>(project_path));
auto hack_studio_widget = TRY(window->try_set_main_widget<HackStudioWidget>(project_path));
s_hack_studio_widget = hack_studio_widget;
window->set_title(String::formatted("{} - Hack Studio", s_hack_studio_widget->project().name()));
window->set_title(String::formatted("{} - Hack Studio", hack_studio_widget->project().name()));
s_hack_studio_widget->initialize_menubar(*window);
hack_studio_widget->initialize_menubar(*window);
window->on_close_request = [&]() -> GUI::Window::CloseRequestDecision {
s_hack_studio_widget->locator().close();
if (s_hack_studio_widget->warn_unsaved_changes("There are unsaved changes, do you want to save before exiting?") == HackStudioWidget::ContinueDecision::Yes)
hack_studio_widget->locator().close();
if (hack_studio_widget->warn_unsaved_changes("There are unsaved changes, do you want to save before exiting?") == HackStudioWidget::ContinueDecision::Yes)
return GUI::Window::CloseRequestDecision::Close;
return GUI::Window::CloseRequestDecision::StayOpen;
};
window->show();
s_hack_studio_widget->update_actions();
hack_studio_widget->update_actions();
if (mode_coredump)
s_hack_studio_widget->open_coredump(argument_absolute_path);
hack_studio_widget->open_coredump(argument_absolute_path);
return app->exec();
}