Repository: microsoft/terminal (language: cpp)

Issue:
Crash while holding a key
### Windows Terminal version

1.13.11432.0

### Windows build number

10.0.22621.1

### Other Software

in WSL I'm running 
- Debian 11 on kernel `5.10.102.1-microsoft-standard-WSL2` 
- fish shell (version 3.4.1) 
- vim (version 8.2)

### Steps to reproduce

I'm not sure what the exact steps to reproduce are, I've seen this crash a few times in the last couple days while holding a key in vim. Trying to find a more reliable way to reproduce but here's what is common across the crashes:

- terminal session was running for at least 1 hour (although one session lasted ~18 hours)
- terminal window contained multiple tabs with separate sessions on the same WSL2 vm
- when it crashes it takes every tab in the terminal window and the underlying WSL2 session with it
- a separate terminal window running an elevated powershell session survives the other window crashing
- crash occurs less than a second after I begin to hold a navigation key in vim (in debian on a WSL2 vm)
- before the crash, I'm able to hold navigation keys without issue
- I don't think it's related to #10957, fairly sure the motion I was performing in vim would not cause a bell. Also I'm able to run `tput bel` in a loop for at least 10 minutes without any issues (stopped at 10 mins for my ears' sake).


### Expected Behavior

Terminal window doesn't crash from underneath me while editing in vim.

### Actual Behavior

After a long time with no issues, terminal crashes less than a second after pressing and holding a navigation key (e.g. `j`, `h`) in vim. The crash takes out every terminal tab in the window and kills the WSL2 vm so I can't reattach and recover my state.


Event viewer report blames `Microsoft.Terminal.Control.dll` in each of the crashes that it has events logged for:

Logged at 6/21/2022 1:23:57 PM:
```
Faulting application name: WindowsTerminal.exe, version: 1.13.2205.23002, time stamp: 0x628bd6e5
Faulting module name: Microsoft.Terminal.Control.dll, version: 1.13.2205.23002, time stamp: 0x628bd501
Exception code: 0xc0000005
Fault offset: 0x00000000000a7031
Faulting process id: 0x0x81D0
Faulting application start time: 0x0x1D885A331CB7DF5
Faulting application path: C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe
Faulting module path: C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe\Microsoft.Terminal.Control.dll
Report Id: 231fb379-0618-424f-b270-4abcd9c76e91
Faulting package full name: Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe
Faulting package-relative application ID: App
```

Logged at 6/21/2022 12:14:47 PM:
```
Faulting application name: WindowsTerminal.exe, version: 1.13.2205.23002, time stamp: 0x628bd6e5
Faulting module name: Microsoft.Terminal.Control.dll, version: 1.13.2205.23002, time stamp: 0x628bd501
Exception code: 0xc0000005
Fault offset: 0x00000000000a7031
Faulting process id: 0x0x2E18
Faulting application start time: 0x0x1D8850DAF2A21D3
Faulting application path: C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe
Faulting module path: C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe\Microsoft.Terminal.Control.dll
Report Id: 16e18e82-72ce-4917-b27c-ad1086de5754
Faulting package full name: Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe
Faulting package-relative application ID: App
```

Logged at 6/20/2022 6:24:36 PM:
```
Faulting application name: WindowsTerminal.exe, version: 1.13.2205.23002, time stamp: 0x628bd6e5
Faulting module name: Microsoft.Terminal.Control.dll, version: 1.13.2205.23002, time stamp: 0x628bd501
Exception code: 0xc0000005
Fault offset: 0x00000000000a7031
Faulting process id: 0x0x7B30
Faulting application start time: 0x0x1D884FA55D2CF69
Faulting application path: C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe
Faulting module path: C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe\Microsoft.Terminal.Control.dll
Report Id: 5e7df318-5652-4433-8a12-0537323b2c06
Faulting package full name: Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe
Faulting package-relative application ID: App
```

Logged at 6/20/2022 4:05:15 PM:
```
Faulting application name: WindowsTerminal.exe, version: 1.13.2205.23002, time stamp: 0x628bd6e5
Faulting module name: Microsoft.Terminal.Control.dll, version: 1.13.2205.23002, time stamp: 0x628bd501
Exception code: 0xc0000005
Fault offset: 0x00000000000a5999
Faulting process id: 0x0x63FC
Faulting application start time: 0x0x1D880EA93FD3C3A
Faulting application path: C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe
Faulting module path: C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe\Microsoft.Terminal.Control.dll
Report Id: 157dd4ea-2879-4dd5-92bf-41d9449cc517
Faulting package full name: Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe
Faulting package-relative application ID: App
```


