{"id":109352,"date":"2024-02-02T07:00:00","date_gmt":"2024-02-02T15:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=109352"},"modified":"2024-02-02T11:13:11","modified_gmt":"2024-02-02T19:13:11","slug":"20240202-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20240202-00\/?p=109352","title":{"rendered":"The case of the invalid parameter error from <CODE>Measure&shy;Override<\/CODE>"},"content":{"rendered":"<p>A customer had a crash with the following stack:<\/p>\n<pre>KERNELBASE!RaiseFailFastException+0x152\r\ncombase!RoFailFastWithErrorContextInternal2+0x4d9\r\nWindows_UI_Xaml!DirectUI::ErrorHelper::ProcessUnhandledError+0xf4\r\nWindows_UI_Xaml!DirectUI::ErrorHelper::ReportUnhandledError+0xf1\r\nWindows_UI_Xaml!AgCoreCallbacks::ReportUnhandledError+0x7\r\nWindows_UI_Xaml!CFxCallbacks::Error_ReportUnhandledError+0x7\r\nWindows_UI_Xaml!CCoreServices::ReportUnhandledError+0x7\r\nWindows_UI_Xaml!CXcpDispatcher::Tick+0x2e6c59\r\nWindows_UI_Xaml!CXcpDispatcher::OnReentrancyProtectedWindowMessage+0x40\r\nWindows_UI_Xaml!CXcpDispatcher::ProcessMessage+0xec\r\nWindows_UI_Xaml!CXcpDispatcher::WindowProc+0x95\r\nWindows_UI_Xaml!CDeferredInvoke::DispatchQueuedMessage+0x9a\r\nWindows_UI_Xaml!CXcpDispatcher::MessageTimerCallback+0x13\r\nWindows_UI_Xaml!CXcpDispatcher::MessageTimerCallbackStatic+0x1c\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::TimeoutHandler::ImportAdapter$::\r\n    __l2::&lt;lambda_654db17c35df07198786f0867aa10de6&gt;::operator()+0x1f\r\nCoreMessaging!CFlat::SehSafe::Execute&lt;\r\n    &lt;lambda_654db17c35df07198786f0867aa10de6&gt; &gt;+0x2c\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::TimeoutHandler::ImportAdapter$+0xb1\r\nCoreMessaging!CFlat::DelegateImpl&lt;Microsoft::CoreUI::Dispatch::TimeoutHandler,0,\r\n    void __cdecl(void),long __cdecl(void *),0&gt;::Invoke+0x22\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::Timeout::CallHandler+0x3c\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::TimeoutManager::Callback_OnDispatch+0x21e\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::Dispatcher::Callback_DispatchNextItem+0x1b3\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::Dispatcher::Callback_DispatchLoop+0x240\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::EventLoop::Callback_RunCoreLoop+0x36f\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::DrainCoreMessagingQueue+0x178\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::OnUserDispatch+0x1f3\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::OnUserDispatchRaw+0x6d\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::DoWork+0x206\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::WindowProc+0x14c\r\nuser32!UserCallWinProcCheckWow+0x2d1\r\nuser32!DispatchClientMessage+0x9c\r\nuser32!__fnDWORD+0x3d\r\nntdll!KiUserCallbackDispatcherContinue\r\nwin32u!ZwUserPeekMessage+0x14\r\nuser32!_PeekMessage+0x3f\r\nuser32!PeekMessageW+0x9c\r\ncontoso!MainWindow::_MessageLoop+0x86\r\ncontoso!MainWindow::MainThreadProc+0x60\r\nkernel32!BaseThreadInitThunk+0x1d\r\nntdll!RtlUserThreadStart+0x28\r\n<\/pre>\n<p>This stack breaks down into three sections.<\/p>\n<table style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<td style=\"position: relative; padding: 0;\">\n<pre style=\"padding: 0; margin: 0;\">KERNELBASE!RaiseFailFastException+0x152\r\ncombase!RoFailFastWithErrorContextInternal2+0x4d9\r\nWindows_UI_Xaml!DirectUI::ErrorHelper::ProcessUnhandledError+0xf4\r\nWindows_UI_Xaml!blah blah blah\r\nWindows_UI_Xaml!CXcpDispatcher::WindowProc+0x95\r\nWindows_UI_Xaml!CDeferredInvoke::DispatchQueuedMessage+0x9a\r\nWindows_UI_Xaml!CXcpDispatcher::MessageTimerCallback+0x13\r\nWindows_UI_Xaml!CXcpDispatcher::MessageTimerCallbackStatic+0x1c\r\n<\/pre>\n<div style=\"position: absolute; top: 0; right: 0;\">XAML<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"position: relative; padding: 0;\">\n<pre style=\"padding: 0; margin: 0;\">CoreMessaging!blah blah blah\r\nuser32!blah blah blah\r\n<\/pre>\n<div style=\"position: absolute; top: 0; right: 0;\">Message dispatch infrastructure<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"position: relative; padding: 0;\">\n<pre style=\"padding: 0; margin: 0;\">contoso!MainWindow::MessageLoop+0x86\r\ncontoso!MainWindow::MainThreadProc+0x60\r\nkernel32!BaseThreadInitThunk+0x1d\r\nntdll!RtlUserThreadStart+0x28\r\n<\/pre>\n<div style=\"position: absolute; top: 0; right: 0;\">Application message loop<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>At the bottom of the stack is the application&#8217;s message loop. The message loop calls into the message dispatch infrastructure, which triggered a call into XAML. XAML processed the message, which told it to <code>Report\u00adUnhandled\u00adError<\/code>, so it reported the error to the application before failing fast.<\/p>\n<p>There isn&#8217;t really anything to see from this stack. XAML is reporting an error that occurred some time ago. But the stack for that error is still recorded: You can use the <code>!pde.dse<\/code> extension to <u>d<\/u>ump the <u>s<\/u>towed <u>e<\/u>xceptions.<\/p>\n<p>The convention in the Windows Runtime is that when code is about to return a COM error (which is the ABI representation of a language exception), it first calls <code>Ro\u00adOriginate\u00adError<\/code> to report the error to the COM infrastructure, which records the error and a stack trace and attaches it to the thread. We saw this earlier when we discussed <a title=\"What's the difference between throwing a winrt::hresult_error and using winrt::throw_hresult?\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20210716-00\/?p=105448\"> the difference between throwing a <code>winrt::<wbr \/>hresult_<wbr \/>error<\/code> and using <code>winrt::<wbr \/>throw_<wbr \/>hresult<\/code><\/a>.<\/p>\n<p>When you ask to dump the stowed exceptions, this digs back into COM&#8217;s bookkeeping and pulls out all of the exceptions that are being tracked by the current thread, most recent first.<\/p>\n<p>&nbsp;<\/p>\n<p>In this case, we get eight such exceptions. The most recent one is this horrible stack, which we break down into pieces:<\/p>\n<table style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<td style=\"position: relative; padding: 0;\">\n<pre style=\"padding: 0; margin: 0;\">contoso!winrt::hresult_error::hresult_error+0x143\r\ncontoso!winrt::hresult_invalid_argument::hresult_invalid_argument+0x14\r\ncontoso!winrt::throw_hresult+0xb9\r\ncontoso!winrt::impl::consume_Windows_UI_Xaml_IFrameworkElementOverrides\r\n    &lt;winrt::Windows::UI::Xaml::IFrameworkElementOverrides&gt;::MeasureOverride+0x3b\r\ncontoso!winrt::impl::produce&lt;winrt::Contoso::implementation::ContosoFrame,\r\n    winrt::Windows::UI::Xaml::IFrameworkElementOverrides&gt;::MeasureOverride+0xa9\r\n<\/pre>\n<div style=\"position: absolute; top: 0; right: 0;\">App rethrows error<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"position: relative; padding: 0;\">\n<pre style=\"padding: 0; margin: 0;\">Windows_UI_Xaml!DirectUI::FrameworkElementGenerated::MeasureOverrideProtected+0xc8\r\nWindows_UI_Xaml!DirectUI::FrameworkElement::MeasureOverrideFromCore+0xf5\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x49a\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CGrid::MeasureOverride+0x11a\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x220\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CCanvas::MeasureOverride+0xa0\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x220\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CXamlIslandRoot::MeasureOverride+0x71\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x220\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CXamlIslandRootCollection::MeasureOverride+0xb6\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x220\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CRootVisual::MeasureOverride+0x64\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x220\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CLayoutManager::UpdateLayout+0x15a\r\nWindows_UI_Xaml!CCoreServices::NWDrawTree+0x246\r\nWindows_UI_Xaml!CCoreServices::NWDrawMainTree+0xc2\r\nWindows_UI_Xaml!CWindowRenderTarget::Draw+0x71\r\nWindows_UI_Xaml!CXcpBrowserHost::OnTick+0xbc\r\nWindows_UI_Xaml!CXcpDispatcher::Tick+0xa1\r\nWindows_UI_Xaml!CXcpDispatcher::OnReentrancyProtectedWindowMessage+0x40\r\nWindows_UI_Xaml!CXcpDispatcher::ProcessMessage+0xea\r\nWindows_UI_Xaml!CXcpDispatcher::WindowProc+0x95\r\nWindows_UI_Xaml!CDeferredInvoke::DispatchQueuedMessage+0x9a\r\nWindows_UI_Xaml!CXcpDispatcher::MessageTimerCallbackStatic+0x1c\r\n<\/pre>\n<div style=\"position: absolute; top: 3em; right: 0;\">XAML layout<br \/>\n(recursive algorithm)<\/div>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"position: relative; padding: 0;\">\n<pre style=\"padding: 0; margin: 0;\">CoreMessaging!CFlat::SehSafe::Execute&lt;\r\n    &lt;lambda_654db17c35df07198786f0867aa10de6&gt; &gt;+0x2c\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::TimeoutHandler::ImportAdapter$+0xb1\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::TimeoutManager::Callback_OnDispatch+0x21e\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::EventLoop::Callback_RunCoreLoop+0x36f\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::OnUserDispatch+0x1f3\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::DoWork+0x206\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::WindowProc+0x17f\r\nuser32!UserCallWinProcCheckWow+0x4ef\r\nuser32!DispatchClientMessage+0x9c\r\nuser32!__fnDWORD+0x3a\r\nntdll!KiUserCallbackDispatcherContinue+0x0\r\nwin32u!ZwUserPeekMessage+0x14\r\nuser32!_PeekMessage+0xb6\r\nuser32!PeekMessageW+0x146\r\ncontoso!MainWindow::MessageLoop+0x86\r\ncontoso!MainWindow::MainThreadProc+0x60\r\nkernel32!BaseThreadInitThunk+0x14\r\nntdll!RtlUserThreadStart+0x28\r\n<\/pre>\n<div style=\"position: absolute; top: 0; right: 0;\">Message dispatch<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Reading from the bottom up lets us see what happened, in chronological order.<\/p>\n<p>Our message pump dispatched a message that caused XAML to perform a <code>Draw()<\/code> operation. This triggers a <code>NWDrawTree()<\/code>, which in turn forces a recalculation of layout: <code>Update\u00adLayout()<\/code>. This layout happens by measuring a bunch of stuff, which is done recursively down the tree. Eventually, we get to the <code>ContosoFrame<\/code>&#8216;s custom <code>Measure\u00adOverride<\/code> method, and that&#8217;s where the exception occurred: On a call to <code>IFramework\u00adElement\u00adOverrides::<wbr \/>Measure\u00adOverride<\/code>:<\/p>\n<pre>winrt::Size ContosoFrame::MeasureOverride(winrt::Size availableSize)\r\n{\r\n    m_availableWidth = availableSize.Width;\r\n    UpdateOverflowItems();\r\n\r\n    \/\/ Invalid parameter on the next line.\r\n    auto result = base_type::MeasureOverride(availableSize);\r\n    EnableAnimations();\r\n    return result;\r\n}\r\n<\/pre>\n<p>Presumably, the <code>availableSize<\/code> was a valid parameter at the time XAML called into <code>Measure\u00adOverride<\/code>, so we must have done something in <code>Update\u00adOverflow\u00adItems()<\/code> that caused the parameter to become invalid. But the customer couldn&#8217;t find anything in <code>Update\u00adOverflow\u00adItems()<\/code> that could cause layout to go bad in such a way that <code>availableSize<\/code> changed from a valid parameter to an invalid one.<\/p>\n<p>Let&#8217;s go back and look at the failure again.<\/p>\n<p>The call to the base class&#8217;s <code>Measure\u00adOverride<\/code> resulted in <code>E_INVALID\u00adARG<\/code>, but there are other stowed exceptions, too.<\/p>\n<pre>Stowed Exception #2 @ 0x000000000a3c9b98\r\n0x80070057 (FACILITY_WIN32 - Win32 Undecorated Error Codes):\r\n    E_INVALIDARG - One or more arguments are not valid\r\n\r\nMicrosoft_UI_Xaml!winrt::hresult_error::hresult_error+0x120\r\nMicrosoft_UI_Xaml!winrt::hresult_invalid_argument::hresult_invalid_argument+0x14\r\nMicrosoft_UI_Xaml!winrt::throw_hresult+0xcd\r\nMicrosoft_UI_Xaml!ItemsRepeater::MeasureOverride+0x9aa\r\nMicrosoft_UI_Xaml!winrt::impl::produce&lt;ItemsRepeater,\r\n    winrt::Windows::UI::Xaml::IFrameworkElementOverrides&gt;::MeasureOverride+0x5b\r\nWindows_UI_Xaml!DirectUI::FrameworkElementGenerated::MeasureOverrideProtected+0xc8\r\nWindows_UI_Xaml!DirectUI::FrameworkElement::MeasureOverrideFromCore+0xf5\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x49a\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CGrid::MeasureOverride+0x11a\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x220\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CControl::MeasureOverride+0x36\r\nWindows_UI_Xaml!DirectUI::FrameworkElement::MeasureOverrideImpl+0x68\r\nWindows_UI_Xaml!DirectUI::FrameworkElementGenerated::MeasureOverride+0x67\r\ncontoso!winrt::impl::consume_Windows_UI_Xaml_IFrameworkElementOverrides\r\n    &lt;winrt::Windows::UI::Xaml::IFrameworkElementOverrides&gt;::MeasureOverride+027\r\ncontoso!winrt::impl::produce&lt;winrt::Contoso::implementation::ContosoFrame,\r\n    winrt::Windows::UI::Xaml::IFrameworkElementOverrides&gt;::MeasureOverride+0xa9\r\nWindows_UI_Xaml!DirectUI::FrameworkElementGenerated::MeasureOverrideProtected+0xc8\r\nWindows_UI_Xaml!DirectUI::FrameworkElement::MeasureOverrideFromCore+0xf5\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x49a\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CGrid::MeasureOverride+0x11a\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x220\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CCanvas::MeasureOverride+0xa0\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x220\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CXamlIslandRoot::MeasureOverride+0x71\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x220\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CXamlIslandRootCollection::MeasureOverride+0xb6\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x220\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CRootVisual::MeasureOverride+0x64\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x220\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CLayoutManager::UpdateLayout+0x15a\r\nWindows_UI_Xaml!CCoreServices::NWDrawTree+0x246\r\nWindows_UI_Xaml!CCoreServices::NWDrawMainTree+0xc2\r\nWindows_UI_Xaml!CWindowRenderTarget::Draw+0x71\r\nWindows_UI_Xaml!CXcpBrowserHost::OnTick+0xbc\r\nWindows_UI_Xaml!CXcpDispatcher::Tick+0xa1\r\nWindows_UI_Xaml!CXcpDispatcher::OnReentrancyProtectedWindowMessage+0x40\r\nWindows_UI_Xaml!CXcpDispatcher::ProcessMessage+0xea\r\nWindows_UI_Xaml!CXcpDispatcher::WindowProc+0x95\r\nWindows_UI_Xaml!CDeferredInvoke::DispatchQueuedMessage+0x9a\r\nWindows_UI_Xaml!CXcpDispatcher::MessageTimerCallbackStatic+0x1c\r\nCoreMessaging!CFlat::SehSafe::Execute&lt;\r\n    &lt;lambda_654db17c35df07198786f0867aa10de6&gt; &gt;+0x2c\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::TimeoutHandler::ImportAdapter$+0xb1\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::TimeoutManager::Callback_OnDispatch+0x21e\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::EventLoop::Callback_RunCoreLoop+0x36f\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::OnUserDispatch+0x1f3\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::DoWork+0x206\r\nCoreMessaging!Microsoft::CoreUI::Dispatch::UserAdapter::WindowProc+0x17f\r\nuser32!UserCallWinProcCheckWow+0x4ef\r\nuser32!DispatchClientMessage+0x9c\r\nuser32!__fnDWORD+0x3a\r\nntdll!KiUserCallbackDispatcherContinue+0x0\r\nwin32u!ZwUserPeekMessage+0x14\r\nuser32!_PeekMessage+0xb6\r\nuser32!PeekMessageW+0x146\r\ncontoso!MainWindow::MessageLoop+0x86\r\ncontoso!MainWidow::MainThreadProc+0x60\r\nkernel32!BaseThreadInitThunk+0x14\r\nntdll!RtlUserThreadStart+0x28\r\n<\/pre>\n<p>This should look very familiar: This stowed exception has the same exception code, and the bottom part of the stack is the same. The top is a little deeper than the first stack, though:<\/p>\n<table style=\"border-collapse: collapse;\" border=\"0\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<td style=\"width: 60px;\">\u00a0<\/td>\n<td style=\"border: solid 1px currentcolor;\" colspan=\"2\" align=\"center\">Stowed Exception #2<\/td>\n<\/tr>\n<tr>\n<td>&nbsp;<\/td>\n<td style=\"border: solid 1px currentcolor; position: relative;\" colspan=\"2\">\n<div style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: currentcolor; opacity: 10%;\">\u00a0<\/div>\n<pre>Microsoft_UI_Xaml!winrt::hresult_error::hresult_error+0x120\r\nMicrosoft_UI_Xaml!winrt::hresult_invalid_argument::hresult_invalid_argument+0x14\r\nMicrosoft_UI_Xaml!winrt::throw_hresult+0xcd\r\nMicrosoft_UI_Xaml!ItemsRepeater::MeasureOverride+0x9aa\r\nMicrosoft_UI_Xaml!winrt::impl::produce&lt;ItemsRepeater,\r\n    winrt::Windows::UI::Xaml::IFrameworkElementOverrides&gt;::MeasureOverride+0x5b\r\nWindows_UI_Xaml!DirectUI::FrameworkElementGenerated::\r\n    MeasureOverrideProtected+0xc8\r\nWindows_UI_Xaml!DirectUI::FrameworkElement::MeasureOverrideFromCore+0xf5\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x49a\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CGrid::MeasureOverride+0x11a\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x220\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CControl::MeasureOverride+0x36\r\nWindows_UI_Xaml!DirectUI::FrameworkElement::MeasureOverrideImpl+0x68\r\nWindows_UI_Xaml!DirectUI::FrameworkElementGenerated::MeasureOverride+0x67\r\ncontoso!winrt::impl::consume_Windows_UI_Xaml_IFrameworkElementOverrides\r\n    &lt;winrt::Windows::UI::Xaml::IFrameworkElementOverrides&gt;::MeasureOverride+027\r\n<\/pre>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"border-right: solid 1px currentcolor;\" colspan=\"3\">\u00a0<\/td>\n<\/tr>\n<tr>\n<td style=\"border: solid 1px currentcolor;\" colspan=\"2\" align=\"center\">Stowed Exception #1<\/td>\n<td style=\"width: 60px; border-right: solid 1px currentcolor;\">\u00a0<\/td>\n<\/tr>\n<tr>\n<td style=\"border: solid 1px currentcolor; position: relative;\" colspan=\"2\">\n<div style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: currentcolor; opacity: 10%;\">\u00a0<\/div>\n<pre>contoso!winrt::hresult_error::hresult_error+0x143\r\ncontoso!winrt::hresult_invalid_argument::hresult_invalid_argument+0x14\r\ncontoso!winrt::throw_hresult+0xb9\r\ncontoso!winrt::impl::consume_Windows_UI_Xaml_IFrameworkElementOverrides\r\n    &lt;winrt::Windows::UI::Xaml::IFrameworkElementOverrides&gt;::MeasureOverride+0x3b\r\n<\/pre>\n<\/td>\n<td style=\"border-right: solid 1px currentcolor;\">\u00a0<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px currentcolor; border-style: none solid;\" colspan=\"3\">\u00a0<\/td>\n<\/tr>\n<tr>\n<td style=\"border: solid 1px currentcolor;\" colspan=\"3\" align=\"center\">Common portion<\/td>\n<\/tr>\n<tr>\n<td style=\"border: solid 1px currentcolor; position: relative;\" colspan=\"3\">\n<div style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: currentcolor; opacity: 10%;\">\u00a0<\/div>\n<pre>contoso!winrt::impl::produce&lt;winrt::Contoso::implementation::ContosoFrame,\r\n    winrt::Windows::UI::Xaml::IFrameworkElementOverrides&gt;::MeasureOverride+0xa9\r\nWindows_UI_Xaml!DirectUI::FrameworkElementGenerated::MeasureOverrideProtected+0xc8\r\nWindows_UI_Xaml!DirectUI::FrameworkElement::MeasureOverrideFromCore+0xf5\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x49a\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\nWindows_UI_Xaml!CGrid::MeasureOverride+0x11a\r\nWindows_UI_Xaml!CFrameworkElement::MeasureCore+0x220\r\nWindows_UI_Xaml!CUIElement::MeasureInternal+0x1b8\r\nWindows_UI_Xaml!CUIElement::Measure+0x513\r\n\u22ee\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>What we&#8217;re seeing here is a cascade failure.<\/p>\n<p>The stowed exceptions are reported in reverse chronological order (most recent first), so what happened is that the <code>Items\u00adRepeater::<wbr \/>Measure\u00adOverride<\/code> returned <code>E_INVALID\u00adARG<\/code>, which C++\/WinRT turned into an exception, causing it to be thrown from <code>Contoso\u00adFrame<\/code>, which is then caught by C++\/WinRT at the ABI boundary and converted back to <code>E_INVALID\u00adARG<\/code> for <code>Measure\u00adOverride\u00adProtected<\/code>.<\/p>\n<p>We are therefore interested in the root cause of this exception, not all the places where the error is detected and converted to an exception, and then converted from an exception back to an <code>HRESULT<\/code>.<\/p>\n<p>Going down the list of stowed exceptions takes us backward in time, closer to the origin. But be careful not to go too far and start investigating some other exception. Go back only until the new stowed exception gives you more information than the previous one. In our case, that takes us to stowed exception number 8.<\/p>\n<pre>Stowed Exception #8 @ 0x000000002639f118\r\n0x80070057 (FACILITY_WIN32 - Win32 Undecorated Error Codes):\r\n    E_INVALIDARG - One or more arguments are not valid\r\n\r\ncombase!RoOriginateLanguageException+0x54\r\ncontoso!winrt::hresult_error::originate+0x6f\r\ncontoso!winrt::hresult_error::hresult_error+0x1de\r\ncontoso!winrt::hresult_invalid_argument::hresult_invalid_argument+0x14\r\ncontoso!winrt::throw_hresult+0xb9\r\ncontoso!winrt::throw_last_error+0x23\r\ncontoso!FormatString+0xcb\r\ncontoso!winrt::Contoso::implementation::ContosoListItemViewModel::HelpText+0x401\r\ncontoso!winrt::impl::produce&lt;TaskListItemViewModel&gt;::get_HelpText+0x24\r\ncontoso!winrt::impl::consume_IApplication&lt;&gt;::Resources+0x38\r\ncontoso!winrt::Contoso::implementation::FrameResourcesT&lt;&gt;::\r\n    FrameResources_obj96_Bindings::Update_+0xf4\r\ncontoso!winrt::Contoso::implementation::FrameResourcesT&lt;&gt;::\r\n    FrameResources_obj96_Bindings::ProcessBindings+0x122\r\ncontoso!winrt::MainWindow::implementation::XamlBindings::ProcessBindings+0x1f\r\ncontoso!winrt::impl::produce&lt;XamlBindings&gt;::ProcessBindings+0x44\r\nMicrosoft_UI_Xaml!ViewManager::GetElementFromElementFactory+0x315\r\nMicrosoft_UI_Xaml!ViewManager::GetElement+0x1bc\r\nMicrosoft_UI_Xaml!RepeaterLayoutContext::GetOrCreateElementAtCore+0x90\r\nMicrosoft_UI_Xaml!winrt::impl::produce&lt;VirtualizingLayoutContext&gt;::\r\n    GetOrCreateElementAtCore+0x49\r\nMicrosoft_UI_Xaml!winrt::impl::consume_IVirtualizingLayoutContextOverrides&lt;&gt;::\r\n    GetOrCreateElementAtCore+0x44\r\nMicrosoft_UI_Xaml!VirtualizingLayoutContext::GetOrCreateElementAt+0x8e\r\nMicrosoft_UI_Xaml!winrt::impl::produce&lt;VirtualizingLayoutContext&gt;::\r\n    GetOrCreateElementAt+0x22\r\ncontoso!winrt::impl::consume_IVirtualizingLayoutContext&lt;&gt;::\r\n    GetOrCreateElementAt+0x3e\r\ncontoso!winrt::Contoso::implementation::FrameLayout::MeasureOverride+0xba\r\ncontoso!winrt::impl::produce&lt;FrameLayout&gt;::MeasureOverride+0x3c\r\n...\r\n<\/pre>\n<p>Okay, now we are getting somewhere.<\/p>\n<p>The &#8220;invalid argument&#8221; exception was thrown from the <code>FormatString<\/code> function:<\/p>\n<pre>inline winrt::hstring FormatString(const PCWSTR format, ...)\r\n{\r\n    va_list ap;\r\n    va_start(ap, format);\r\n\r\n    wchar_t strBuffer[512];\r\n    if (FormatMessage(FORMAT_MESSAGE_FROM_STRING, format, 0, 0,\r\n            strBuffer, ARRAYSIZE(strBuffer), &amp;ap) == 0)\r\n    {\r\n        winrt::throw_last_error(); \/\/ &lt;&lt;&lt; thrown here\r\n    }\r\n\r\n    return winrt::hstring(strBuffer);\r\n}\r\n<\/pre>\n<p>Aha, the problem is that <code>Format\u00adMessage<\/code> itself failed with <code>E_INVALID\u00adARG<\/code>.\u00b9<\/p>\n<p>What would cause <code>Format\u00adMessage<\/code> to fail with <code>E_INVALID\u00adARG<\/code>? All of the arguments look good.<\/p>\n<p>Well, except that the format string might be invalid.<\/p>\n<p>The <code>Contoso\u00adList\u00adItem\u00adView\u00adModel::\u00adHelpText<\/code> method is formatting this string:<\/p>\n<pre>hstring preformattedString = viewServices-&gt;GetString(L\"ProgressStateText\");\r\nappendState(FormatString(preformattedString.c_str(), formattedValue.c_str()));\r\n<\/pre>\n<p>The <code>Progress\u00adState\u00adText<\/code> string is<\/p>\n<pre>  &lt;data name=\"ProgressStateText\" xml:space=\"preserve\"&gt;\r\n    &lt;value&gt;Operation %1 percent complete&lt;\/value&gt;\r\n    &lt;comment&gt;Accessible text for progress bar&lt;\/comment&gt;\r\n  \r\n<\/pre>\n<p>The FormatMessage function replaces the <code>%1<\/code> with the percentage amount. But the text is talking about percents. I wonder&#8230;<\/p>\n<p>Hey look, the Italian translation looks suspicious:<\/p>\n<pre>  &lt;data name=\"ProgressStateText\" xml:space=\"preserve\"&gt;\r\n    &lt;value&gt;Operazione completata al %1%&lt;\/value&gt;\r\n    &lt;comment&gt;Accessible text for progress bar&lt;\/comment&gt;\r\n  &lt;\/data&gt;\r\n<\/pre>\n<p>Look at that trailing percent sign. That&#8217;s illegal in <code>Format\u00adMessage<\/code>!<\/p>\n<p>So that&#8217;s where the invalid parameter error is coming from. It&#8217;s a mistranslated format string that accidentally used a percent sign in a place where percent signs have special meaning.<\/p>\n<p>This particular string is used for screen readers, and it shouldn&#8217;t contain the percent sign at all. That&#8217;s why the English version spells it out as &#8220;percent&#8221;.<\/p>\n<p>The customer updated the localization comment to emphasize that the word &#8220;percent&#8221; must be written out in words and that you cannot use the <code>%<\/code> symbol.<\/p>\n<p>(In case you couldn&#8217;t figure it out, the primary goal of today&#8217;s investigation was to demonstrate how to use stowed exceptions and specifically how to find the stowed exception that is going to be most helpful in finding the root cause of the problem.)<\/p>\n<p>\u00b9 Another problem is that the <code>Format\u00adString<\/code> function forgot to call <code>va_end(ap)<\/code> when it was finished with the <code>va_list<\/code>. On most platforms, it&#8217;s a nop, but <a title=\"Even if a function doesn\u2019t do anything, you still have to call it if the documentation says so, because it might do something tomorrow\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20080925-00\/?p=20763\"> you still have to call it<\/a>, because you might be unlucky and run on a platform where it actually does something required.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Chasing it back to its origin.<\/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-109352","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Chasing it back to its origin.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/109352","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=109352"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/109352\/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=109352"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=109352"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=109352"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}