-
Notifications
You must be signed in to change notification settings - Fork 8.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix a crash setting the hotkey during teardown #12580
Conversation
From MSFT:36797001. Okay so this is only .22% of our crashes, but every little bit helps, right?
@@ -967,6 +967,15 @@ winrt::fire_and_forget AppHost::_setupGlobalHotkeys() | |||
// The hotkey MUST be registered on the main thread. It will fail otherwise! | |||
co_await winrt::resume_foreground(_logic.GetRoot().Dispatcher()); | |||
|
|||
if (!_window) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah we null it out properly too? Awesome
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, is this sufficient? The only time we will observe _window
to be null is after our destructor has run... which would make accessing &this->_window
an AV (or UB). We need to make sure that AppHost is properly lifetime-managed before we get here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AH YOU'D THINK
Looking at the stack, this hits in this sliver of time where we've called ~AppHost
, we've nulled out the _window
, but then the Dispatcher like, runs a bunch more and... flushes callbacks? I'm not sure what it's doing here. There's been miscellaneous crashes over the last few months where like, we try to set the title of the window but it doesn't exist, because we're in this bit of Dispatcher rundown. This is just another version of that. They're all crashes once we've already started tearing down, so they're not that user-impactful, but they still happen.
IDK if it's safe to just gank the Dispatcher
before we null out the _window
to release the XAML bits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the ~AppHost
dtor is not on the stack, it is still UB to access this member; I'm concerned this is a band-aid? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh sorry, to clarify, the ~AppHost
dtor is on the stack here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
notes
He's on vacation and this fix is affecting internal reliability calculations. And Griese answered the notes.
This comment was marked as resolved.
This comment was marked as resolved.
winrt::TerminalApp::AppLogic::CloseRequested_revoker _CloseRequestedRevoker; | ||
winrt::TerminalApp::AppLogic::RequestedThemeChanged_revoker _RequestedThemeChangedRevoker; | ||
winrt::TerminalApp::AppLogic::FullscreenChanged_revoker _FullscreenChangedRevoker; | ||
winrt::TerminalApp::AppLogic::FocusModeChanged_revoker _FocusModeChangedRevoker; | ||
winrt::TerminalApp::AppLogic::AlwaysOnTopChanged_revoker _AlwaysOnTopChangedRevoker; | ||
winrt::TerminalApp::AppLogic::RaiseVisualBell_revoker _RaiseVisualBellRevoker; | ||
winrt::TerminalApp::AppLogic::SystemMenuChangeRequested_revoker _SystemMenuChangeRequestedRevoker; | ||
winrt::TerminalApp::AppLogic::ChangeMaximizeRequested_revoker _ChangeMaximizeRequestedRevoker; | ||
winrt::TerminalApp::AppLogic::TitleChanged_revoker _TitleChangedRevoker; | ||
winrt::TerminalApp::AppLogic::LastTabClosed_revoker _LastTabClosedRevoker; | ||
winrt::TerminalApp::AppLogic::SetTaskbarProgress_revoker _SetTaskbarProgressRevoker; | ||
winrt::TerminalApp::AppLogic::IdentifyWindowsRequested_revoker _IdentifyWindowsRequestedRevoker; | ||
winrt::TerminalApp::AppLogic::RenameWindowRequested_revoker _RenameWindowRequestedRevoker; | ||
winrt::TerminalApp::AppLogic::SettingsChanged_revoker _SettingsChangedRevoker; | ||
winrt::TerminalApp::AppLogic::IsQuakeWindowChanged_revoker _IsQuakeWindowChangedRevoker; | ||
winrt::TerminalApp::AppLogic::SummonWindowRequested_revoker _SummonWindowRequestedRevoker; | ||
winrt::TerminalApp::AppLogic::OpenSystemMenu_revoker _OpenSystemMenuRevoker; | ||
winrt::TerminalApp::AppLogic::QuitRequested_revoker _QuitRequestedRevoker; | ||
winrt::Microsoft::Terminal::Remoting::WindowManager::ShowNotificationIconRequested_revoker _ShowNotificationIconRequestedRevoker; | ||
winrt::Microsoft::Terminal::Remoting::WindowManager::HideNotificationIconRequested_revoker _HideNotificationIconRequestedRevoker; | ||
winrt::Microsoft::Terminal::Remoting::WindowManager::QuitAllRequested_revoker _QuitAllRequestedRevoker; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woof. This is going to be the next candidate to be put into the macros.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I quite nearly had a std::deque<>
of event revokers that I just pushed them all into, then pop'd and revoked, but alas, I'm not lucky enough to have them all share some common base class ;____;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good with this.
If you can imagine a way that we could remove this foot-gun with further X-macros... please file that follow-on (aka automate the creation of the revokers and the revocations).
Otherwise just get your typo and let's get this on its way to merging in.
Hello @zadjii-msft! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
From MSFT:36797001. Okay so this is only .22% of our crashes, but every little bit helps, right? Turns out this is also hitting in: * MSFT:35726322 * MSFT:34662459 and together they're a fairly hot bug. There's a large class of bugs where we might get a callback to one of our event handlers when we call `app.Close()` in the `AppHost` dtor. This PR adds manual revokers to these events, and makes sure to revoke them BEFORE nulling out the `_window`. That will prevent callbacks during the rest of the dtor, when the `_window` is null.
From MSFT:36797001. Okay so this is only .22% of our crashes, but every little bit helps, right? Turns out this is also hitting in: * MSFT:35726322 * MSFT:34662459 and together they're a fairly hot bug. There's a large class of bugs where we might get a callback to one of our event handlers when we call `app.Close()` in the `AppHost` dtor. This PR adds manual revokers to these events, and makes sure to revoke them BEFORE nulling out the `_window`. That will prevent callbacks during the rest of the dtor, when the `_window` is null. (cherry picked from commit 8962c75)
🎉 Handy links: |
🎉 Handy links: |
From MSFT:36797001. Okay so this is only .22% of our crashes, but every little bit helps, right?
Turns out this is also hitting in:
and together they're a fairly hot bug.
There's a large class of bugs where we might get a callback to one of our event handlers when we call
app.Close()
in theAppHost
dtor. This PR adds manual revokers to these events, and makes sure to revoke them BEFORE nulling out the_window
. That will prevent callbacks during the rest of the dtor, when the_window
is null.