Discussion / hints:
Hmm. This is 1.13 so it's not the alt buffer crash. 

> and kills the WSL2 vm

Well, now, that certainly sounds like a bigger issue than just us. Though, maybe if all the WSL sessions go away, it exits itself? I'm less familiar with the machinations of WSL2. 
Nah this definitely is us. Right now the top 5 crashes in TerminalControl are code `c0000005`...
> maybe if all the WSL sessions go away, it exits itself?

Not sure but I've had WSL2 survive the Windows Store closing my terminal windows on me to update terminal and was able to reattach to the shell processes in a new terminal window.
`c0000005` is meaningless though 🙃 I wish we could get something useful there
Those addresses point into...

```
% & llvm-symbolizer.exe --obj=microsoft.terminal.control.dll "CODE 0x00000000000a7031" "CODE 0xa5999" --basenames
int (__cdecl *`bool __cdecl winrt::impl::invoke<struct winrt::Windows::Foundation::TypedEventHandler<struct winrt::Windows::Foundation::IInspectable, struct winrt::hstring>, struct winrt::Microsoft::Terminal::Control::implementation::InteractivityAutomationPeer, struct winrt::hstring>(struct winrt::Windows::Foundation::TypedEventHandler<struct winrt::Windows::Foundation::IInspectable, struct winrt::hstring> const &, struct winrt::Microsoft::Terminal::Control::implementation::InteractivityAutomationPeer const &, struct winrt::hstring const &)'::`4'::handler)(int, int, void *) noexcept
int (__cdecl *`bool __cdecl winrt::impl::invoke<struct winrt::Windows::Foundation::TypedEventHandler<struct winrt::Windows::Foundation::IInspectable, struct winrt::hstring>, struct winrt::Microsoft::Terminal::Control::implementation::InteractivityAutomationPeer, struct winrt::hstring>(struct winrt::Windows::Foundation::TypedEventHandler<struct winrt::Windows::Foundation::IInspectable, struct winrt::hstring> const &, struct winrt::Microsoft::Terminal::Control::implementation::InteractivityAutomationPeer const &, struct winrt::hstring const &)'::`4'::handler)(int, int, void *) noexcept
```

which are invokers for events coming out of InteractivityAutomationPeer with this signature:

```
event Windows.Foundation.TypedEventHandler<Object, String> NewOutput;
TYPED_EVENT(NewOutput, IInspectable, hstring);
```

Which is likely to be failure hash `3f46a289-653a-34ba-9a2a-379ba23358cd` (our highest hitter, at 89% of all TermControl crashes!)
Found one more error event from `WindowsTerminal.exe` that I accidentally filtered out in the first post. Not sure if it's relevant since it's the only event I see with this exception code and only occurred after the one crash.

It was logged 33 seconds after the oldest event at the bottom of the first post. Its contents exactly match the preceding event except that it has `Exception code: 0xc000041d` and `Report Id: d8bf9507-2bc6-4258-9a8e-3f00959f94e6`:

Logged at 6/20/2022 4:05:48 PM:
```
Faulting application name: WindowsTerminal.exe, version: 1.13.2205.23002, time stamp: 0x628bd6e5
Faulting module name: Microsoft.Terminal.Control.dll, version: 1.13.2205.23002, time stamp: 0x628bd501
Exception code: 0xc000041d
Fault offset: 0x00000000000a5999
Faulting process id: 0x0x63FC
Faulting application start time: 0x0x1D880EA93FD3C3A
Faulting application path: C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe
Faulting module path: C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe\Microsoft.Terminal.Control.dll
Report Id: d8bf9507-2bc6-4258-9a8e-3f00959f94e6
Faulting package full name: Microsoft.WindowsTerminal_1.13.11432.0_x64__8wekyb3d8bbwe
Faulting package-relative application ID: App
```
I'll stick this in 1.15 for now. We've got a live report of this crash, we should take a closer look. MSFT:39994969 is the internal bug. 

The blame on the failure has the following stack:

```
  DirectUI::AutomationPeer::RaiseAutomationEventImpl
  DirectUI::AutomationPeerGenerated::RaiseAutomationEvent
  TermControlAutomationPeer_::RaiseAutomationEvent
> TermControlAutomationPeer::SignalTextChanged
```

Which is definitely different than the `NotifyNewOutput` frame. The notify new output code was in `Preview v1.13.1073` & `Stable v1.12.1073`, in #12358, so that's definitely in this build. 

Ironically, I can't open any dumps from that failure without breaking into the post-moretem debugger for windbg itself, spiderman.png. 
Huh. A bunch of these dumps are all north of `~AppHost`. Like, we're already tearing down the app for some reason, and then flushing the dispatcher queue, which is triggering this

<details>
<summary>example</summary>

```
0:000> k
 # Call Site
00 Windows_UI_Xaml!ctl::ComPtr<Windows::UI::Xaml::Automation::Peers::IAutomationPeer>::{dtor} 
01 Windows_UI_Xaml!DirectUI::AutomationPeer::RaiseAutomationEventImpl+0x78 
02 Windows_UI_Xaml!DirectUI::AutomationPeerGenerated::RaiseAutomationEvent+0x44 
03 Microsoft_Terminal_Control!winrt::impl::consume_Windows_UI_Xaml_Automation_Peers_IAutomationPeer<winrt::Microsoft::Terminal::Control::implementation::TermControlAutomationPeer>::RaiseAutomationEvent+0x58 
04 Microsoft_Terminal_Control!winrt::Microsoft::Terminal::Control::implementation::TermControlAutomationPeer::SignalTextChanged::__l2::<lambda_1>::operator()+0x2e 
05 Microsoft_Terminal_Control!winrt::impl::delegate<winrt::Windows::UI::Core::DispatchedHandler,`winrt::Microsoft::Terminal::Control::implementation::TermControlAutomationPeer::SignalTextChanged'::`2'::<lambda_1> >::Invoke+0x32 
06 Windows_UI!<lambda_59517943c03487243f9bea31c6c1a784>::operator()+0x84 
07 Windows_UI!Microsoft::WRL::Details::DelegateArgTraits<long (__cdecl Windows::System::IDispatcherQueueHandler::*)(void)>::DelegateInvokeHelper<Microsoft::WRL::Implements<Microsoft::WRL::RuntimeClassFlags<2>,Windows::System::IDispatcherQueueHandler,Microsoft::WRL::FtmBase>,<lambda_59517943c03487243f9bea31c6c1a784>,-1>::Invoke+0xf 
08 CoreMessaging!Windows::System::DispatcherQueue::DeferInvokeCallback+0x20 
09 CoreMessaging!Microsoft::CoreUI::ActionCallback::ImportAdapter$::__l2::<lambda_a81ff790741c2a62f2197c2561f5fe49>::operator()+0x1f 
0a CoreMessaging!CFlat::SehSafe::Execute<<lambda_a81ff790741c2a62f2197c2561f5fe49> >+0x2c 
0b CoreMessaging!Microsoft::CoreUI::ActionCallback::ImportAdapter$+0xae 
0c CoreMessaging!CFlat::DelegateImpl<Microsoft::CoreUI::ActionCallback,0,void __cdecl(void),long __cdecl(void *),0>::Invoke+0x26 
0d CoreMessaging!Microsoft::CoreUI::Dispatch::DeferredCall::Callback_Dispatch+0x2bf 
0e CoreMessaging!Microsoft::CoreUI::Dispatch::DeferredCallDispatcher::Callback_OnDispatch+0x12b 
0f CoreMessaging!Microsoft::CoreUI::Dispatch::Dispatcher::Callback_DispatchNextItem+0x11b 
10 CoreMessaging!Microsoft::CoreUI::Dispatch::Dispatcher::Callback_DispatchLoop+0x1df 
11 CoreMessaging!Microsoft::CoreUI::Dispatch::EventLoop::Callback_RunCoreLoop+0x2ed 
12 CoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::DrainCoreMessagingQueue+0x195 
13 CoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::OnUserDispatch+0x214 
14 CoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::OnUserDispatchRaw+0x69 
15 CoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::DoWork+0x1fc 
16 CoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::WindowProc+0x4f 
17 user32!UserCallWinProcCheckWow+0x33c 
18 user32!DispatchClientMessage+0x9c 
19 user32!__fnDWORD+0x3d 
1a ntdll!KiUserCallbackDispatcherContinue 
1b win32u!ZwUserPeekMessage+0x14 
1c user32!_PeekMessage+0x3f 
1d user32!PeekMessageW+0x13a 
1e Microsoft_Toolkit_Win32_UI_XamlHost!winrt::Microsoft::Toolkit::Win32::UI::XamlHost::implementation::XamlApplication::Close+0x145 
1f Microsoft_Toolkit_Win32_UI_XamlHost!winrt::impl::produce<winrt::Microsoft::Toolkit::Win32::UI::XamlHost::implementation::XamlApplication,winrt::Windows::Foundation::IClosable>::Close+0x19 
20 WindowsTerminal!winrt::impl::consume_Windows_Foundation_IClosable<winrt::TerminalApp::App>::Close+0x1f 
21 WindowsTerminal!AppHost::~AppHost+0x1a4 
```

</details>

This is just another one of these callback after teardown bugs. Maybe we do need the apphost dtor to just `std::exit()`, cause we keep hitting this.

That being said, that just means the app was already closing, which kinda implies that something else started taking the Terminal down already. 

<hr>

EDIT: 8/29 investigation notes

<details>
<summary>Details</summary>

```
0:000> dv
     strongThis = struct winrt::com_ptr<winrt::Microsoft::Terminal::Control::implementation::TermControlAutomationPeer>
0:000> dx -r1 (*((Microsoft_Terminal_Control!winrt::com_ptr<winrt::Microsoft::Terminal::Control::implementation::TermControlAutomationPeer> *)0xb1db0fec68))
(*((Microsoft_Terminal_Control!winrt::com_ptr<winrt::Microsoft::Terminal::Control::implementation::TermControlAutomationPeer> *)0xb1db0fec68))                 [Type: winrt::com_ptr<winrt::Microsoft::Terminal::Control::implementation::TermControlAutomationPeer>]
    [+0x000] m_ptr            : 0x1d158c0aec0 [Type: winrt::Microsoft::Terminal::Control::implementation::TermControlAutomationPeer *]
0:000> dx -r1 ((Microsoft_Terminal_Control!winrt::Microsoft::Terminal::Control::implementation::TermControlAutomationPeer *)0x1d158c0aec0)
((Microsoft_Terminal_Control!winrt::Microsoft::Terminal::Control::implementation::TermControlAutomationPeer *)0x1d158c0aec0)                 : 0x1d158c0aec0 [Type: winrt::impl::heap_implements<winrt::Microsoft::Terminal::Control::implementation::TermControlAutomationPeer> * (derived from winrt::Microsoft::Terminal::Control::implementation::TermControlAutomationPeer *)]
    ......
    [+0x008] m_inner          [Type: winrt::Windows::Foundation::IInspectable]
    [+0x010] m_references     : 0x800000e8ac651660 [Type: std::atomic<unsigned __int64>]
    [+0x070] _termControl     : 0x1d1579695d0 [Type: winrt::Microsoft::Terminal::Control::implementation::TermControl *]
    [+0x078] _contentAutomationPeer [Type: winrt::Microsoft::Terminal::Control::InteractivityAutomationPeer]
    [+0x080] _keyEvents       : { size=0x0 } [Type: std::deque<wchar_t,std::allocator<wchar_t> >]
0:000> dx -r1 ((Microsoft_Terminal_Control!winrt::Microsoft::Terminal::Control::implementation::TermControl *)0x1d1579695d0)
((Microsoft_Terminal_Control!winrt::Microsoft::Terminal::Control::implementation::TermControl *)0x1d1579695d0)                 : 0x1d1579695d0 [Type: winrt::impl::heap_implements<winrt::Microsoft::Terminal::Control::implementation::TermControl> * (derived from winrt::Microsoft::Terminal::Control::implementation::TermControl *)]
    ......
    is_composing     : true [Type: bool]
    [+0x008] m_inner          [Type: winrt::Windows::Foundation::IInspectable]
    [+0x010] m_references     : 0x800000e8ac29efb0 [Type: std::atomic<unsigned __int64>]
    [+0x088] _contentLoaded   : true [Type: bool]
    [+0x1c8] _automationPeer  [Type: winrt::Microsoft::Terminal::Control::TermControlAutomationPeer]
    [+0x1d0] _interactivity   [Type: winrt::Microsoft::Terminal::Control::ControlInteractivity]
    [+0x1d8] _core            [Type: winrt::Microsoft::Terminal::Control::ControlCore]
    [+0x1e0] _searchBox       [Type: winrt::com_ptr<winrt::Microsoft::Terminal::Control::implementation::SearchBoxControl>]
    [+0x1e8] _closing         : true [Type: bool]
    [+0x1e9] _focused         : false [Type: bool]
    [+0x1ea] _initializedTerminal : true [Type: bool]
    [+0x1f0] _playWarningBell : {...} [Type: std::shared_ptr<ThrottledFunc<1> >]
    [+0x200] _updateScrollBar : {...} [Type: std::shared_ptr<ThrottledFunc<0,winrt::Microsoft::Terminal::Control::implementation::TermControl::ScrollBarUpdate> >]
    [+0x210] _isInternalScrollBarUpdate : false [Type: bool]
    [+0x218] _autoScrollVelocity : 0.000000 [Type: double]
    [+0x220] _autoScrollingPointerPoint : nullopt [Type: std::optional<winrt::Windows::UI::Input::PointerPoint>]
    [+0x230] _autoScrollTimer [Type: winrt::Windows::UI::Xaml::DispatcherTimer]
    [+0x238] _lastAutoScrollUpdateTime : nullopt [Type: std::optional<std::chrono::time_point<std::chrono::steady_clock,std::chrono::duration<__int64,std::ratio<1,1000000000> > > >]
    [+0x248] _pointerPressedInBounds : false [Type: bool]
    [+0x250] _bellLightAnimation [Type: winrt::Windows::UI::Composition::ScalarKeyFrameAnimation]
    [+0x258] _bellLightTimer  [Type: winrt::Windows::UI::Xaml::DispatcherTimer]
    [+0x260] _cursorTimer     : {...} [Type: std::optional<winrt::Windows::UI::Xaml::DispatcherTimer>]
    [+0x270] _blinkTimer      : {...} [Type: std::optional<winrt::Windows::UI::Xaml::DispatcherTimer>]
    [+0x280] _layoutUpdatedRevoker [Type: winrt::impl::event_revoker<winrt::Windows::UI::Xaml::IFrameworkElement,&winrt::impl::abi<winrt::Windows::UI::Xaml::IFrameworkElement,void>::type::`vcall'{400}'>]
0:000> dx -r1 (*((Microsoft_Terminal_Control!winrt::Microsoft::Terminal::Control::ControlCore *)0x1d1579697a8))
(*((Microsoft_Terminal_Control!winrt::Microsoft::Terminal::Control::ControlCore *)0x1d1579697a8))                 [Type: winrt::Microsoft::Terminal::Control::ControlCore]
    [+0x000] m_ptr            : 0x1d15457e6b0 : [object Object] [Type: winrt::impl::abi<winrt::Windows::Foundation::IUnknown,void>::type *]
0:000> dx -r1 (*((Microsoft_Terminal_Control!winrt::Microsoft::Terminal::Control::TermControlAutomationPeer *)0x1d157969798))
(*((Microsoft_Terminal_Control!winrt::Microsoft::Terminal::Control::TermControlAutomationPeer *)0x1d157969798))                 [Type: winrt::Microsoft::Terminal::Control::TermControlAutomationPeer]
    [+0x000] m_ptr            : 0x1d158c0aed8 : [object Object] [Type: winrt::impl::abi<winrt::Windows::Foundation::IUnknown,void>::type *]
```

</details>

Interesting bits:
* The `_core` is already `_closing` 
* the automation peer wasn't nulled out (but that could just be garbage)
* I'd bet that what's happening is a `Release` on something that's not really a com_ptr here, the `impl::TermControl*`
Hey @iamevn, would you be able to grab a trace from the feedback hub, taking a recording while you repro it? We haven't been able to positively match this against other crashes we've been seeing.

If you have the Advanced Diagnostics section in Feedback Hub, you can do this entirely locally without uploading the traces to Microsoft's servers:

<img width="843" alt="image" src="https://user-images.githubusercontent.com/189190/177425497-ffe386bb-1b33-4a83-b65a-81ffd39fcfaa.png">

After you stop recording, give it a couple minutes and follow this File Location link:

<img width="302" alt="image" src="https://user-images.githubusercontent.com/189190/177425579-cd16080d-6f49-4470-8e6f-32be64138088.png">

The archive it links you to will contain process dumps, traces from our ETW trace provider (publicly documented [here](https://github.com/microsoft/terminal/blob/main/src/Terminal.wprp)), and a snapshot of the Console-related registry settings. You can either crack them open yourself--though I suspect you may not want to get deep into the weeds on our behalf--or send me the diagnostics in whatever way you find most appropriate. My e-mail's on my GitHub profile! :smile:

<details>
<summary>snapshot from one diagnostic archive</summary>

<img width="865" alt="image" src="https://user-images.githubusercontent.com/189190/177425899-a748def4-40cc-4761-aa11-0cd0da07c4ae.png">

The stuff we generally care about is in the "Trace" sections; however, if there's a crash the process dumps will come in handy.

</details>
I'm gonna cross reference this with #12176 - both are "TermControl tried to do a thing even though we were already going down".

The crash being where it is in the dumps we have so far is confusing. They all imply that the Terminal was already exiting (gracefully or not), and just so happened to take a trip to flavortown on its way down. That means the stack we can see from the crash doesn't actually have anything to do with what triggered the Terminal to exit in the first place 😕 
I've been trying to get you those logs but haven't managed to trigger the crash recently, sorry!

Fix patch:
diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp
index e053fd10720..3b6f1fe945b 100644
--- a/src/cascadia/TerminalControl/TermControl.cpp
+++ b/src/cascadia/TerminalControl/TermControl.cpp
@@ -707,7 +707,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
                                              margins.Top,
                                              margins.Right,
                                              margins.Bottom };
-                _automationPeer = winrt::make<implementation::TermControlAutomationPeer>(this, padding, interactivityAutoPeer);
+                _automationPeer = winrt::make<implementation::TermControlAutomationPeer>(get_strong(), padding, interactivityAutoPeer);
                 return _automationPeer;
             }
         }
diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp
index b0203d24208..1f670cd1f6d 100644
--- a/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp
+++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.cpp
@@ -67,10 +67,10 @@ static constexpr bool IsReadable(std::wstring_view text)
 
 namespace winrt::Microsoft::Terminal::Control::implementation
 {
-    TermControlAutomationPeer::TermControlAutomationPeer(TermControl* owner,
+    TermControlAutomationPeer::TermControlAutomationPeer(winrt::com_ptr<TermControl> owner,
                                                          const Core::Padding padding,
                                                          Control::InteractivityAutomationPeer impl) :
-        TermControlAutomationPeerT<TermControlAutomationPeer>(*owner), // pass owner to FrameworkElementAutomationPeer
+        TermControlAutomationPeerT<TermControlAutomationPeer>(*owner.get()), // pass owner to FrameworkElementAutomationPeer
         _termControl{ owner },
         _contentAutomationPeer{ impl }
     {
@@ -134,8 +134,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         dispatcher.RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [weakThis{ get_weak() }]() {
             if (auto strongThis{ weakThis.get() })
             {
-                // The event that is raised when the text selection is modified.
-                strongThis->RaiseAutomationEvent(AutomationEvents::TextPatternOnTextSelectionChanged);
+                if (auto control{ strongThis->_termControl.get() })
+                {
+                    // The event that is raised when the text selection is modified.
+                    strongThis->RaiseAutomationEvent(AutomationEvents::TextPatternOnTextSelectionChanged);
+                }
             }
         });
     }
@@ -157,8 +160,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         dispatcher.RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [weakThis{ get_weak() }]() {
             if (auto strongThis{ weakThis.get() })
             {
-                // The event that is raised when textual content is modified.
-                strongThis->RaiseAutomationEvent(AutomationEvents::TextPatternOnTextChanged);
+                if (auto control{ strongThis->_termControl.get() })
+                {
+                    // The event that is raised when textual content is modified.
+                    strongThis->RaiseAutomationEvent(AutomationEvents::TextPatternOnTextChanged);
+                }
             }
         });
     }
