{"id":108991,"date":"2023-11-10T07:00:00","date_gmt":"2023-11-10T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=108991"},"modified":"2023-11-10T08:42:59","modified_gmt":"2023-11-10T16:42:59","slug":"20231110-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20231110-00\/?p=108991","title":{"rendered":"The case of the invalid argument exception from a method that takes no arguments"},"content":{"rendered":"<p>A customer was getting crashes with the following stack:<\/p>\n<pre><span style=\"border: solid 1px currentcolor; border-bottom: none;\">ucrtbase!abort+0x4e                                            <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">ucrtbase!terminate+0x29                                        <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">ucrtbase!FindHandler&lt;__FrameHandler4&gt;+0x4f4                    <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">ucrtbase!__InternalCxxFrameHandler&lt;__FrameHandler4&gt;+0x276      <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">ucrtbase!__InternalCxxFrameHandlerWrapper&lt;__FrameHandler4&gt;+0x3e<\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">ucrtbase!__CxxFrameHandler4+0xa9                               <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">contoso!__GSHandlerCheck_EH4+0x64                              <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">ntdll!RtlpExecuteHandlerForException+0xf                       <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">ntdll!RtlDispatchException+0x26c                               <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">ntdll!RtlRaiseException+0x195                                  <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">KERNELBASE!RaiseException+0x6c                                 <\/span>\r\n<span style=\"border: solid 1px currentcolor; border-top: none;\">ucrtbase!_CxxThrowException+0x9a                               <\/span>\r\n<span style=\"border: solid 1px currentcolor; border-bottom: none;\">contoso!winrt::throw_hresult+0xd3                              <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">contoso!winrt::check_hresult+0xcf                              <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">contoso!winrt::impl::consume_Microsoft_UI_Xaml_Controls_       <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">        Primitives_IFlyoutBase&lt;winrt::Microsoft::UI::Xaml::    <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">        Controls::Primitives::IFlyoutBase&gt;::Hide+0xe9          <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">contoso!MyPanel::CancelCurrentFlyout+0x25e                     <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">contoso!MyPanel::IsReadyForNewContextMenu+0x4b                 <\/span>\r\n<span style=\"border: solid 1px currentcolor; border-top: none;\">contoso!MyPanel::DoContextMenu+0x1ac                           <\/span>\r\ncontoso!MyPanel::WndProc+0x7f2\r\nuser32!UserCallWinProcCheckWow+0x2ba\r\nuser32!DispatchMessageWorker+0x2b0\r\ncontoso!CMainWindow::Run+0xde\r\ncontoso!wWinMain+0xd69\r\ncontoso!invoke_main+0x21\r\ncontoso!__scrt_common_main_seh+0x110\r\nkernel32!BaseThreadInitThunk+0x1d\r\nntdll!RtlUserThreadStart+0x28\r\n<\/pre>\n<p>The block of stack frames at the top is the C++ runtime infrastructure throwing an exception and looking for a handler. Eventually, no handler is found, and we end up terminating due to an unhandled exception.<\/p>\n<p>The next block of stack frames is the code that threw the unhandled exception. From the <code>winrt::<wbr \/>throw_<wbr \/>hresult<\/code>, we know that this code is written in C++\/WinRT, and the <code>check_<wbr \/>hresult<\/code> tells us that we are converting a failure <code>HRESULT<\/code> into an exception. The next frame tells us that this failure <code>HRESULT<\/code> came from a call to <code>IFlyoutBase::<wbr \/>Hide<\/code>.<\/p>\n<p>The name of that frame breaks down like this:<\/p>\n<ul>\n<li><span style=\"border: solid 1px gray;\"><code>winrt::impl::<\/code><\/span> C++\/WinRT internal method<\/li>\n<li><span style=\"border: solid 1px gray;\"><code>consume_<\/code><\/span> Wrapper for client code to call into Windows Runtime component (consuming an interface)<\/li>\n<li><span style=\"border: solid 1px gray;\"><code>Microsoft_<wbr \/>UI_<wbr \/>Xaml_<wbr \/>Controls_<wbr \/>Primitives_<wbr \/>IFlyoutBase<\/code><\/span> The interface we called is <code>Microsoft::<wbr \/>UI::<wbr \/>Xaml::<wbr \/>Controls::<wbr \/>Primitives::<wbr \/>IFlyoutBase<\/code>.<\/li>\n<li><span style=\"border: solid 1px gray;\"><code>&lt;winrt::<wbr \/>Microsoft::<wbr \/>UI::<wbr \/>Xaml::<wbr \/>Controls::<wbr \/>Primitives::<wbr \/>IFlyoutBase&gt;<\/code><\/span> The interface is implemented by an object whose type is <code>winrt::<wbr \/>Microsoft::<wbr \/>UI::<wbr \/>Xaml::<wbr \/>Controls::<wbr \/>Primitives::<wbr \/>IFlyoutBase<\/code>. In this case, we are invoking it directly on the interface, so the interface simply implements itself, and this part looks silly.<\/li>\n<li><span style=\"border: solid 1px gray;\"><code>Hide<\/code><\/span> is the method being invoked.<\/li>\n<\/ul>\n<p>Okay, so our call on the <code>IFlyoutBase::<wbr \/>Hide<\/code> method failed with an &#8220;invalid parameter&#8221; exception. How can a method with no parameters have an invalid parameter?<\/p>\n<p>Here&#8217;s the call in the Contoso app:<\/p>\n<pre>void MyPanel::CancelCurrentFlyout()\r\n{\r\n    \/\/ Cancel any pending action.\r\n    if (!m_actionPending)\r\n    {\r\n        InvokeCancel();\r\n    }\r\n\r\n    \/\/ Hide any open flyout.\r\n    if (m_menu &amp;&amp;\r\n        ((m_flyoutState == FlyoutState::Opened) ||\r\n         (m_flyoutState == FlyoutState::Opening)))\r\n    {\r\n        m_menu.Hide(); \/* we failed here *\/\r\n    }\r\n    TransitionFlyoutState(FlyoutState::Closed);\r\n    ResetDataModelAndTasks();\r\n}\r\n<\/pre>\n<p>Let&#8217;s look more closely at the exception that was thrown. We know that it was an <code>hresult_error<\/code>, so we can just dump it straight away.<\/p>\n<pre>0:000&gt; .frame b\r\n0b 00000000`0107c670 00007ffa`84e2d24b     ucrtbase!_CxxThrowException+0x9a\r\n0:000&gt; dv\r\npExceptionObject = 0x00000000`0107c700\r\n...\r\n0:000&gt; dps 0x00000000`0107c700 L3\r\n00000000`0107c700  00000000`00000000\r\n00000000`0107c708  80070057`aabbccdd \/\/ There's our ERROR_INVALID_PARAMETER\r\n00000000`0107c710  00000000`2c81b7a8 \/\/ Here's the IErrorInfo\r\n<\/pre>\n<p>Although we don&#8217;t know the internal layout of the <code>IErrorInfo<\/code>, we can dump it to see if anything jumps out at us.<\/p>\n<pre>0:000&gt; dc 0x00000000`2c81b7a8\r\n00000000`2c81b7a8  6b70cca8 00007ffa 6b70cb30 00007ffa  ..pk....0.pk....\r\n00000000`2c81b7b8  6b70cad0 00007ffa 6b70ccd0 00007ffa  ..pk......pk....\r\n00000000`2c81b7c8  6b70cb78 00007ffa 6b70cc50 00007ffa  x.pk....P.pk....\r\n00000000`2c81b7d8  6b70cc08 00007ffa 6b70caf8 00007ffa  ..pk......pk....\r\n00000000`2c81b7e8  00000000 00000001 28a6a1a0 00000000  ...........(....\r\n00000000`2c81b7f8  290bc760 00000000 00000000 00000000  `..)............\r\n00000000`2c81b808  80070057 00000000 00000000 00000000  W...............\r\n00000000`2c81b818  00000000 00000000 00010002 00000039  ............9...\r\n00000000`2c81b828  283dbe90 00000000 00000008 00000000  ..=(............\r\n00000000`2c81b838  00000038 <span style=\"border: solid 1px gray;\">53453032<\/span> 80070057 000056dd  8...<span style=\"border: solid 1px gray;\">20ES<\/span>W....V..\r\n00000000`2c81b848  6b4d1bf8 00007ffa 00000008 00000039  ..Mk........9...\r\n00000000`2c81b858  283dbe90 00000000 00000000 00000000  ..=(............\r\n00000000`2c81b868  00000000 00000000 00000000 00000000  ................\r\n00000000`2c81b878  43832534 35316d47 108a28cb 09f94d9d  4%.CGm15.(...M..\r\n00000000`2c81b888  00000000 00000000 2c81ab08 00000000  ...........,....\r\n00000000`2c81b898  00000000 00000000 00000002 00000000  ................\r\n<\/pre>\n<p>After a lot of introductory stuff, we recognize the failure <code>HRESULT<\/code> of <code>0x80070057<\/code>, but more interestingly, the signature value <code>53453032<\/code> which decodes to the ASCII characters <code>SE02<\/code>, the signature for <code>STOWED_<wbr \/>EXCEPTION_<wbr \/>INFORMATION_<wbr \/>V2<\/code>. There&#8217;s a good chance this is a <code>STOWED_<wbr \/>EXCEPTION_<wbr \/>INFORMATION_<wbr \/>V2<\/code> structure. Let&#8217;s ask the <code>!pde.dse<\/code> extension to dump it.<\/p>\n<p>The <code>!pde.dse<\/code> extension optionally takes a pointer to an array of stowed exception pointers. To dump a single stowed exception, we&#8217;ll have to create one of these arrays and ask <code>!pde.dse<\/code> to dump it.<\/p>\n<pre>0:000&gt; eq @rsp-8 0x00000000`2c81b7a8\r\n0:000&gt; !pde.dse @rsp-8\r\nStowed Exception Array @ 0x00000000035477e8\r\n\r\nStowed Exception #1 @ 0x000000002c81b838\r\n        0x80070057: E_INVALIDARG - One or more arguments are not valid\r\n\r\nStack    : 0x283dbe90\r\n\r\ncombase!RoOriginateErrorW+0x131\r\nMicrosoft_UI_Xaml!DirectUI::ErrorHelper::OriginateError+0x172\r\nMicrosoft_UI_Xaml!DirectUI::ErrorHelper::OriginateError+0x28\r\nMicrosoft_UI_Xaml!DirectUI::VisualTreeHelper::GetOpenPopupsForXamlRoot+0x63\r\ncontoso!&lt;lambda_\u27e6\u2026\u27e7&gt;::operator()+0x3e\r\ncontoso!winrt::\u27e6\u2026\u27e7::VisualTreeHelper::GetOpenPopupsForXamlRoot+0x43\r\ncontoso!&lt;lambda_\u27e6\u2026\u27e7&gt;::operator()+0x7f\r\ncontoso!winrt::impl::delegate&lt;winrt::\u27e6\u2026\u27e7::TypedEventHandler&lt;\r\n    winrt::\u27e6\u2026\u27e7::FlyoutBase,\r\n    winrt::\u27e6\u2026\u27e7::FlyoutBaseClosingEventArgs&gt;,\r\n    &lt;lambda_\u27e6\u2026\u27e7&gt; &gt;::Invoke+0x22\r\nMicrosoft_UI_Xaml!DirectUI::CEventSourceBase&lt;\u27e6\u2026\u27e7&gt;::Raise+0xa0\r\nMicrosoft_UI_Xaml!DirectUI::FlyoutBase::OnClosing+0x7c\r\nMicrosoft_UI_Xaml!DirectUI::FlyoutBase::HideImpl+0x3b\r\nMicrosoft_UI_Xaml!DirectUI::FlyoutBaseGenerated::Hide+0x52\r\n<span style=\"border: solid 1px currentcolor; border-bottom: none;\">contoso!MyPanel::CancelCurrentFlyout+0x25e    <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">contoso!MyPanel::IsReadyForNewContextMenu+0x4b<\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">contoso!MyPanel::DoContextMenu+0x1ac          <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">contoso!MyPanel::WndProc+0x7f2                <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">user32!UserCallWinProcCheckWow+0x2ba          <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">user32!DispatchMessageWorker+0x2b0            <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">contoso!CMainWindow::Run+0xde                 <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">contoso!wWinMain+0xd69                        <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">contoso!invoke_main+0x21                      <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">contoso!__scrt_common_main_seh+0x110          <\/span>\r\n<span style=\"border: 1px currentcolor; border-style: none solid;\">kernel32!BaseThreadInitThunk+0x1d             <\/span>\r\n<span style=\"border: solid 1px currentcolor; border-top: none;\">ntdll!RtlUserThreadStart+0x28                 <\/span>\r\n<\/pre>\n<p>Notice that the deeper part of the stack matches our current stack. This is expected because the stowed exception captures the error origination slightly deeper in the stack, so the stuff outside <code>MyPanel::<wbr \/>CancelCurrentFlyout<\/code> will still be the same.<\/p>\n<p>Note also that the stack trace from the stowed exception doesn&#8217;t include inlined functions, because the stack capturing code doesn&#8217;t have access to symbols. It just walks the stack frames.<\/p>\n<p>So let&#8217;s look at the new information we gained from the stowed exception:<\/p>\n<pre>combase!RoOriginateErrorW+0x131\r\nMicrosoft_UI_Xaml!DirectUI::ErrorHelper::OriginateError+0x172\r\nMicrosoft_UI_Xaml!DirectUI::ErrorHelper::OriginateError+0x28\r\nMicrosoft_UI_Xaml!DirectUI::VisualTreeHelper::GetOpenPopupsForXamlRoot+0x63\r\ncontoso!`winrt::\u27e6\u2026\u27e7::VisualTreeHelper::GetOpenPopupsForXamlRoot`::\r\n    &lt;lambda_1&gt;::operator()+0x3e\r\ncontoso!winrt::\u27e6\u2026\u27e7::VisualTreeHelper::GetOpenPopupsForXamlRoot+0x43\r\ncontoso!`winrt::\u27e6\u2026\u27e7::MenuFlyoutControl::CreateMenu`::&lt;lambda_1&gt;::operator()+0x7f\r\ncontoso!winrt::impl::delegate&lt;winrt::\u27e6\u2026\u27e7::TypedEventHandler&lt;\r\n    winrt::\u27e6\u2026\u27e7::FlyoutBase,\r\n    winrt::\u27e6\u2026\u27e7::FlyoutBaseClosingEventArgs&gt;,\r\n    `winrt::\u27e6\u2026\u27e7::MenuFlyoutControl::CreateMenu`::&lt;lambda_1&gt; &gt;::Invoke+0x22\r\nMicrosoft_UI_Xaml!DirectUI::CEventSourceBase&lt;\u27e6\u2026\u27e7&gt;::Raise+0xa0\r\nMicrosoft_UI_Xaml!DirectUI::FlyoutBase::OnClosing+0x7c\r\nMicrosoft_UI_Xaml!DirectUI::FlyoutBase::HideImpl+0x3b\r\nMicrosoft_UI_Xaml!DirectUI::FlyoutBaseGenerated::Hide+0x52\r\n<\/pre>\n<p>Reading from the bottom: Our code called the <code>Hide<\/code> method, which went into <code>HideImpl<\/code>, which called <code>OnClosing<\/code>. Based on the name of the method and the fact that it calls <code>CEventSourceBase::<wbr \/>Raise<\/code>, it&#8217;s apparent that this code is raising the <code>Closing<\/code> event. The delegate registered for this event is a lambda in <code>Menu\u00adFlyout\u00adControl::<wbr \/>Create\u00adMenu<\/code>, and it called <code>Get\u00adOpen\u00adPopups\u00adFor\u00adXaml\u00adRoot<\/code>, which decided to return an &#8220;invalid argument&#8221; error.<\/p>\n<p>Let&#8217;s see why.<\/p>\n<pre>0:000&gt; u 7ffa266ad663-63 7ffa266ad663\r\nDirectUI::VisualTreeHelper::GetOpenPopupsForXamlRoot:\r\n00007ffa`266ad600 mov     qword ptr [rsp+20h],rbx\r\n00007ffa`266ad605 push    rbp\r\n00007ffa`266ad606 push    rsi\r\n00007ffa`266ad607 push    rdi\r\n00007ffa`266ad608 sub     rsp,30h\r\n00007ffa`266ad60c mov     rax,qword ptr [_security_cookie (00007ffa`26bef010)]\r\n00007ffa`266ad613 xor     rax,rsp\r\n00007ffa`266ad616 mov     qword ptr [rsp+28h],rax\r\n00007ffa`266ad61b and     qword ptr [rsp+20h],0\r\n00007ffa`266ad621 mov     rsi,r8\r\n00007ffa`266ad624 mov     rdi,rdx\r\n00007ffa`266ad627 mov     rbp,rcx\r\n00007ffa`266ad62a test    r8,r8\r\n00007ffa`266ad62d jne     00007ffa`266ad64a\r\n00007ffa`266ad62f lea     r8,[`string' (00007ffa`26904470)]\r\n00007ffa`266ad636 mov     ecx,80070057h\r\n00007ffa`266ad63b lea     edx,[rsi+0Bh]\r\n00007ffa`266ad63e call    DirectUI::ErrorHelper::OriginateError\r\n00007ffa`266ad643 mov     ebx,eax\r\n00007ffa`266ad645 jmp     00007ffa`266ad6f3\r\n00007ffa`266ad64a test    rdi,rdi\r\n00007ffa`266ad64d jne     00007ffa`266ad675\r\n00007ffa`266ad64f lea     r8,[`string' (00007ffa`26b663b0)]\r\n00007ffa`266ad656 mov     ecx,80070057h\r\n00007ffa`266ad65b lea     edx,[rdi+8]\r\n00007ffa`266ad65e call    DirectUI::ErrorHelper::OriginateError\r\n00007ffa`266ad663 mov     ebx,eax\r\n<\/pre>\n<p>The code that leads up to the error breaks up into three parts:<\/p>\n<pre>00007ffa`266ad600 mov     qword ptr [rsp+20h],rbx\r\n00007ffa`266ad605 push    rbp\r\n00007ffa`266ad606 push    rsi\r\n00007ffa`266ad607 push    rdi\r\n00007ffa`266ad608 sub     rsp,30h\r\n00007ffa`266ad60c mov     rax,qword ptr [_security_cookie (00007ffa`26bef010)]\r\n00007ffa`266ad613 xor     rax,rsp\r\n00007ffa`266ad616 mov     qword ptr [rsp+28h],rax\r\n00007ffa`266ad61b and     qword ptr [rsp+20h],0\r\n00007ffa`266ad621 mov     rsi,r8\r\n00007ffa`266ad624 mov     rdi,rdx\r\n00007ffa`266ad627 mov     rbp,rcx\r\n<\/pre>\n<p>This first section is function prologue stuff and initializing local variables. The inbound parameters are stored in <code>rbp<\/code>, <code>rdi<\/code>, and <code>rsi<\/code>. Therefore we have this so far:<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<td><code>rbp<\/code> = <code>rcx<\/code><\/td>\n<td><code>this<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>rdi<\/code> = <code>rdx<\/code><\/td>\n<td><code>xamlRoot<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>rsi<\/code> = <code>r8<\/code><\/td>\n<td><code>result<\/code> (output)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Next up is this section:<\/p>\n<pre>00007ffa`266ad62a test    r8,r8\r\n00007ffa`266ad62d jne     00007ffa`266ad64a\r\n00007ffa`266ad62f lea     r8,[`string' (00007ffa`26904470)]\r\n00007ffa`266ad636 mov     ecx,80070057h\r\n00007ffa`266ad63b lea     edx,[rsi+0Bh]\r\n00007ffa`266ad63e call    DirectUI::ErrorHelper::OriginateError\r\n00007ffa`266ad643 mov     ebx,eax\r\n00007ffa`266ad645 jmp     00007ffa`266ad6f3\r\n<\/pre>\n<p>If <code>r8<\/code> is zero, then we return <code>0x80070057<\/code> = <code>E_INVALIDARG<\/code> with a custom message:<\/p>\n<pre>0:000&gt; du 00007ffa`26904470\r\n00007ffa`26904470  \"returnValue\"\r\n<\/pre>\n<p>Okay, so first we verify that the result parameter (which I guess this function calls <code>returnValue<\/code>) is not null; if it is, we fail with <code>E_INVALIDARG<\/code>.<\/p>\n<p>And then we have this:<\/p>\n<pre>00007ffa`266ad64a test    rdi,rdi\r\n00007ffa`266ad64d jne     00007ffa`266ad675\r\n00007ffa`266ad64f lea     r8,[`string' (00007ffa`26b663b0)]\r\n00007ffa`266ad656 mov     ecx,80070057h\r\n00007ffa`266ad65b lea     edx,[rdi+8]\r\n00007ffa`266ad65e call    DirectUI::ErrorHelper::OriginateError\r\n00007ffa`266ad663 mov     ebx,eax\r\n<\/pre>\n<p>This returns <code>E_INVALIDARG<\/code> with a custom message if the <code>rdi<\/code> register is zero, which our table above tells us corresponds to the <code>xamlRoot<\/code> parameter. The error message confirms this:<\/p>\n<pre>0:000&gt; du 00007ffa`26b663b0\r\n00007ffa`26b663b0  \"xamlRoot\"\r\n<\/pre>\n<p>So we got an &#8220;invalid argument&#8221; error because <code>xamlRoot<\/code> was null. Working backward, we can look at the <code>Closing<\/code> event handler:<\/p>\n<pre style=\"font-size: 80%;\">void MenuFlyoutControl::CreateMenu(const winrt::IIterable&amp; menuItems)\r\n{\r\n    \u27e6\u2026\u27e7\r\n\r\n    m_closingRevoker = flyout.Closing(winrt::auto_revoke,\r\n        [](auto&amp;&amp; sender, auto&amp;&amp;) {\r\n        if (auto flyout = sender.try_as&lt;xaml::CommandBarFlyout&gt;()) {\r\n            auto popups = xaml::VisualTreeHelper::GetOpenPopupsForXamlRoot(flyout.XamlRoot());\r\n            \u27e6\u2026\u27e7\r\n        }\r\n    });\r\n\r\n    \u27e6\u2026\u27e7\r\n}\r\n<\/pre>\n<p>We infer therefore that <code>flyout.XamlRoot()<\/code> was null. And that&#8217;s what generates the &#8220;invalid parameter&#8221; exception: Null is not a valid parameter for <code>Get\u00adOpen\u00adPopups\u00adFor\u00adXaml\u00adRoot<\/code>.<\/p>\n<p>This invalid parameter error projects as an exception, which causes the <code>Closing<\/code> event handler to fail with an exception, which is then transformed back into <code>E_INVALIDARG<\/code> at the ABI. This error presumably propagates out of the <code>Raise<\/code> method back into <code>OnClosing<\/code> and then to <code>HideImpl<\/code>, and then back to the caller, which causes <code>m_menu.Hide()<\/code> to fail with an invalid argument exception, which is where our crash dump was generated.<\/p>\n<p>The customer fixed the problem by revising the <code>Closing<\/code> event handler to skip the call to <code>Get\u00adOpen\u00adPopups\u00adFor\u00adXaml\u00adRoot<\/code> if <code>flyout.XamlRoot()<\/code> is null, and just assume that there are no popups.<\/p>\n<p><b>Bonus viewing<\/b>: <a href=\"https:\/\/learn.microsoft.com\/shows\/inside\/c000027b\"> Stowed Exception C000027B<\/a>: A video with the creator of the <code>!pde.dse<\/code> debugger extension. The array of pointers shows up at time code 5:24.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Where did the invalid argument come from?<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-108991","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Where did the invalid argument come from?<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/108991","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=108991"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/108991\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=108991"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=108991"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=108991"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}