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 onSigusr2 = util::SIGNALACTION_DEFAULT_SIGUSR2;
|
||||
|
||||
/* Disconnected in ~Bar before the modules are destroyed (#5182). */
|
||||
sigc::connection map_conn_;
|
||||
sigc::connection unmap_conn_;
|
||||
};
|
||||
|
||||
} // 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_unmap().connect([this]() {
|
||||
unmap_conn_ = window.signal_unmap().connect([this]() {
|
||||
spdlog::debug("Output {} unmapped (DPMS off), suspending modules", output->name);
|
||||
toggleSuspend(true);
|
||||
});
|
||||
|
||||
window.signal_map().connect([this]() {
|
||||
map_conn_ = window.signal_map().connect([this]() {
|
||||
spdlog::debug("Output {} mapped (DPMS on), resuming modules", output->name);
|
||||
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 */
|
||||
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) {
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
Reference in New Issue
Block a user