@@ -180,13 +186,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         dispatcher.RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [weakThis{ get_weak() }]() {
             if (auto strongThis{ weakThis.get() })
             {
-                // The event that is raised when the text was changed in an edit control.
-                // Do NOT fire a TextEditTextChanged. Generally, an app on the other side
-                //    will expect more information. Though you can dispatch that event
-                //    on its own, it may result in a nullptr exception on the other side
-                //    because no additional information was provided. Crashing the screen
-                //    reader.
-                strongThis->RaiseAutomationEvent(AutomationEvents::TextPatternOnTextSelectionChanged);
+                if (auto control{ strongThis->_termControl.get() })
+                {
+                    // The event that is raised when the text was changed in an edit control.
+                    // Do NOT fire a TextEditTextChanged. Generally, an app on the other side
+                    //    will expect more information. Though you can dispatch that event
+                    //    on its own, it may result in a nullptr exception on the other side
+                    //    because no additional information was provided. Crashing the screen
+                    //    reader.
+                    strongThis->RaiseAutomationEvent(AutomationEvents::TextPatternOnTextSelectionChanged);
+                }
             }
         });
     }
@@ -236,14 +245,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         dispatcher.RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [weakThis{ get_weak() }, sanitizedCopy{ hstring{ sanitized } }]() {
             if (auto strongThis{ weakThis.get() })
             {
-                try
+                if (auto control{ strongThis->_termControl.get() })
                 {
-                    strongThis->RaiseNotificationEvent(AutomationNotificationKind::ActionCompleted,
-                                                       AutomationNotificationProcessing::All,
-                                                       sanitizedCopy,
-                                                       L"TerminalTextOutput");
+                    try
+                    {
+                        strongThis->RaiseNotificationEvent(AutomationNotificationKind::ActionCompleted,
+                                                           AutomationNotificationProcessing::All,
+                                                           sanitizedCopy,
+                                                           L"TerminalTextOutput");
+                    }
+                    CATCH_LOG();
                 }
-                CATCH_LOG();
             }
         });
     }
