Assertion failure: mOuter, at src/dom/serviceworkers/RemoteServiceWorkerRegistrationImpl.cpp:46
Categories
(Core :: DOM: Service Workers, defect, P2)
Tracking
()
People
(Reporter: tsmith, Assigned: sg)
References
(Blocks 2 open bugs)
Details
(Keywords: assertion, testcase)
Attachments
(2 files)
343 bytes,
text/html
|
Details | |
47 bytes,
text/x-phabricator-request
|
pascalc
:
approval-mozilla-beta+
|
Details | Review |
Reduced with m-c 20200120-59873ee30955
Assertion failure: mOuter, at src/dom/serviceworkers/RemoteServiceWorkerRegistrationImpl.cpp:46
0|0|libxul.so|mozilla::dom::RemoteServiceWorkerRegistrationImpl::ClearServiceWorkerRegistration(mozilla::dom::ServiceWorkerRegistration*)|hg:hg.mozilla.org/mozilla-central:dom/serviceworkers/RemoteServiceWorkerRegistrationImpl.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|47|0x2e
0|1|libxul.so|mozilla::dom::ServiceWorkerRegistration::~ServiceWorkerRegistration()|hg:hg.mozilla.org/mozilla-central:dom/serviceworkers/ServiceWorkerRegistration.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|58|0x1a
0|2|libxul.so|mozilla::dom::ServiceWorkerRegistration::~ServiceWorkerRegistration()|hg:hg.mozilla.org/mozilla-central:dom/serviceworkers/ServiceWorkerRegistration.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|59|0x5
0|3|libxul.so|SnowWhiteKiller::MaybeKillObject(SnowWhiteKiller::SnowWhiteObject&)|hg:hg.mozilla.org/mozilla-central:xpcom/base/nsCycleCollector.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|2430|0xd
0|4|libxul.so|SnowWhiteKiller::~SnowWhiteKiller()|hg:hg.mozilla.org/mozilla-central:xpcom/base/nsCycleCollector.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|2417|0xb
0|5|libxul.so|nsCycleCollector::FreeSnowWhite(bool)|hg:hg.mozilla.org/mozilla-central:xpcom/base/nsCycleCollector.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|2592|0x7d
0|6|libxul.so|nsCycleCollector::BeginCollection(ccType, nsICycleCollectorListener*)|hg:hg.mozilla.org/mozilla-central:xpcom/base/nsCycleCollector.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|3585|0xd
0|7|libxul.so|nsCycleCollector::Collect(ccType, js::SliceBudget&, nsICycleCollectorListener*, bool)|hg:hg.mozilla.org/mozilla-central:xpcom/base/nsCycleCollector.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|3372|0xf7
0|8|libxul.so|nsCycleCollector_collect(nsICycleCollectorListener*)|hg:hg.mozilla.org/mozilla-central:xpcom/base/nsCycleCollector.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|3914|0x1f
0|9|libxul.so|nsJSContext::CycleCollectNow(nsICycleCollectorListener*)|hg:hg.mozilla.org/mozilla-central:dom/base/nsJSEnvironment.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|1527|0x4a
0|10|libxul.so|mozilla::dom::FuzzingFunctions_Binding::cycleCollect|s3:gecko-generated-sources:ade1d1fcbb7347c0c612954467004c6479f65bb4b7351b55fc52ad70dc01544001d53ee1cf16df2eeaad7e2912e5250f2d68801bdabea84510cbf44ec6401ea0/dom/bindings/FuzzingFunctionsBinding.cpp:|67|0x8
0|11|libxul.so|CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), js::CallReason, JS::CallArgs const&)|hg:hg.mozilla.org/mozilla-central:js/src/vm/Interpreter.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|452|0x19
0|12|libxul.so|js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason)|hg:hg.mozilla.org/mozilla-central:js/src/vm/Interpreter.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|544|0x12
0|13|libxul.so|InternalCall|hg:hg.mozilla.org/mozilla-central:js/src/vm/Interpreter.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|608|0x10
0|14|libxul.so|Interpret|hg:hg.mozilla.org/mozilla-central:js/src/vm/Interpreter.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|612|0x18
0|15|libxul.so|js::RunScript(JSContext*, js::RunState&)|hg:hg.mozilla.org/mozilla-central:js/src/vm/Interpreter.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|388|0xfe
0|16|libxul.so|js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason)|hg:hg.mozilla.org/mozilla-central:js/src/vm/Interpreter.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|580|0xf
0|17|libxul.so|InternalCall|hg:hg.mozilla.org/mozilla-central:js/src/vm/Interpreter.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|608|0x10
0|18|libxul.so|js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason)|hg:hg.mozilla.org/mozilla-central:js/src/vm/Interpreter.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|625|0x8
0|19|libxul.so|JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>)|hg:hg.mozilla.org/mozilla-central:js/src/jsapi.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|2787|0x1f
0|20|libxul.so|mozilla::dom::EventListener::HandleEvent(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, mozilla::ErrorResult&)|s3:gecko-generated-sources:9ca8646d8042e9b4b76d2e1b358b984be17743b71b832c0897d61bb500e0fecbe38fa54273dc522878c87fcb2c9bfd274a8190c7bc56fbbb58cb3ca68462e527/dom/bindings/EventListenerBinding.cpp:|52|0x5
0|21|libxul.so|mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*)|s3:gecko-generated-sources:f3d9c01258576daaac3afc4fb3b283652e7f1168abb5287eff6775451ebd0ab6a0e4c8d88d3a67f7147042501bc091c6dfed25b4b8ccf4e4f420897b8d0ba906/dist/include/mozilla/dom/EventListenerBinding.h:|66|0x1c
0|22|libxul.so|mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*, bool)|hg:hg.mozilla.org/mozilla-central:dom/events/EventListenerManager.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|1271|0x1c
0|23|libxul.so|mozilla::EventTargetChainItem::HandleEvent(mozilla::EventChainPostVisitor&, mozilla::ELMCreationDetector&)|hg:hg.mozilla.org/mozilla-central:dom/events/EventDispatcher.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|326|0x6b
0|24|libxul.so|mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&)|hg:hg.mozilla.org/mozilla-central:dom/events/EventDispatcher.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|558|0x12
0|25|libxul.so|mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*)|hg:hg.mozilla.org/mozilla-central:dom/events/EventDispatcher.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|1056|0x1a
0|26|libxul.so|mozilla::EventDispatcher::DispatchDOMEvent(nsISupports*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsPresContext*, nsEventStatus*)|hg:hg.mozilla.org/mozilla-central:dom/events/EventDispatcher.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|1161|0x16
0|27|libxul.so|mozilla::DOMEventTargetHelper::DispatchEvent(mozilla::dom::Event&, mozilla::dom::CallerType, mozilla::ErrorResult&)|hg:hg.mozilla.org/mozilla-central:dom/events/DOMEventTargetHelper.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|169|0x5
0|28|libxul.so|mozilla::dom::EventTarget::DispatchEvent(mozilla::dom::Event&, mozilla::ErrorResult&)|hg:hg.mozilla.org/mozilla-central:dom/events/EventTarget.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|184|0x34
0|29|libxul.so|mozilla::DOMEventTargetHelper::DispatchTrustedEvent(mozilla::dom::Event*)|hg:hg.mozilla.org/mozilla-central:dom/events/DOMEventTargetHelper.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|190|0xe
0|30|libxul.so|mozilla::DOMEventTargetHelper::DispatchTrustedEvent(nsTSubstring<char16_t> const&)|hg:hg.mozilla.org/mozilla-central:dom/events/DOMEventTargetHelper.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|183|0xc
0|31|libxul.so|mozilla::dom::ServiceWorker::MaybeDispatchStateChangeEvent()|hg:hg.mozilla.org/mozilla-central:dom/serviceworkers/ServiceWorker.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|156|0x9
0|32|libxul.so|mozilla::dom::ServiceWorkerRegistration::UpdateStateInternal(mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> const&, mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> const&, mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> const&)::{lambda()#1}::operator()() const|||0xc3
0|33|libxul.so|mozilla::dom::ServiceWorkerRegistration::UpdateStateInternal(mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> const&, mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> const&, mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> const&)|hg:hg.mozilla.org/mozilla-central:mfbt/ScopeExit.h:59873ee30955167ac1c6cc1eaafcbeda834ef74d|108|0x8
0|34|libxul.so|mozilla::dom::ServiceWorkerRegistration::UpdateState(mozilla::dom::ServiceWorkerRegistrationDescriptor const&)|hg:hg.mozilla.org/mozilla-central:dom/serviceworkers/ServiceWorkerRegistration.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|154|0x16
0|35|libxul.so|mozilla::dom::ServiceWorkerRegistration::ServiceWorkerRegistration(nsIGlobalObject*, mozilla::dom::ServiceWorkerRegistrationDescriptor const&, mozilla::dom::ServiceWorkerRegistration::Inner*)|hg:hg.mozilla.org/mozilla-central:dom/serviceworkers/ServiceWorkerRegistration.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|53|0xb
0|36|libxul.so|mozilla::dom::ServiceWorkerRegistration::CreateForMainThread(nsPIDOMWindowInner*, mozilla::dom::ServiceWorkerRegistrationDescriptor const&)|hg:hg.mozilla.org/mozilla-central:dom/serviceworkers/ServiceWorkerRegistration.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|83|0x32
0|37|libxul.so|nsGlobalWindowInner::GetOrCreateServiceWorkerRegistration(mozilla::dom::ServiceWorkerRegistrationDescriptor const&)|hg:hg.mozilla.org/mozilla-central:dom/base/nsGlobalWindowInner.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|5515|0xf
0|38|libxul.so|std::_Function_handler<void(const mozilla::dom::ServiceWorkerRegistrationDescriptor&), mozilla::dom::ServiceWorkerContainer::Register(const nsAString&, const mozilla::dom::RegistrationOptions&, mozilla::ErrorResult&)::<lambda(const mozilla::dom::ServiceWorkerRegistrationDescriptor&)> >::_M_invoke|/builds/worker/fetches/gcc/include/c++/8.3.0/bits/std_function.h|297|0x64
0|39|libxul.so|std::_Function_handler<void(mozilla::dom::IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult&&), mozilla::dom::RemoteServiceWorkerContainerImpl::Register(const mozilla::dom::ClientInfo&, const nsACString&, const nsACString&, mozilla::dom::ServiceWorkerUpdateViaCache, mozilla::dom::ServiceWorkerRegistrationCallback&&, mozilla::dom::ServiceWorkerFailureCallback&&) const::<lambda(const mozilla::dom::IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult&)> >::_M_invoke|/builds/worker/fetches/gcc/include/c++/8.3.0/bits/std_function.h|297|0x97
0|40|libxul.so|mozilla::dom::PServiceWorkerContainerChild::OnMessageReceived(IPC::Message const&)|hg:hg.mozilla.org/mozilla-central:ipc/glue/MessageChannel.h:59873ee30955167ac1c6cc1eaafcbeda834ef74d|131|0xc
0|41|libxul.so|mozilla::ipc::PBackgroundChild::OnMessageReceived(IPC::Message const&)|s3:gecko-generated-sources:2c00c6e8fe94c4488d1fca390aff0552cb4c3ce40484b98f953b8e69d8f06e217c2149c17ee88489855e4d63a022e5bc503c37aacdd686847caea60851863176/ipc/ipdl/PBackgroundChild.cpp:|5806|0xd
0|42|libxul.so|mozilla::ipc::MessageChannel::DispatchAsyncMessage(mozilla::ipc::ActorLifecycleProxy*, IPC::Message const&)|hg:hg.mozilla.org/mozilla-central:ipc/glue/MessageChannel.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|2212|0x6
0|43|libxul.so|mozilla::ipc::MessageChannel::DispatchMessage(IPC::Message&&)|hg:hg.mozilla.org/mozilla-central:ipc/glue/MessageChannel.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|2134|0xb
0|44|libxul.so|mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::MessageChannel::MessageTask&)|hg:hg.mozilla.org/mozilla-central:ipc/glue/MessageChannel.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|1973|0xb
0|45|libxul.so|mozilla::ipc::MessageChannel::MessageTask::Run()|hg:hg.mozilla.org/mozilla-central:ipc/glue/MessageChannel.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|2004|0xc
0|46|libxul.so|nsThread::ProcessNextEvent(bool, bool*)|hg:hg.mozilla.org/mozilla-central:xpcom/threads/nsThread.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|1220|0xe
0|47|libxul.so|NS_ProcessNextEvent(nsIThread*, bool)|hg:hg.mozilla.org/mozilla-central:xpcom/threads/nsThreadUtils.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|486|0x11
0|48|libxul.so|mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*)|hg:hg.mozilla.org/mozilla-central:ipc/glue/MessagePump.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|87|0xa
0|49|libxul.so|MessageLoop::RunInternal()|hg:hg.mozilla.org/mozilla-central:ipc/chromium/src/base/message_loop.cc:59873ee30955167ac1c6cc1eaafcbeda834ef74d|315|0x19
0|50|libxul.so|MessageLoop::Run()|hg:hg.mozilla.org/mozilla-central:ipc/chromium/src/base/message_loop.cc:59873ee30955167ac1c6cc1eaafcbeda834ef74d|290|0x8
0|51|libxul.so|nsBaseAppShell::Run()|hg:hg.mozilla.org/mozilla-central:widget/nsBaseAppShell.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|137|0xd
0|52|libxul.so|nsAppStartup::Run()|hg:hg.mozilla.org/mozilla-central:toolkit/components/startup/nsAppStartup.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|272|0x10
0|53|libxul.so|XREMain::XRE_mainRun()|hg:hg.mozilla.org/mozilla-central:toolkit/xre/nsAppRunner.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|4603|0x16
0|54|libxul.so|XREMain::XRE_main(int, char**, mozilla::BootstrapConfig const&)|hg:hg.mozilla.org/mozilla-central:toolkit/xre/nsAppRunner.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|4740|0x8
0|55|libxul.so|XRE_main(int, char**, mozilla::BootstrapConfig const&)|hg:hg.mozilla.org/mozilla-central:toolkit/xre/nsAppRunner.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|4821|0x5
0|56|firefox-bin|do_main|hg:hg.mozilla.org/mozilla-central:browser/app/nsBrowserApp.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|217|0x26
0|57|firefox-bin|main|hg:hg.mozilla.org/mozilla-central:browser/app/nsBrowserApp.cpp:59873ee30955167ac1c6cc1eaafcbeda834ef74d|339|0xf
0|58|libc-2.23.so|__libc_start_main|/build/glibc-LK5gWL/glibc-2.23/csu/../csu/libc-start.c|291|0x1a
0|59|firefox-bin|_start|||0x29
Reporter | ||
Comment 1•5 years ago
|
||
This test case requires a fuzzing debug build with fuzzing.enabled=true
and it must be served from a webserver. Also an empty file name empty.js
must be placed next to testcase.html.
Comment 2•5 years ago
|
||
Hi Tyson, would it be possible to get a pernosco session for this? Thank you!
Updated•5 years ago
|
Reporter | ||
Comment 3•5 years ago
|
||
A Pernosco session is available here: https://pernos.co/debug/YSBLDAzomHMR6D6JYDxbPQ/index.html
Comment 4•5 years ago
•
|
||
Interesting. The following is happening all on the same thread 1616 / stack trace:
- We want to register a new service worker. (ServiceWorkerContainer.cpp:390 — global->GetOrCreateServiceWorkerRegistration(aDesc);)
- The construction of the RemoteServiceWorkerRegistrationImpl initializes mOuter = nullptr.
- We dispatch the state "activated". (ServiceWorker.cpp:156 — DOMEventTargetHelper::DispatchTrustedEvent(NS_LITERAL_STRING("statechange"));)
- During dispatch, we call the cycle collector (I assume, this can happen randomly on any event dispatching). (nsJSEnvironment.cpp:1535 — nsCycleCollector_collect(aListener);)
- The cycle collector recognizes the ServiceWorkerRegistration we are coming from as dangling and destroys it (ServiceWorkerRegistration.cpp:57 — ServiceWorkerRegistration::~ServiceWorkerRegistration)
- The deconstruction of ServiceWorkerRegistration wants to clear a never set inner registration and fails. (RemoteServiceWorkerRegistrationImpl::ClearServiceWorkerRegistration)
I assume, that it is not wanted that ServiceWorkerRegistration is being destroyed by the cycle collector during the ongoing registration process. So probably we want to prevent this.
I am also wondering, if it is in general a good idea to let the cycle collector allow to run during a synchronous event dispatching? Or is this part of the fuzzing logic in order to provoke more failures?
Comment 5•5 years ago
|
||
I assume, the problem lies here:
RefPtr<ServiceWorkerRegistration> reg =
global->GetOrCreateServiceWorkerRegistration(aDesc);
In fact, the call to GetOrCreateServiceWorkerRegistration(aDesc)
does many things (lasts long), among them it may create a new ServiceWorkerRegistration
instance. This instance is never assigned to the RefPtr<ServiceWorkerRegistration> reg
until the call returns and thus dangling from the point of view of the cycle collector for quite some time. We probably need to seperate the logic that decides if we need to allocate a new SeviceWorkerRegistration
instance from all the subsequent registration logic (in particular the dispatching of events).
In alternative, we might want to ensure the survival of ServiceWorkerRegistration
through the use of NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN
/...END
. If I understand right, we could implement some logic that detects, that we are on a new, not yet fully registered instance there.
Updated•5 years ago
|
Updated•5 years ago
|
Comment 6•5 years ago
|
||
How reproducible is this? I let the test case run a few minutes on my fuzzing build, but no crashes so far.
Updated•5 years ago
|
Comment 7•5 years ago
|
||
ServiceWorkerRegistration::UpdateState can call content code, which
in turn can result in the registrations getting deleted. This
commit moves the call outside the constructor, so the
registration's creator has a chance to get a proper RefPtr to it.
Comment 8•5 years ago
|
||
:sgiesecke assigning to you for landing support
Updated•5 years ago
|
Comment 10•5 years ago
|
||
bugherder |
Assignee | ||
Comment 12•5 years ago
|
||
Comment on attachment 9124516 [details]
Bug 1610692 - Move call that can run content code out of constructor. r=#dom-workers-and-storage-reviewers
Beta/Release Uplift Approval Request
- User impact if declined: Exposure to undefined behaviour/content process crashes depending on content code executed in service worker registration event handlers (if it triggers a cycle collection).
- Is this code covered by automated tests?: No
- Has the fix been verified in Nightly?: Yes
- Needs manual test from QE?: No
- If yes, steps to reproduce: Unfortunately, no test case reproducible without a fuzzing build is available.
- List of other uplifts needed: None
- Risk to taking this patch: Low
- Why is the change risky/not risky? (and alternatives if risky): The code dispatching the event is only slightly moved from within the ServiceWorkerRegistration constructor to its call sites, which ensures there is a strong reference held to the registration, and it can't be destroyed before being returned to caller.
- String changes made/needed:
Assignee | ||
Comment 13•5 years ago
|
||
(In reply to Julien Cristau [:jcristau] from comment #11)
Should we uplift this to beta?
Yes, makes sense. I requested uplift. Thanks for pointing this out!
Comment 14•5 years ago
|
||
Comment on attachment 9124516 [details]
Bug 1610692 - Move call that can run content code out of constructor. r=#dom-workers-and-storage-reviewers
Low risk, uplift approved for 74.0b8, thanks.
Comment 15•5 years ago
|
||
bugherder uplift |
Updated•5 years ago
|
Description
•