Bug 141736
Summary: | [GTK] Crash in debug builds when closing web page after r180214 | ||
---|---|---|---|
Product: | WebKit | Reporter: | Michael Catanzaro <mcatanzaro> |
Component: | WebKitGTK | Assignee: | Nobody <webkit-unassigned> |
Status: | RESOLVED DUPLICATE | ||
Severity: | Normal | CC: | cgarcia, mcatanzaro, svillar |
Priority: | P2 | ||
Version: | 528+ (Nightly build) | ||
Hardware: | PC | ||
OS: | Linux |
Michael Catanzaro
r180214 seems to have introduced a crash when closing epiphany. I need to debug this further but my guess at this point is that in DOMObjectCacheFrameObserver::frameDestroyed, the call to domObjectCacheFrameObservers().remove(frame) causes the destruction of the DOMObjectCacheFrameObserver, which is bad because WebCore::FrameDestructionObserver's destructor calls m_frame->removeDestructionObserver, resulting in WebCore::Frame::m_destructionObservers changing size while it is being iterated through in WebCore::Frame's destructor. That's probably illegal.
#0 0x00007f6f920aa3a7 in WTFCrash ()
at ../../Source/WTF/wtf/Assertions.cpp:321
No locals.
#1 0x00007f6f97df035f in WTF::HashTableConstIterator<WebCore::FrameDestructionObserver*, WebCore::FrameDestructionObserver*, WTF::IdentityExtractor, WTF::PtrHash<WebCore::FrameDestructionObserver*>, WTF::HashTraits<WebCore::FrameDestructionObserver*>, WTF::HashTraits<WebCore::FrameDestructionObserver*> >::checkValidity (this=0x7fff804241d0) at ../../Source/WTF/wtf/HashTable.h:210
__PRETTY_FUNCTION__ = "void WTF::HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::checkValidity() const [with Key = WebCore::FrameDestructionObserver*; Value = WebCore::FrameDestructionObserv"...
#2 0x00007f6f97def7e0 in WTF::HashTableConstIterator<WebCore::FrameDestructionObserver*, WebCore::FrameDestructionObserver*, WTF::IdentityExtractor, WTF::PtrHash<WebCore::FrameDestructionObserver*>, WTF::HashTraits<WebCore::FrameDestructionObserver*>, WTF::HashTraits<WebCore::FrameDestructionObserver*> >::operator++
(this=0x7fff804241d0) at ../../Source/WTF/wtf/HashTable.h:177
__PRETTY_FUNCTION__ = "WTF::HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::const_iterator& WTF::HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::operator++()"...
#3 0x00007f6f97dee42a in WTF::HashTableConstIteratorAdapter<WTF::HashTable<WebCore::FrameDestructionObserver*, WebCore::FrameDestructionObserver*, WTF::IdentityExtractor, WTF::PtrHash<WebCore::FrameDestructionObserver*>, WTF::HashTraits<WebCore::FrameDestructionObserver*>, WTF::HashTraits<WebCore::FrameDestructionObserver*> >, WebCore::FrameDestructionObserver*>::operator++ (this=0x7fff804241d0)
at ../../Source/WTF/wtf/HashTable.h:1363
No locals.
#4 0x00007f6f97debe5e in WebCore::Frame::willDetachPage (this=0x7f6f6d7ed000)
at ../../Source/WebCore/page/Frame.cpp:785
observer = @0x7f6f6dffe4c8: 0x85ab80
__for_range = @0x7f6f6d7ed010: {m_impl = {
static m_maxLoad = <optimized out>,
static m_minLoad = <optimized out>, m_table = 0x7f6f6dffe4c0,
m_tableSize = 8, m_tableSizeMask = 7, m_keyCount = 2,
m_deletedCount = 1, m_iterators = 0x0,
m_mutex = std::unique_ptr<std::mutex> containing 0x7a6ee0}}
__for_begin = {m_impl = {m_position = 0x7f6f6dffe4c8,
m_endPosition = 0x7f6f6dffe500, m_table = 0x0, m_next = 0x0,
m_previous = 0x0}}
__for_end = {m_impl = {m_position = 0x7f6f6dffe500,
m_endPosition = 0x7f6f6dffe500, m_table = 0x0, m_next = 0x0,
m_previous = 0x0}}
#5 0x00007f6f97cac54c in WebCore::FrameLoader::detachFromParent (
this=0x7f6f6d7ed098) at ../../Source/WebCore/loader/FrameLoader.cpp:2496
parent = 0x0
protect = {m_ptr = 0x7f6f6d7ed000}
#6 0x00007f6f971d5eb0 in WebKit::WebPage::close (this=0x7f6f6c012600)
at ../../Source/WebKit2/WebProcess/WebPage/WebPage.cpp:1037
isRunningModal = false
#7 0x00007f6f973838b9 in IPC::callMemberFunctionImpl<WebKit::WebPage, void (WebKit::WebPage::*)(), std::tuple<>>(WebKit::WebPage*, void (WebKit::WebPage::*)(), std::tuple<>&&, std::index_sequence<>) (object=0x7f6f6c012600,
function=(void (WebKit::WebPage::*)(WebKit::WebPage * const)) 0x7f6f971d5aee <WebKit::WebPage::close()>,
args=<unknown type in /home/mcatanzaro/jhbuild/install/lib/libwebkit2gtk-4.0.so.37, CU 0xc7eeee6, DIE 0xc87c1c4>)
at ../../Source/WebKit2/Platform/IPC/HandleMessage.h:16
No locals.
#8 0x00007f6f9738193e in IPC::callMemberFunction<WebKit::WebPage, void (WebKit::WebPage::*)(), std::tuple<>, std::make_index_sequence<0ul> >(std::tuple<>&&, WebKit::WebPage*, void (WebKit::WebPage::*)()) (
args=<unknown type in /home/mcatanzaro/jhbuild/install/lib/libwebkit2gtk-4.0.so.37, CU 0xc7eeee6, DIE 0xc875b80>, object=0x7f6f6c012600,
function=(void (WebKit::WebPage::*)(WebKit::WebPage * const)) 0x7f6f971d5aee <WebKit::WebPage::close()>)
at ../../Source/WebKit2/Platform/IPC/HandleMessage.h:22
No locals.
#9 0x00007f6f9737dbd8 in IPC::handleMessage<Messages::WebPage::Close, WebKit::WebPage, void (WebKit::WebPage::*)()> (decoder=..., object=0x7f6f6c012600,
function=(void (WebKit::WebPage::*)(WebKit::WebPage * const)) 0x7f6f971d5aee <WebKit::WebPage::close()>)
at ../../Source/WebKit2/Platform/IPC/HandleMessage.h:92
__PRETTY_FUNCTION__ = "void IPC::handleMessage(IPC::MessageDecoder&, C*, MF) [with T = Messages::WebPage::Close; C = WebKit::WebPage; MF = void (WebKit::WebPage::*)()]"
arguments = empty std::tuple
#10 0x00007f6f973780d1 in WebKit::WebPage::didReceiveWebPageMessage (
this=0x7f6f6c012600, connection=..., decoder=...)
at DerivedSources/WebKit2/WebPageMessageReceiver.cpp:629
__PRETTY_FUNCTION__ = "void WebKit::WebPage::didReceiveWebPageMessage(IPC::Connection&, IPC::MessageDecoder&)"
#11 0x00007f6f971e0505 in WebKit::WebPage::didReceiveMessage (
this=0x7f6f6c012600, connection=..., decoder=...)
at ../../Source/WebKit2/WebProcess/WebPage/WebPage.cpp:3584
No locals.
#12 0x00007f6f96eb40a6 in IPC::MessageReceiverMap::dispatchMessage (
this=0x6e5fc0, connection=..., decoder=...)
at ../../Source/WebKit2/Platform/IPC/MessageReceiverMap.cpp:87
messageReceiver = 0x7f6f6c012610
__PRETTY_FUNCTION__ = "bool IPC::MessageReceiverMap::dispatchMessage(IPC::Connection&, IPC::MessageDecoder&)"
#13 0x00007f6f970abad4 in WebKit::WebProcess::didReceiveMessage (
this=0x6e5ec0, connection=..., decoder=...)
at ../../Source/WebKit2/WebProcess/WebProcess.cpp:611
__PRETTY_FUNCTION__ = "virtual void WebKit::WebProcess::didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&)"
#14 0x00007f6f96ea26c0 in IPC::Connection::dispatchMessage (
this=0x7f6f6d7fb000, decoder=...)
at ../../Source/WebKit2/Platform/IPC/Connection.cpp:837
No locals.
#15 0x00007f6f96ea278c in IPC::Connection::dispatchMessage (
this=0x7f6f6d7fb000,
message=std::unique_ptr<IPC::MessageDecoder> containing 0x7f6f6def0180)
at ../../Source/WebKit2/Platform/IPC/Connection.cpp:860
oldDidReceiveInvalidMessage = false
#16 0x00007f6f96ea294f in IPC::Connection::dispatchOneMessage (
this=0x7f6f6d7fb000)
at ../../Source/WebKit2/Platform/IPC/Connection.cpp:888
message = std::unique_ptr<IPC::MessageDecoder> containing 0x0
#17 0x00007f6f96eb3419 in WTF::FunctionWrapper<void (IPC::Connection::*)()>::operator() (this=0x7f6f6dfec6c8, c=0x7f6f6d7fb000)
at ../../Source/WTF/wtf/Functional.h:218
No locals.
#18 0x00007f6f96eb3264 in WTF::BoundFunctionImpl<WTF::FunctionWrapper<void (IPC::Connection::*)()>, void (IPC::Connection*)>::operator()() (
this=0x7f6f6dfec6b8) at ../../Source/WTF/wtf/Functional.h:496
No locals.
#19 0x00007f6f96eacb77 in WTF::Function<void ()>::operator()() const (
this=0x7f6f140011d0) at ../../Source/WTF/wtf/Functional.h:704
__PRETTY_FUNCTION__ = "R WTF::Function<R()>::operator()() const [with R = void]"
#20 0x00007f6f96ea93ac in std::_Function_handler<void (), WTF::Function<void ()> >::_M_invoke(std::_Any_data const&) (__functor=...)
at /usr/include/c++/4.9.2/functional:2039
No locals.
#21 0x00007f6f96e8b450 in std::function<void ()>::operator()() const (
this=0x7fff80425e30) at /usr/include/c++/4.9.2/functional:2439
No locals.
#22 0x00007f6f98cc60a9 in WTF::RunLoop::performWork (this=0x7f6f6dff9000)
at ../../Source/WTF/wtf/RunLoop.cpp:104
function = {<std::_Maybe_unary_or_binary_function<void>> = {<No data fields>}, <std::_Function_base> = {static _M_max_size = 16,
static _M_max_align = 8, _M_functor = {_M_unused = {
_M_object = 0x7f6f140011d0, _M_const_object = 0x7f6f140011d0,
_M_function_pointer = 0x7f6f140011d0,
_M_member_pointer = (void (std::_Undefined_class::*)(std::_Undefined_class * const)) 0x7f6f140011d0, this adjustment 140116597139168},
_M_pod_data = "\320\021\000\024o\177\000\000\340\346\377oo\177\000"},
_M_manager = 0x7f6f96ea93ae <std::_Function_base::_Base_manager<WTF::Function<void ()> >::_M_manager(std::_Any_data&, std::_Any_data const&, std::_Manager_operation)>},
_M_invoker = 0x7f6f96ea938c <std::_Function_handler<void (), WTF::Function<void ()> >::_M_invoke(std::_Any_data const&)>}
functionsToHandle = 1
#23 0x00007f6f98cc9908 in WTF::RunLoop::<lambda()>::operator()(void) const (
__closure=0x7f6f14001e20) at ../../Source/WTF/wtf/gtk/RunLoopGtk.cpp:104
runLoop = {m_ptr = 0x7f6f6dff9000}
#24 0x00007f6f98cc9e90 in std::_Function_handler<void(), WTF::RunLoop::wakeUp()::<lambda()> >::_M_invoke(const std::_Any_data &) (__functor=...)
at /usr/include/c++/4.9.2/functional:2039
No locals.
#25 0x00007f6f96e8b450 in std::function<void ()>::operator()() const (
this=0x7fff80425f68) at /usr/include/c++/4.9.2/functional:2439
No locals.
#26 0x00007f6f920f2bbf in WTF::GMainLoopSource::voidCallback (
this=0x7f6f6dfa0dc0)
at ../../Source/WTF/wtf/gobject/GMainLoopSource.cpp:365
context = {source = {m_ptr = 0x7f6f14001e40}, cancellable = {
m_ptr = 0x0}, socketCancellable = {m_ptr = 0x0},
voidCallback = {<std::_Maybe_unary_or_binary_function<void>> = {<No data fields>}, <std::_Function_base> = {static _M_max_size = 16,
static _M_max_align = 8, _M_functor = {_M_unused = {
_M_object = 0x7f6f14001e20,
_M_const_object = 0x7f6f14001e20,
_M_function_pointer = 0x7f6f14001e20,
_M_member_pointer = (void (std::_Undefined_class::*)(std::_Undefined_class * const)) 0x7f6f14001e20, this adjustment 140117281643823},
_M_pod_data = " \036\000\024o\177\000\000/\235̘o\177\000"},
_M_manager = 0x7f6f98cc9e92 <std::_Function_base::_Base_manager<WTF::RunLoop::wakeUp()::<lambda()> >::_M_manager(std::_Any_data &, const std::_Any_data &, std::_Manager_operation)>},
_M_invoker = 0x7f6f98cc9e70 <std::_Function_handler<void(), WTF::RunLoop::wakeUp()::<lambda()> >::_M_invoke(const std::_Any_data &)>},
boolCallback = {<std::_Maybe_unary_or_binary_function<bool>> = {<No data fields>}, <std::_Function_base> = {static _M_max_size = 16,
static _M_max_align = 8, _M_functor = {_M_unused = {
_M_object = 0x7f6f6dfa0e48,
_M_const_object = 0x7f6f6dfa0e48,
_M_function_pointer = 0x7f6f6dfa0e48,
_M_member_pointer = (void (std::_Undefined_class::*)(std::_Undefined_class * const)) 0x7f6f6dfa0e48, this adjustment 140116597137616},
_M_pod_data = "H\016\372mo\177\000\000\320\340\377oo\177\000"}, _M_manager = 0x0}, _M_invoker = 0x7f6f6fffe1f0},
socketCallback = {<std::_Maybe_unary_or_binary_function<bool, GIOCondition>> = {<std::unary_function<GIOCondition, bool>> = {<No data fields>}, <No data fields>}, <std::_Function_base> = {static _M_max_size = 16,
static _M_max_align = 8, _M_functor = {_M_unused = {
_M_object = 0x7f6f6fffe170,
_M_const_object = 0x7f6f6fffe170,
_M_function_pointer = 0x7f6f6fffe170,
_M_member_pointer = (void (std::_Undefined_class::*)(std::_Undefined_class * const)) 0x7f6f6fffe170, this adjustment 140116597137632},
_M_pod_data = "p\341\377oo\177\000\000\340\340\377oo\177\000"}, _M_manager = 0x0}, _M_invoker = 0x7f6f6fffe0f0},
destroyCallback = {<std::_Maybe_unary_or_binary_function<void>> = {<No data fields>}, <std::_Function_base> = {static _M_max_size = 16,
static _M_max_align = 8, _M_functor = {_M_unused = {
_M_object = 0x7f6f6fffe2c0,
_M_const_object = 0x7f6f6fffe2c0,
_M_function_pointer = 0x7f6f6fffe2c0,
_M_member_pointer = (void (std::_Undefined_class::*)(std::_Undefined_class * const)) 0x7f6f6fffe2c0, this adjustment 140116563562504},
_M_pod_data = "\300\342\377oo\177\000\000\b\220\377mo\177\000"}, _M_manager = 0x0}, _M_invoker = 0x641550}}
#27 0x00007f6f920f32c3 in WTF::GMainLoopSource::voidSourceCallback (
source=0x7f6f6dfa0dc0)
at ../../Source/WTF/wtf/gobject/GMainLoopSource.cpp:456
No locals.
#28 0x00007f6f8e19cfe2 in g_idle_dispatch (source=0x7f6f14001e40,
callback=0x7f6f920f32a0 <WTF::GMainLoopSource::voidSourceCallback(WTF::GMainLoopSource*)>, user_data=0x7f6f6dfa0dc0) at gmain.c:5392
No locals.
#29 0x00007f6f8e19a656 in g_main_dispatch (context=0x641550) at gmain.c:3122
dispatch = 0x7f6f8e19cf96 <g_idle_dispatch>
prev_source = 0x0
was_in_call = 0
user_data = 0x7f6f6dfa0dc0
callback = 0x7f6f920f32a0 <WTF::GMainLoopSource::voidSourceCallback(WTF::GMainLoopSource*)>
cb_funcs = 0x7f6f8e4a6a00 <g_source_callback_funcs>
cb_data = 0x7f6f14001ed0
need_destroy = 0
source = 0x7f6f14001e40
current = 0x662110
i = 0
__FUNCTION__ = "g_main_dispatch"
#30 0x00007f6f8e19b491 in g_main_context_dispatch (context=0x641550)
at gmain.c:3737
No locals.
#31 0x00007f6f8e19b676 in g_main_context_iterate (context=0x641550, block=1,
dispatch=1, self=0x66b190) at gmain.c:3808
max_priority = 2147483647
timeout = 4997
some_ready = 1
nfds = 5
allocated_nfds = 5
fds = 0x6c3210
#32 0x00007f6f8e19ba9d in g_main_loop_run (loop=0xaa2f20) at gmain.c:4002
self = 0x66b190
__FUNCTION__ = "g_main_loop_run"
#33 0x00007f6f98cc9682 in WTF::RunLoop::run ()
at ../../Source/WTF/wtf/gtk/RunLoopGtk.cpp:59
mainRunLoop = @0x7f6f6dff9000: {<WTF::FunctionDispatcher> = {<WTF::ThreadSafeRefCounted<WTF::FunctionDispatcher>> = {<WTF::ThreadSafeRefCountedBase> = {m_refCount = {<std::__atomic_base<int>> = {
_M_i = 3}, <No data fields>}}, <No data fields>},
_vptr.FunctionDispatcher = 0x7f6f9c485d50 <vtable for WTF::RunLoop+16>}, m_functionQueueLock = {m_mutex = {__data = {__lock = 0, __count = 0,
__owner = 0, __nusers = 0, __kind = 512, __spins = 0,
__elision = 0, __list = {__prev = 0x0, __next = 0x0}},
__size = '\000' <repeats 17 times>, "\002", '\000' <repeats 21 times>, __align = 0}}, m_functionQueue = {m_start = 6, m_end = 7,
m_buffer = {<WTF::VectorBufferBase<std::function<void()> >> = {
m_buffer = 0x7f6f6d7f8000, m_capacity = 21,
m_size = 0}, <No data fields>}, m_iterators = 0x0},
m_runLoopContext = {m_ptr = 0x641550},
m_runLoopMainLoops = {<WTF::VectorBuffer<WTF::GRefPtr<_GMainLoop>, 0ul>> = {<WTF::VectorBufferBase<WTF::GRefPtr<_GMainLoop> >> = {
m_buffer = 0x7f6f6dffc180, m_capacity = 16,
m_size = 1}, <No data fields>}, <No data fields>}}
innermostLoop = 0xaa2f20
nestedMainLoop = 0x7ec6b0
#34 0x00007f6f972f90c4 in WebKit::ChildProcessMain<WebKit::WebProcess, WebKit::WebProcessMain> (argc=2, argv=0x7fff80426358)
at ../../Source/WebKit2/Shared/unix/ChildProcessMain.h:61
childMain = {<WebKit::ChildProcessMainBase> = {
_vptr.ChildProcessMainBase = 0x7f6f9c2eed30 <vtable for WebKit::WebProcessMain+16>, m_parameters = {uiProcessName = {m_impl = {m_ptr = 0x0}},
clientIdentifier = {m_impl = {m_ptr = 0x0}},
connectionIdentifier = 26, extraInitializationData = {m_impl = {
static m_maxLoad = <optimized out>,
static m_minLoad = <optimized out>, m_table = 0x0,
m_tableSize = 0, m_tableSizeMask = 0, m_keyCount = 0,
m_deletedCount = 0, m_iterators = 0x0,
m_mutex = std::unique_ptr<std::mutex> containing 0x61b8e0}}}}, <No data fields>}
#35 0x00007f6f972f8f2f in WebKit::WebProcessMainUnix (argc=2,
argv=0x7fff80426358)
at ../../Source/WebKit2/WebProcess/gtk/WebProcessMainGtk.cpp:77
No locals.
#36 0x0000000000400c0a in main (argc=2, argv=0x7fff80426358)
at ../../Source/WebKit2/WebProcess/EntryPoint/unix/WebProcessMain.cpp:44
No locals.
Attachments | ||
---|---|---|
Add attachment proposed patch, testcase, etc. |
Carlos Garcia Campos
(In reply to comment #0)
> r180214 seems to have introduced a crash when closing epiphany. I need to
> debug this further but my guess at this point is that in
> DOMObjectCacheFrameObserver::frameDestroyed, the call to
> domObjectCacheFrameObservers().remove(frame) causes the destruction of the
> DOMObjectCacheFrameObserver, which is bad because
> WebCore::FrameDestructionObserver's destructor calls
> m_frame->removeDestructionObserver, resulting in
> WebCore::Frame::m_destructionObservers changing size while it is being
> iterated through in WebCore::Frame's destructor. That's probably illegal.
>
The crash happens when Frame::willDetachPage() iterates the observers, so at that point frameDestroyed() hasn't been called at all, it's called in ~Frame. When the frame is destroyed we call the parent FrameDestructionObserver::frameDestroyed() that sets m_frame to nullptr, so when the DOMObjectCacheFrameObserver is deleted, the destructor doesn't call m_frame->removeDestructionObserver() because m_frame is already nullptr. That's why things happen in that order, and the reason why we save the m_frame pointer before calling FrameDestructionObserver::frameDestroyed(). So, unless something really weird is happening, it must be something else.
Michael Catanzaro
You are right. I think I somehow switched from looking at the iteration over the observer list in Frame::willDetatchPage() to the one in the destructor and never looked back. Silly...
Michael Catanzaro
I am not seeing this crash anymore, and it used to happen 100%, so I think it's obsolete.
Michael Catanzaro
*** This bug has been marked as a duplicate of bug 144508 ***