@@ -284,17 +296,29 @@ namespace winrt::Microsoft::Terminal::Control::implementation
     hstring TermControlAutomationPeer::GetNameCore() const
     {
         // fallback to title if profile name is empty
-        auto profileName = _termControl->GetProfileName();
-        if (profileName.empty())
+        if (auto control{ _termControl.get() })
         {
-            return _termControl->Title();
+            const auto profileName = control->GetProfileName();
+            if (profileName.empty())
+            {
+                return control->Title();
+            }
+            else
+            {
+                return profileName;
+            }
         }
-        return profileName;
+
+        return L"";
     }
 
     hstring TermControlAutomationPeer::GetHelpTextCore() const
     {
-        return _termControl->Title();
+        if (const auto control{ _termControl.get() })
+        {
+            return control->Title();
+        }
+        return L"";
     }
 
     AutomationLiveSetting TermControlAutomationPeer::GetLiveSettingCore() const
diff --git a/src/cascadia/TerminalControl/TermControlAutomationPeer.h b/src/cascadia/TerminalControl/TermControlAutomationPeer.h
index 758864bc38f..c9e00340f9c 100644
--- a/src/cascadia/TerminalControl/TermControlAutomationPeer.h
+++ b/src/cascadia/TerminalControl/TermControlAutomationPeer.h
@@ -42,7 +42,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
         ::Microsoft::Console::Types::IUiaEventDispatcher
     {
     public:
-        TermControlAutomationPeer(Microsoft::Terminal::Control::implementation::TermControl* owner,
+        TermControlAutomationPeer(winrt::com_ptr<Microsoft::Terminal::Control::implementation::TermControl> owner,
                                   const Core::Padding padding,
                                   Control::InteractivityAutomationPeer implementation);
 
@@ -78,7 +78,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
 #pragma endregion
 
     private:
-        winrt::Microsoft::Terminal::Control::implementation::TermControl* _termControl;
+        winrt::weak_ref<Microsoft::Terminal::Control::implementation::TermControl> _termControl;
         Control::InteractivityAutomationPeer _contentAutomationPeer;
         std::deque<wchar_t> _keyEvents;
     };


Test patch: