fix(bar): avoid use-after-free segfault on exit
Members are destroyed in reverse declaration order, so modules_all_ (and the modules it owns) are gone before the GtkWindow. Tearing down a mapped window emits `unmap`, whose handler runs toggleSuspend() over the already freed modules. Disconnect the map/unmap handlers in ~Bar first. Fixes #5182
This commit is contained in:
@@ -131,6 +131,10 @@ class Bar : public sigc::trackable {
|
|||||||
|
|
||||||
waybar::util::KillSignalAction onSigusr1 = util::SIGNALACTION_DEFAULT_SIGUSR1;
|
waybar::util::KillSignalAction onSigusr1 = util::SIGNALACTION_DEFAULT_SIGUSR1;
|
||||||
waybar::util::KillSignalAction onSigusr2 = util::SIGNALACTION_DEFAULT_SIGUSR2;
|
waybar::util::KillSignalAction onSigusr2 = util::SIGNALACTION_DEFAULT_SIGUSR2;
|
||||||
|
|
||||||
|
/* Disconnected in ~Bar before the modules are destroyed (#5182). */
|
||||||
|
sigc::connection map_conn_;
|
||||||
|
sigc::connection unmap_conn_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace waybar
|
} // namespace waybar
|
||||||
|
|||||||
+8
-3
@@ -269,12 +269,12 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
|||||||
|
|
||||||
window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMap));
|
window.signal_map_event().connect_notify(sigc::mem_fun(*this, &Bar::onMap));
|
||||||
|
|
||||||
window.signal_unmap().connect([this]() {
|
unmap_conn_ = window.signal_unmap().connect([this]() {
|
||||||
spdlog::debug("Output {} unmapped (DPMS off), suspending modules", output->name);
|
spdlog::debug("Output {} unmapped (DPMS off), suspending modules", output->name);
|
||||||
toggleSuspend(true);
|
toggleSuspend(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
window.signal_map().connect([this]() {
|
map_conn_ = window.signal_map().connect([this]() {
|
||||||
spdlog::debug("Output {} mapped (DPMS on), resuming modules", output->name);
|
spdlog::debug("Output {} mapped (DPMS on), resuming modules", output->name);
|
||||||
toggleSuspend(false);
|
toggleSuspend(false);
|
||||||
});
|
});
|
||||||
@@ -352,7 +352,12 @@ waybar::Bar::Bar(struct waybar_output* w_output, const Json::Value& w_config)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Need to define it here because of forward declared members */
|
/* Need to define it here because of forward declared members */
|
||||||
waybar::Bar::~Bar() = default;
|
waybar::Bar::~Bar() {
|
||||||
|
/* Destroying the window emits `unmap`, whose handler runs toggleSuspend() over
|
||||||
|
* modules_all_ -- already freed by this point. Disconnect first (#5182). */
|
||||||
|
unmap_conn_.disconnect();
|
||||||
|
map_conn_.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
void waybar::Bar::setMode(const std::string& mode) {
|
void waybar::Bar::setMode(const std::string& mode) {
|
||||||
using namespace std::literals::string_literals;
|
using namespace std::literals::string_literals;
|
||||||
|
|||||||
Reference in New Issue
Block a user