Using ExecuteScript( "document.documentElement.outerHTML" ) to get the DOM from a loaded page can terminate a 32-bit app with exception code e0000008 due to EmbeddedBrowserWebView!partition_alloc::internal::OnNoMemoryInternal being called when:
a) document.documentElement.outerHTML.length is large (outerHTML > 15 million chars is not unusual on some e-commerce sites using React)
b) memory is fragmented (ExecuteScript needs at least a 30MB contiguous free block when converting 15 million chars)
If the return value from ExecuteScript has 15 million chars then the call to UTF8ToWide in EmbeddedBrowserWebView.dll is passed a UTF8 copy of the return value (requiring a 15MB contiguous block) and creates a char16_t copy (requiring a 30MB contiguous block)
The process can have plenty of free memory but needs several large contiguous free blocks to avoid catastrophe when calling ExecuteScript (e.g. there might be 500MB free in total but if the largest free block is 20MB then any single allocation over 20MB will fail).
It would be much better if the completion handler returned E_OUTOFMEMORY instead of terminating the app when allocation fails (because it's difficult for the caller to know exactly how large the returned JSON payload might be).
02f6ddf8 72f0a9e0 e0000008 00000001 00000003 KERNELBASE!RaiseException+0x62
02f6de78 72f0a9fa 02280000 02f6de94 72f0aa12 EmbeddedBrowserWebView!partition_alloc::internal::OnNoMemoryInternal+0x90
02f6de84 72f0aa11 02280000 02280000 02f6df24 EmbeddedBrowserWebView!partition_alloc::TerminateBecauseOutOfMemory+0xa
02f6de94 72f078b4 02280000 00000000 001fffff EmbeddedBrowserWebView!partition_alloc::internal::OnNoMemory+0x11
02f6df24 72f0a204 02280000 0000002d 731a3400 EmbeddedBrowserWebView!partition_alloc::PartitionRoot::OutOfMemory+0x174
02f6df3c 72f09f73 00000000 00000010 0226d000 EmbeddedBrowserWebView!partition_alloc::internal::`anonymous namespace'::PartitionOutOfMemoryMappingFailure+0x24
02f6df70 72f0955a 0226c1f0 00004000 00000000 EmbeddedBrowserWebView!partition_alloc::internal::`anonymous namespace'::PartitionDirectMap+0x2f3
02f6dfe0 72f0bbc2 731a3400 00000010 0226c1f0 EmbeddedBrowserWebView!partition_alloc::internal::PartitionBucket::SlowPathAlloc+0x10a
02f6e064 72f0b38e 0226c1f0 00000000 00000000 EmbeddedBrowserWebView!allocator_shim::internal::PartitionAllocFunctionsInternal<16,2>::Malloc+0x5b2
02f6e084 73043cc8 0226c1f0 02f6e0b8 72ec9093 EmbeddedBrowserWebView!_malloc_base+0x1e
02f6e090 72ec9093 0226c1f0 81137214 011360f8 EmbeddedBrowserWebView!operator new+0x1a
02f6e0b8 72ec8d31 0000009c 7a204001 00000030 EmbeddedBrowserWebView!std::__Cr::basic_string<char16_t,std::__Cr::char_traits<char16_t>,std::__Cr::allocator<char16_t> >::shrink_to_fit+0x93
02f6e0d8 72ec8d63 5c804000 01137212 02f6e104 EmbeddedBrowserWebView!base::UTF8ToWide+0x3d1
02f6e0f0 72d7b6e3 02f6e104 5c804000 01137212 EmbeddedBrowserWebView!base::UTF8ToWide+0x23
02f6e120 72d68df9 57a58858 02f6e260 02f6e1b0 EmbeddedBrowserWebView!base::internal::Invoker<base::internal::FunctorTraits<`lambda at ..\..\edge_embedded_browser\client\win\current\embedded_browser_webview_frame.cc:153:11' &&,scoped_refptr<ICoreWebView2ExecuteScriptCompletedHandler> &&>,base::internal::BindState<0,0,0,`lambda at ..\..\edge_embedded_browser\client\win\current\embedded_browser_webview_frame.cc:153:11',scoped_refptr<ICoreWebView2ExecuteScriptCompletedHandler> >,void (const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char> > &, const long &)>::RunOnce+0x43
02f6e148 72df6f72 02f6e260 02f6e1b0 02f6e180 EmbeddedBrowserWebView!base::OnceCallback<void (long, const tagVARIANT *)>::Run+0x37
02f6e164 72df6e2e 57a58390 02f6e260 02f6e1b0 EmbeddedBrowserWebView!base::internal::Invoker<base::internal::FunctorTraits<void (mojo::internal::CallbackWithDeleteHelper<void (const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char> > &, const long &)>::*&&)(const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char> > &, const long &) __attribute__((thiscall)),std::__Cr::unique_ptr<mojo::internal::CallbackWithDeleteHelper<void (const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char> > &, const long &)>,std::__Cr::default_delete<mojo::internal::CallbackWithDeleteHelper<void (const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char> > &, const long &)> > > &&>,base::internal::BindState<1,1,0,void (mojo::internal::CallbackWithDeleteHelper<void (const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char> > &, const long &)>::*)(const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char> > &, const long &) __attribute__((thiscall)),std::__Cr::unique_ptr<mojo::internal::CallbackWithDeleteHelper<void (const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char> > &, const long &)>,std::__Cr::default_delete<mojo::internal::CallbackWithDeleteHelper<void (const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char> > &, const long &)> > > >,void (const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char> > &, const long &)>::RunOnce+0x22
02f6e198 72decbca 000001d3 00000000 02f6e1b0 EmbeddedBrowserWebView!embedded_browser_webview::EmbeddedBrowserWebViewFrameBaseCore::InvokeExecuteScriptHandler+0x9c
02f6e1c0 72d15d58 000001d3 00000000 00000000 EmbeddedBrowserWebView!embedded_browser_webview::EmbeddedBrowserWebViewCore::ExecuteScriptResult+0x4a
02f6e2dc 72df4f93 57a2c0b0 02f6e45c 02f6e354 EmbeddedBrowserWebView!embedded_browser::mojom::EmbeddedBrowserClientStubDispatch::Accept+0x19c4
02f6e2ec 72f9d9c1 02f6e45c 72fa052b 02f6e45c EmbeddedBrowserWebView!embedded_browser::mojom::EmbeddedBrowserClientStub<mojo::RawPtrImplRefTraits<embedded_browser::mojom::EmbeddedBrowserClient> >::Accept+0x13
02f6e354 72f94fbb 02f6e45c 57aceb8c 02f6e384 EmbeddedBrowserWebView!mojo::InterfaceEndpointClient::HandleValidatedMessage+0x345
02f6e384 72f9e848 02f6e45c 730a9870 00002000 EmbeddedBrowserWebView!mojo::MessageDispatcher::Accept+0xfb
02f6e444 72f9a82b 02f6e45c 02f6e4c0 72f0955a EmbeddedBrowserWebView!mojo::InterfaceEndpointClient::HandleIncomingMessage+0x50
02f6e4ac 72f9a405 02f6e4dc 00000002 57b14000 EmbeddedBrowserWebView!mojo::internal::MultiplexRouter::ProcessIncomingMessage+0x1e5
02f6e544 72f94fbb 02f6e58c 00000000 00000000 EmbeddedBrowserWebView!mojo::internal::MultiplexRouter::Accept+0x175
02f6e574 72fa21be 02f6e58c 72f94ec0 57aa0368 EmbeddedBrowserWebView!mojo::MessageDispatcher::Accept+0xfb
02f6e604 72fa275d 00000000 57aa0368 57af4034 EmbeddedBrowserWebView!mojo::Connector::DispatchMessageW+0x11e
02f6e63c 72fa2626 02f6e65c 72fa25e9 00000000 EmbeddedBrowserWebView!mojo::Connector::ReadAllAvailableMessages+0x87
02f6e644 72fa25e9 00000000 ce06acde 72fa25c0 EmbeddedBrowserWebView!mojo::Connector::OnHandleReadyInternal+0x1a
02f6e65c 72fa2e0d 730a9870 00000000 57a44b20 EmbeddedBrowserWebView!mojo::Connector::OnWatcherHandleReady+0x29
02f6e678 72ddb76f 57a44b20 00000000 00000000 EmbeddedBrowserWebView!base::internal::Invoker<base::internal::FunctorTraits<void (mojo::Connector::*const &)(const char *, unsigned int) __attribute__((thiscall)),mojo::Connector *,const char *const &>,base::internal::BindState<1,1,0,void (mojo::Connector::*)(const char *, unsigned int) __attribute__((thiscall)),base::internal::UnretainedWrapper<mojo::Connector,base::unretained_traits::MayNotDangle,0>,base::internal::UnretainedWrapper<const char,base::unretained_traits::MayNotDangle,0> >,void (unsigned int)>::Run+0x2d
02f6e690 72fa2dae 00000000 02f6e6bc 72fa2dd0 EmbeddedBrowserWebView!base::RepeatingCallback<void (const gfx::PointF &)>::Run+0x2f
02f6e69c 72fa2dd0 57a59784 00000000 57a885c4 EmbeddedBrowserWebView!mojo::SimpleWatcher::DiscardReadyState+0xe
02f6e6bc 72dd8300 57a59770 00000000 57a885c4 EmbeddedBrowserWebView!base::internal::Invoker<base::internal::FunctorTraits<void (*const &)(const base::RepeatingCallback<void (unsigned int)> &, unsigned int, const mojo::HandleSignalsState &),const base::RepeatingCallback<void (unsigned int)> &>,base::internal::BindState<0,1,0,void (*)(const base::RepeatingCallback<void (unsigned int)> &, unsigned int, const mojo::HandleSignalsState &),base::RepeatingCallback<void (unsigned int)> >,void (unsigned int, const mojo::HandleSignalsState &)>::Run+0x20
02f6e6dc 72fab945 00000000 57a885c4 730a9870 EmbeddedBrowserWebView!base::RepeatingCallback<void (IUnknown *, embedded_browser_webview::internal::ResourceState)>::Run+0x34
02f6e714 72fabbc3 00000001 00000000 57a885c4 EmbeddedBrowserWebView!mojo::SimpleWatcher::OnHandleReady+0xc5
02f6e73c 72ec4c12 57a885a0 00000000 00000000 EmbeddedBrowserWebView!base::internal::Invoker<base::internal::FunctorTraits<void (mojo::SimpleWatcher::*&&)(int, unsigned int, const mojo::HandleSignalsState &) __attribute__((thiscall)),base::WeakPtr<mojo::SimpleWatcher> &&,int &&,unsigned int &&,mojo::HandleSignalsState &&>,base::internal::BindState<1,1,0,void (mojo::SimpleWatcher::*)(int, unsigned int, const mojo::HandleSignalsState &) __attribute__((thiscall)),base::WeakPtr<mojo::SimpleWatcher>,int,unsigned int,mojo::HandleSignalsState>,void ()>::RunOnce+0x53
02f6e798 72dd6fbc 02f6e800 0000e7b0 02f6e7d8 EmbeddedBrowserWebView!base::TaskAnnotator::RunTaskImpl+0x162
02f6e7d0 72dd6e84 730ba696 02f6e800 00000000 EmbeddedBrowserWebView!base::TaskAnnotator::RunTask<>+0x74
02f6e870 72dd66a2 72cfd21a 00000000 00000000 EmbeddedBrowserWebView!embedded_browser_webview::internal::AppTaskRunner::DoWork+0x114
02f6e8ac 72dd7054 00000401 00000000 00000000 EmbeddedBrowserWebView!embedded_browser_webview::internal::AppTaskRunner::MessageCallback+0x32
02f6e8d0 72e7093d 57a441e0 00000401 00000000 EmbeddedBrowserWebView!base::internal::Invoker<base::internal::FunctorTraits<bool (embedded_browser_webview::internal::AppTaskRunner::*const &)(unsigned int, unsigned int, long, long *) __attribute__((thiscall)),embedded_browser_webview::internal::AppTaskRunner *>,base::internal::BindState<1,1,0,bool (embedded_browser_webview::internal::AppTaskRunner::*)(unsigned int, unsigned int, long, long *) __attribute__((thiscall)),base::internal::UnretainedWrapper<embedded_browser_webview::internal::AppTaskRunner,base::unretained_traits::MayNotDangle,0> >,bool (unsigned int, unsigned int, long, long *)>::Run+0x34
02f6e908 72e703e8 02b600a6 00000401 00000000 EmbeddedBrowserWebView!base::win::MessageWindow::WindowProc+0x13d
02f6e948 753ed2d3 02b600a6 00000401 00000000 EmbeddedBrowserWebView!base::win::WrappedWindowProc<&base::win::MessageWindow::WindowProc>+0x48
02f6e974 753cd30a 72e703a0 02b600a6 00000401 user32!_InternalCallWinProc+0x2b
02f6ea5c 753ccc54 72e703a0 00000000 00000401 user32!UserCallWinProcCheckWow+0x30a
02f6ead0 753cca10 94f8f39a 02f6eb20 002ceef5 user32!DispatchMessageWorker+0x234
02f6eadc 002ceef5 032ead00 00000000 56f1b412 user32!DispatchMessageW+0x10
Important. My app's user experience is significantly compromised.
What happened?
Using ExecuteScript( "document.documentElement.outerHTML" ) to get the DOM from a loaded page can terminate a 32-bit app with exception code e0000008 due to EmbeddedBrowserWebView!partition_alloc::internal::OnNoMemoryInternal being called when:
a) document.documentElement.outerHTML.length is large (outerHTML > 15 million chars is not unusual on some e-commerce sites using React)
b) memory is fragmented (ExecuteScript needs at least a 30MB contiguous free block when converting 15 million chars)
If the return value from ExecuteScript has 15 million chars then the call to UTF8ToWide in EmbeddedBrowserWebView.dll is passed a UTF8 copy of the return value (requiring a 15MB contiguous block) and creates a char16_t copy (requiring a 30MB contiguous block)
The process can have plenty of free memory but needs several large contiguous free blocks to avoid catastrophe when calling ExecuteScript (e.g. there might be 500MB free in total but if the largest free block is 20MB then any single allocation over 20MB will fail).
It would be much better if the completion handler returned E_OUTOFMEMORY instead of terminating the app when allocation fails (because it's difficult for the caller to know exactly how large the returned JSON payload might be).
Importance
Important. My app's user experience is significantly compromised.
Runtime Channel
Stable release (WebView2 Runtime)
Runtime Version
148.0.3967.96
SDK Version
1.0.3800.47
Framework
Win32
Operating System
Windows Server
OS Version
10.0.14393
Repro steps
Repros in Edge Browser
No, issue does not reproduce in the corresponding Edge version
Regression
No, this never worked
Last working version (if regression)
No response