Closed Bug 1428253 Opened 2 years ago Closed 2 years ago

browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js | application crashed [@ MOZ_CrashOOL] maybe after bug 1193394

Categories

(Firefox :: General, defect, P3)

defect

Tracking

()

RESOLVED FIXED
Firefox 59
Tracking Status
firefox59 --- fixed

People

(Reporter: arai, Assigned: bevis)

References

Details

Attachments

(1 file)

https://treeherder.mozilla.org/#/jobs?repo=try&revision=caddd5487d746816bb03fe7c691f5e8d03164cbc&filter-searchStr=bc&filter-resultStatus=testfailed&filter-resultStatus=busted&filter-resultStatus=exception&filter-resultStatus=retry&filter-resultStatus=usercancel&filter-resultStatus=running&filter-resultStatus=pending&filter-resultStatus=runnable&selectedJob=153764906
> TEST-UNEXPECTED-FAIL | browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js | application terminated with exit code 1
> runtests.py | Application ran for: 0:01:13.557182
> zombiecheck | Reading PID log: /var/folders/hr/8c2s8g055snd0_g68pb0fq6800000w/T/tmp1ZFjG2pidlog
> ==> process 2063 launched child process 2064
> ==> process 2063 launched child process 2065
> ==> process 2063 launched child process 2066
> ==> process 2063 launched child process 2067
> zombiecheck | Checking for orphan process with PID: 2064
> zombiecheck | Checking for orphan process with PID: 2065
> zombiecheck | Checking for orphan process with PID: 2066
> zombiecheck | Checking for orphan process with PID: 2067
> mozcrash Downloading symbols from: https://queue.taskcluster.net/v1/task/ZjAlHNLsRrCLBVrYBCv2dQ/artifacts/public/build/target.crashreporter-symbols.zip
> mozcrash Copy/paste: /Users/cltbld/tasks/task_1514897694/build/macosx64-minidump_stackwalk /var/folders/hr/8c2s8g055snd0_g68pb0fq6800000w/T/tmpL9jFss.mozrunner/minidumps/A534EC9A-86BD-46A5-B6F7-6A2C924112CC.dmp /var/folders/hr/8c2s8g055snd0_g68pb0fq6800000w/T/tmpqtpP5N
> mozcrash Saved minidump as /Users/cltbld/tasks/task_1514897694/build/blobber_upload_dir/A534EC9A-86BD-46A5-B6F7-6A2C924112CC.dmp
> mozcrash Saved app info as /Users/cltbld/tasks/task_1514897694/build/blobber_upload_dir/A534EC9A-86BD-46A5-B6F7-6A2C924112CC.extra
> PROCESS-CRASH | browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js | application crashed [@ MOZ_CrashOOL]
> Crash dump filename: /var/folders/hr/8c2s8g055snd0_g68pb0fq6800000w/T/tmpL9jFss.mozrunner/minidumps/A534EC9A-86BD-46A5-B6F7-6A2C924112CC.dmp
> Operating system: Mac OS X
>                   10.10.5 14F27
> CPU: amd64
>      family 6 model 69 stepping 1
>      4 CPUs
> 
> GPU: UNKNOWN
> 
> Crash reason:  EXC_BAD_ACCESS / KERN_INVALID_ADDRESS
> Crash address: 0x0
> Process uptime: 72 seconds
> 
> Thread 61 (crashed)
>  0  libmozglue.dylib!MOZ_CrashOOL [Assertions.cpp:caddd5487d74 : 33 + 0x0]
>     rax = 0x0000000119a36900   rdx = 0x0000000000000000
>     rcx = 0x0000000000000000   rbx = 0x000000011c241478
>     rsi = 0x0000000119a36900   rdi = 0x000000000000088d
>     rbp = 0x0000000112786e00   rsp = 0x0000000112786e00
>      r8 = 0x0000000119a36900    r9 = 0x0000000000000005
>     r10 = 0x0000000000001090   r11 = 0x0000000107fd4b00
>     r12 = 0x0000000112786e38   r13 = 0x000000011c241430
>     r14 = 0x0000000000000005   r15 = 0x000000010cb34b50
>     rip = 0x0000000107fd4b0b
>     Found by: given as instruction pointer in context
>  1  XUL!mozilla::dom::workers::RuntimeService::CrashIfHanging() [RuntimeService.cpp:caddd5487d74 : 2189 + 0x12]
>     rbx = 0x000000011c241478   rbp = 0x0000000112786ea0
>     rsp = 0x0000000112786e10   r12 = 0x0000000112786e38
>     r13 = 0x000000011c241430   r14 = 0x0000000000000005
>     r15 = 0x000000010cb34b50   rip = 0x000000010a56e78d
>     Found by: call frame info
>  2  XUL!mozilla::(anonymous namespace)::RunWatchdog(void*) [nsTerminator.cpp:caddd5487d74 : 162 + 0x8]
>     rbx = 0x000000000000003f   rbp = 0x0000000112786ec0
>     rsp = 0x0000000112786eb0   r12 = 0x000000000000e507
>     r13 = 0x00000000000008ff   r14 = 0x0000000119a0ab90
>     r15 = 0x0000000000000001   rip = 0x000000010bbc7bed
>     Found by: call frame info
>  3  libnss3.dylib!_pt_root [ptthread.c:caddd5487d74 : 201 + 0x3]
>     rbx = 0x000000010826b970   rbp = 0x0000000112786ef0
>     rsp = 0x0000000112786ed0   r12 = 0x000000000000e507
>     r13 = 0x00000000000008ff   r14 = 0x0000000112787000
>     r15 = 0x0000000000000001   rip = 0x0000000108443cf3
>     Found by: call frame info
>  4  libsystem_pthread.dylib!_pthread_body + 0x83
>     rbx = 0x0000000112787000   rbp = 0x0000000112786f10
>     rsp = 0x0000000112786f00   r12 = 0x000000000000e507
>     r13 = 0x00000000000008ff   r14 = 0x000000010826b970
>     r15 = 0x0000000108443c20   rip = 0x00007fff8154305a
>     Found by: call frame info
>  5  libsystem_pthread.dylib!_pthread_start + 0xb0
>     rbp = 0x0000000112786f50   rsp = 0x0000000112786f20
>     rip = 0x00007fff81542fd7
>     Found by: previous frame's frame pointer
>  6  libsystem_pthread.dylib!thread_start + 0xd
>     rbp = 0x0000000112786f78   rsp = 0x0000000112786f60
>     rip = 0x00007fff815403ed
>     Found by: previous frame's frame pointer
>  7  libnss3.dylib + 0x143c20
>     rsp = 0x0000000112787030   rip = 0x0000000108443c20
>     Found by: stack scanning

I'm not sure whether this is new failure or not, but this crash is happening across almost all platforms and configurations, intermittently.
at least, I don't see any other bug filed for browser_openPromptInBackgroundTab.js
froydnj, can you give me some hint where to look into, for this kind of crash?
Flags: needinfo?(nfroyd)
(In reply to Tooru Fujisawa [:arai] from comment #2)
> froydnj, can you give me some hint where to look into, for this kind of
> crash?

The crashing thread is in dom/workers/RuntimeService.cpp:

https://searchfox.org/mozilla-central/source/dom/workers/RuntimeService.cpp#2141

Therefore, some other thread is doing *something* without yielding to the event loop; you want to look for some other thread that appears to be doing useful work (i.e. not waiting on a condition variable).  But all the other threads appear to be waiting!  So I'm not sure what's going wrong here.

baku, do you know why RuntimeService would decide to crash everything like this?
Flags: needinfo?(nfroyd) → needinfo?(amarchesini)
> baku, do you know why RuntimeService would decide to crash everything like
> this?

I have introduced this crash report in order to see why we have shutdown hanging in workers. The crash string shows what keeps the worker alive. This is a "temporary" solution. I'm collecting crash reports in order to come out with a new shutting down approach for workers.
Flags: needinfo?(amarchesini)
thanks :)
so, the issue is that for some reason the process hangups (main thread stops, watchdog keeps alive) while shutting down, after the test finishes,
and the "some reason" may be caused by bug 1193394 change if the issue happens only after the patch is applied, right?

I guess I need to look into the state of the main thread (maybe sShutdownSteps values), which seems to be shutting down (there's DoShutdown in callstack, but stops with processing event queue), and why it stops resetting heartbeat.
here's call stack and relevant code:

https://searchfox.org/mozilla-central/rev/0a895028f74cffa67561150d10700abca8a931d8/toolkit/xre/nsAppRunner.cpp#1502
> ScopedXPCOMStartup::~ScopedXPCOMStartup()
> {
> ...
>   if (mServiceManager) {
> ...
>     gDirServiceProvider->DoShutdown();

https://searchfox.org/mozilla-central/rev/0a895028f74cffa67561150d10700abca8a931d8/toolkit/xre/nsXREDirProvider.cpp#1087-1099
> nsXREDirProvider::DoShutdown()
> {
> ...
>   if (mProfileNotified) {
> ...
>     if (obsSvc) {
> ...
>       static const char16_t kShutdownPersist[] = u"shutdown-persist";
>       obsSvc->NotifyObservers(nullptr, "profile-change-net-teardown", kShutdownPersist);
>       obsSvc->NotifyObservers(nullptr, "profile-change-teardown", kShutdownPersist);
> ...
>       obsSvc->NotifyObservers(nullptr, "profile-before-change", kShutdownPersist);
>       obsSvc->NotifyObservers(nullptr, "profile-before-change-qm", kShutdownPersist);
>       obsSvc->NotifyObservers(nullptr, "profile-before-change-telemetry", kShutdownPersist);

https://searchfox.org/mozilla-central/rev/0a895028f74cffa67561150d10700abca8a931d8/xpcom/ds/nsObserverList.cpp#112
> nsObserverList::NotifyObservers(nsISupports* aSubject,
>                                 const char* aTopic,
>                                 const char16_t* someData)
> {
> ...
>   for (int32_t i = 0; i < observers.Count(); ++i) {
>     observers[i]->Observe(aSubject, aTopic, someData);

https://searchfox.org/mozilla-central/rev/0a895028f74cffa67561150d10700abca8a931d8/dom/ipc/ContentParent.cpp#2763
> ContentParent::Observe(nsISupports* aSubject,
>                        const char* aTopic,
>                        const char16_t* aData)
> {
>   if (mSubprocess && (!strcmp(aTopic, "profile-before-change") ||
>                       !strcmp(aTopic, "xpcom-shutdown"))) {
>     // Okay to call ShutDownProcess multiple times.
>     ShutDownProcess(SEND_SHUTDOWN_MESSAGE);
> 
>     // Wait for shutdown to complete, so that we receive any shutdown
>     // data (e.g. telemetry) from the child before we quit.
>     // This loop terminate prematurely based on mForceKillTimer.
>     SpinEventLoopUntil([&]() { return !mIPCOpen || mCalledKillHard; });

https://searchfox.org/mozilla-central/rev/0a895028f74cffa67561150d10700abca8a931d8/xpcom/threads/nsThreadUtils.h#323
> SpinEventLoopUntil(Pred&& aPredicate, nsIThread* aThread = nullptr)
> {
>   nsIThread* thread = aThread ? aThread : NS_GetCurrentThread();
> 
>   while (!aPredicate()) {
>     bool didSomething = NS_ProcessNextEvent(thread, true);
> 
>     if (Behavior == ProcessFailureBehavior::IgnoreAndContinue) {
>       // Don't care what happened, continue on.
>       continue;
>     } else if (!didSomething) {
>       return false;
>     }
>   }

https://searchfox.org/mozilla-central/rev/0a895028f74cffa67561150d10700abca8a931d8/xpcom/threads/nsThreadUtils.cpp#517
> NS_ProcessNextEvent(nsIThread* aThread, bool aMayWait)
> {
> ...
>   return NS_SUCCEEDED(aThread->ProcessNextEvent(aMayWait, &val)) && val;

https://searchfox.org/mozilla-central/rev/0a895028f74cffa67561150d10700abca8a931d8/xpcom/threads/nsThread.cpp#967
> nsThread::ProcessNextEvent(bool aMayWait, bool* aResult)
> {
> ...
>  // The toplevel event loop normally blocks waiting for the next event, but
>  // if we're trying to shut this thread down, we must exit the event loop when
>  // the event queue is empty.
>  // This only applys to the toplevel event loop! Nested event loops (e.g.
>  // during sync dispatch) are waiting for some state change and must be able
>  // to block even if something has requested shutdown of the thread. Otherwise
>  // we'll just busywait as we endlessly look for an event, fail to find one,
>  // and repeat the nested event loop since its state change hasn't happened yet.
>  bool reallyWait = aMayWait && (mNestedEventLoopDepth > 0 || !ShuttingDown());
> ...
>   {
>     // Scope for |event| to make sure that its destructor fires while
>     // mNestedEventLoopDepth has been incremented, since that destructor can
>     // also do work.
>     EventPriority priority;
>     nsCOMPtr<nsIRunnable> event = mEvents->GetEvent(reallyWait, &priority);

https://searchfox.org/mozilla-central/rev/0a895028f74cffa67561150d10700abca8a931d8/xpcom/threads/ThreadEventQueue.cpp#139
> ThreadEventQueue<InnerQueueT>::GetEvent(bool aMayWait,
>                                         EventPriority* aPriority)
> {
>   MutexAutoLock lock(mLock);
> 
>   nsCOMPtr<nsIRunnable> event;
>   for (;;) {
>     if (mNestedQueues.IsEmpty()) {
>       event = mBaseQueue->GetEvent(aPriority, lock);
>     } else {
>       // We always get events from the topmost queue when there are nested
>       // queues.
>       event = mNestedQueues.LastElement().mQueue->GetEvent(aPriority, lock);
>     }
> 
>     if (event || !aMayWait) {
>       break;
>     }
> 
>     mEventsAvailable.Wait();

so, looks like `!mIPCOpen || mCalledKillHard` condition doesn't become true, or maybe some issue around that.
I'll check the difference between the successful case and failure case, around updating the flag.
so far
  1. the issue happens while notifying profile-before-change
  2. on successful case, ContentParent::ActorDestroy is called 4 times (I think the number of content process), for each SpinEventLoopUntil call
  3. on failure case, one of them is not called and the shutdown progress stops there

maybe, one of content processes somehow stops?
another try with some more logging for shutting down
https://treeherder.mozilla.org/#/jobs?repo=try&revision=cb75dd04b48e1ef3f56683ad812995b12ed957d8
(I don't see ContentChild methods in backtraces tho)

the strange thing is that, the crash happens on all platform, almost all build configuration on try, but I cannot reproduce locally with macOS and linux :/
I wonder what the difference is...
for problematic content process, ContentChild::RecvShutdown every time enters the following branch,
while it's called multiple times (maybe ~5 times per second?).

https://searchfox.org/mozilla-central/rev/0a895028f74cffa67561150d10700abca8a931d8/dom/ipc/ContentChild.cpp#2960-2969
> ContentChild::RecvShutdown()
> {
> ...
>   MOZ_ASSERT(NS_IsMainThread());
>   RefPtr<nsThread> mainThread = nsThreadManager::get().GetCurrentThread();
>   // Note that we only have to check the recursion count for the current
>   // cooperative thread. Since the Shutdown message is not labeled with a
>   // SchedulerGroup, there can be no other cooperative threads doing work while
>   // we're running.
>   if (mainThread && mainThread->RecursionDepth() > 1) {
>     // We're in a nested event loop. Let's delay for an arbitrary period of
>     // time (100ms) in the hopes that the event loop will have finished by
>     // then.
>     MessageLoop::current()->PostDelayedTask(
>       NewRunnableMethod(
>         "dom::ContentChild::RecvShutdown", this, &ContentChild::RecvShutdown),
>       100);
>     return IPC_OK();
>   }

I'll check where that nested event loop is.
another try.
https://treeherder.mozilla.org/#/jobs?repo=try&revision=0c96722697b9c818901162b318ba3a45ae7e3150&group_state=expanded

here's the stack trace for nsThread::ProcessNextEvent just before the first RecvShutdown, where `mainThread->RecursionDepth() > 1`.
apparently there's some alert or confirm shown, and also SpinEventLoopUntil is called from JS (maybe it's test harness).

>  0   XUL                                 0x000000010d98fe56 nsThread::ProcessNextEvent(bool, bool*) + 278
>  1   XUL                                 0x000000010d99987f NS_ProcessNextEvent(nsIThread*, bool) + 47
>  2   XUL                                 0x000000010d991e9c nsThreadManager::SpinEventLoopUntil(nsINestedEventLoopCondition*) + 92
>  3   XUL                                 0x000000010d99effe NS_InvokeByIndex + 142
>  4   XUL                                 0x000000010e1fd154 XPCWrappedNative::CallMethod(XPCCallContext&, XPCWrappedNative::CallMode) + 4292
>  5   XUL                                 0x000000010e1fe7bf XPC_WN_CallMethod(JSContext*, unsigned int, JS::Value*) + 479
>  6   XUL                                 0x0000000110fd7b15 js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 565
>  7   XUL                                 0x0000000110fd279f Interpret(JSContext*, js::RunState&) + 32783
>  8   XUL                                 0x0000000110fca60e js::RunScript(JSContext*, js::RunState&) + 382
>  9   XUL                                 0x0000000110fd7cf9 js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 1049
>  10  XUL                                 0x0000000110fd279f Interpret(JSContext*, js::RunState&) + 32783
>  11  XUL                                 0x0000000110fca60e js::RunScript(JSContext*, js::RunState&) + 382
>  12  XUL                                 0x0000000110fd7cf9 js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 1049
>  13  XUL                                 0x0000000110fd8009 js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) + 41
>  14  XUL                                 0x0000000111305e8b JS_CallFunctionValue(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) + 667
>  15  XUL                                 0x000000010e1f599a nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS*, unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) + 3370
>  16  XUL                                 0x000000010d9a034c PrepareAndDispatch + 540
>  17  XUL                                 0x000000010d99f1bb SharedStub + 91
>  18  XUL                                 0x000000010e7f791f nsGlobalWindowOuter::AlertOrConfirm(bool, nsTSubstring<char16_t> const&, nsIPrincipal&, mozilla::ErrorResult&) + 1023
>  19  XUL                                 0x000000010e7dde21 nsGlobalWindowInner::Alert(nsTSubstring<char16_t> const&, nsIPrincipal&, mozilla::ErrorResult&) + 209
>  20  XUL                                 0x000000010ee18c5b mozilla::dom::WindowBinding::alert(JSContext*, JS::Handle<JSObject*>, nsGlobalWindowInner*, JSJitMethodCallArgs const&) + 363
>  21  XUL                                 0x000000010ee1827f mozilla::dom::WindowBinding::genericMethod(JSContext*, unsigned int, JS::Value*) + 447
>  22  XUL                                 0x0000000110fd7b15 js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 565
>  23  XUL                                 0x0000000110fd279f Interpret(JSContext*, js::RunState&) + 32783
>  24  XUL                                 0x0000000110fca60e js::RunScript(JSContext*, js::RunState&) + 382
>  25  XUL                                 0x0000000110fd7cf9 js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 1049
>  26  XUL                                 0x0000000110fd8009 js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) + 41
>  27  XUL                                 0x0000000111306a90 JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) + 688
>  28  XUL                                 0x000000010eed22c6 mozilla::dom::EventListener::HandleEvent(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, mozilla::ErrorResult&) + 710
>  29  XUL                                 0x000000010f1f6ba0 mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, nsIDOMEvent*, mozilla::dom::EventTarget*) + 336
>  30  XUL                                 0x000000010f1f7737 mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent**, mozilla::dom::EventTarget*, nsEventStatus*) + 2759
>  31  XUL                                 0x000000010f1f0bc2 mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) + 450
>  32  XUL                                 0x000000010f1f1cb8 mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) + 2792
>  33  XUL                                 0x000000010f1f22bc mozilla::EventDispatcher::DispatchDOMEvent(nsISupports*, mozilla::WidgetEvent*, nsIDOMEvent*, nsPresContext*, nsEventStatus*) + 268
>  34  XUL                                 0x000000010e91c34a nsINode::DispatchEvent(nsIDOMEvent*, bool*) + 186
>  35  XUL                                 0x000000010e7a6c15 nsContentUtils::DispatchEvent(nsIDocument*, nsISupports*, nsTSubstring<char16_t> const&, bool, bool, bool, bool*, bool) + 181
>  36  XUL                                 0x000000010e7a6b4c nsContentUtils::DispatchTrustedEvent(nsIDocument*, nsISupports*, nsTSubstring<char16_t> const&, bool, bool, bool*) + 28
>  37  XUL                                 0x000000010e8e0bb9 nsDocument::UpdateVisibilityState() + 233
>  38  XUL                                 0x000000010e8f50fc mozilla::detail::RunnableMethodImpl<nsDocument*, void (nsDocument::*)(), true, (mozilla::RunnableKind)0>::Run() + 44
>  39  XUL                                 0x000000010d9825a1 mozilla::SchedulerGroup::Runnable::Run() + 257
>  40  XUL                                 0x000000010d9904af nsThread::ProcessNextEvent(bool, bool*) + 1903
>  41  XUL                                 0x000000010d9997ce NS_ProcessPendingEvents(nsIThread*, unsigned int) + 78
>  42  XUL                                 0x000000010fa63c61 nsBaseAppShell::NativeEventCallback() + 113
>  43  XUL                                 0x000000010fabb566 nsAppShell::ProcessGeckoEvents(void*) + 246
>  44  CoreFoundation                      0x00007fff86a3aa01 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
>  45  CoreFoundation                      0x00007fff86a2cb8d __CFRunLoopDoSources0 + 269
>  46  CoreFoundation                      0x00007fff86a2c1bf __CFRunLoopRun + 927
>  47  CoreFoundation                      0x00007fff86a2bbd8 CFRunLoopRunSpecific + 296
>  48  HIToolbox                           0x00007fff8a62e56f RunCurrentEventLoopInMode + 235
>  49  HIToolbox                           0x00007fff8a62e2ea ReceiveNextEventCommon + 431
>  50  HIToolbox                           0x00007fff8a62e12b _BlockUntilNextEventMatchingListInModeWithFilter + 71
>  51  AppKit                              0x00007fff87a6f8ab _DPSNextEvent + 978
>  52  AppKit                              0x00007fff87a6ee58 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 346
>  53  XUL                                 0x000000010fababe6 -[GeckoNSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 86
>  54  AppKit                              0x00007fff87a64af3 -[NSApplication run] + 594
>  55  XUL                                 0x000000010fabbab9 nsAppShell::Run() + 249
>  56  XUL                                 0x0000000110ec0c6e XRE_RunAppShell() + 270
>  57  XUL                                 0x000000010dde06a9 MessageLoop::Run() + 73
>  58  XUL                                 0x0000000110ec0996 XRE_InitChildProcess(int, char**, XREChildData const*) + 1878
>  59  plugin-container                    0x000000010d5c0ee9 main + 89
>  60  plugin-container                    0x000000010d5c0e84 start + 52

I'll try printing the JS backtrace there to see the actual caller.
another try.
https://treeherder.mozilla.org/#/jobs?repo=try&revision=d57f27012e82eebb31bccc59fd8408c0af5ceed6&selectedJob=154585122

this is the only JS stack trace for nsThreadManager::SpinEventLoopUntil,
that appears in the content process which stops shutting down.
it's called twice.

#0    jar:file:///Users/cltbld/tasks/task_1515265636/build/application/Firefox%20Nightly.app/Contents/Resources/omni.ja!/components/nsPrompter.js:510
#1    jar:file:///Users/cltbld/tasks/task_1515265636/build/application/Firefox%20Nightly.app/Contents/Resources/omni.ja!/components/nsPrompter.js:544
#2    jar:file:///Users/cltbld/tasks/task_1515265636/build/application/Firefox%20Nightly.app/Contents/Resources/omni.ja!/components/nsPrompter.js:617
#3    http://example.com/browser/browser/base/content/test/tabPrompts/openPromptOffTimeout.html:6

so, it's the following line.

https://searchfox.org/mozilla-central/rev/51d4c2d9ce39faec9d74e9597b69d5cc697bd93f/browser/base/content/test/tabPrompts/openPromptOffTimeout.html#6
> document.addEventListener("visibilitychange", () => {
>   if (document.hidden) {
>     alert("You hid my page!");
>   }
> });
https://treeherder.mozilla.org/#/jobs?repo=try&revision=e045e6bcb6e06e18d40b229288aa1921050658fb&group_state=expanded

indeed, the 2nd nsThreadManager::SpinEventLoopUntil call there doesn't return until force shutdown.

also, ContentChild::RecvShutdown is called while the nested nsThread::ProcessNextEvent is on the stack.
hmm, it might be different.
nsThreadManager::SpinEventLoopUntil from openPromptOffTimeout.html doesn't return locally on successful case.
this is the backtrace for the 1st ContentChild::RecvShutdown call,
that is triggered by the message from parent process.

>  0   mozilla::dom::ContentChild::RecvShutdown() + 356
>  1   mozilla::dom::PContentChild::OnMessageReceived(IPC::Message const&) + 30275
>  2   mozilla::ipc::MessageChannel::DispatchAsyncMessage(IPC::Message const&) + 113
>  3   mozilla::ipc::MessageChannel::DispatchMessage(IPC::Message&&) + 330
>  4   mozilla::ipc::MessageChannel::MessageTask::Run() + 78
>  5   nsThread::ProcessNextEvent(bool, bool*) + 2027
>  6   NS_ProcessNextEvent(nsIThread*, bool) + 47
>  7   nsThreadManager::SpinEventLoopUntil(nsINestedEventLoopCondition*) + 236
>  8   NS_InvokeByIndex + 142
>  9   XPCWrappedNative::CallMethod(XPCCallContext&, XPCWrappedNative::CallMode) + 4292
>  10  XPC_WN_CallMethod(JSContext*, unsigned int, JS::Value*) + 479
>  11  js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 565
>  12  Interpret(JSContext*, js::RunState&) + 32783
>  13  js::RunScript(JSContext*, js::RunState&) + 382
>  14  js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 1049
>  15  Interpret(JSContext*, js::RunState&) + 32783
>  16  js::RunScript(JSContext*, js::RunState&) + 382
>  17  js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 1049
>  18  js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) + 41
>  19  JS_CallFunctionValue(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) + 667
>  20  nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS*, unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) + 3370
>  21  PrepareAndDispatch + 540
>  22  SharedStub + 91
>  23  nsGlobalWindowOuter::AlertOrConfirm(bool, nsTSubstring<char16_t> const&, nsIPrincipal&, mozilla::ErrorResult&) + 1023
>  24  nsGlobalWindowInner::Alert(nsTSubstring<char16_t> const&, nsIPrincipal&, mozilla::ErrorResult&) + 209
>  25  mozilla::dom::WindowBinding::alert(JSContext*, JS::Handle<JSObject*>, nsGlobalWindowInner*, JSJitMethodCallArgs const&) + 363
>  26  mozilla::dom::WindowBinding::genericMethod(JSContext*, unsigned int, JS::Value*) + 447
>  27  js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 565
>  28  Interpret(JSContext*, js::RunState&) + 32783
>  29  js::RunScript(JSContext*, js::RunState&) + 382
>  30  js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 1049
>  31  js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) + 41
>  32  JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) + 688
>  33  mozilla::dom::EventListener::HandleEvent(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, mozilla::ErrorResult&) + 710
>  34  mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, nsIDOMEvent*, mozilla::dom::EventTarget*) + 336
>  35  mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent**, mozilla::dom::EventTarget*, nsEventStatus*) + 2759
>  36  mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) + 450
>  37  mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) + 2792
>  38  mozilla::EventDispatcher::DispatchDOMEvent(nsISupports*, mozilla::WidgetEvent*, nsIDOMEvent*, nsPresContext*, nsEventStatus*) + 268
>  39  nsINode::DispatchEvent(nsIDOMEvent*, bool*) + 186
>  40  nsContentUtils::DispatchEvent(nsIDocument*, nsISupports*, nsTSubstring<char16_t> const&, bool, bool, bool, bool*, bool) + 181
>  41  nsContentUtils::DispatchTrustedEvent(nsIDocument*, nsISupports*, nsTSubstring<char16_t> const&, bool, bool, bool*) + 28
>  42  nsDocument::UpdateVisibilityState() + 233
>  43  mozilla::detail::RunnableMethodImpl<nsDocument*, void (nsDocument::*)(), true, (mozilla::RunnableKind)0>::Run() + 44
>  44  mozilla::SchedulerGroup::Runnable::Run() + 257
>  45  nsThread::ProcessNextEvent(bool, bool*) + 2027
>  46  NS_ProcessPendingEvents(nsIThread*, unsigned int) + 78
>  47  nsBaseAppShell::NativeEventCallback() + 113
>  48  nsAppShell::ProcessGeckoEvents(void*) + 246
>  49  __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
>  50  __CFRunLoopDoSources0 + 269
>  51  __CFRunLoopRun + 927
>  52  CFRunLoopRunSpecific + 296
>  53  RunCurrentEventLoopInMode + 235
>  54  ReceiveNextEventCommon + 431
>  55  _BlockUntilNextEventMatchingListInModeWithFilter + 71
>  56  _DPSNextEvent + 978
>  57  -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 346
>  58  -[GeckoNSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 86
>  59  -[NSApplication run] + 594
>  60  nsAppShell::Run() + 249
>  61  XRE_RunAppShell() + 270
>  62  MessageLoop::Run() + 73
>  63  XRE_InitChildProcess(int, char**, XREChildData const*) + 1878
>  64  main + 89
>  65  start + 52

and this is the 2nd one, that is triggered by PostDelayedTask.
https://searchfox.org/mozilla-central/rev/51d4c2d9ce39faec9d74e9597b69d5cc697bd93f/dom/ipc/ContentChild.cpp#2968-2971

>  0   mozilla::dom::ContentChild::RecvShutdown() + 356
>  1   mozilla::detail::RunnableMethodImpl<mozilla::dom::ContentChild*, mozilla::ipc::IPCResult (mozilla::dom::ContentChild::*)(), true, (mozilla::RunnableKind)0>::Run() + 44
>  2   (anonymous namespace)::DelayedRunnable::Run() + 190
>  3   nsThread::ProcessNextEvent(bool, bool*) + 2027
>  4   NS_ProcessNextEvent(nsIThread*, bool) + 47
>  5   nsThreadManager::SpinEventLoopUntil(nsINestedEventLoopCondition*) + 236
>  6   NS_InvokeByIndex + 142
>  7   XPCWrappedNative::CallMethod(XPCCallContext&, XPCWrappedNative::CallMode) + 4292
>  8   XPC_WN_CallMethod(JSContext*, unsigned int, JS::Value*) + 479
>  9   js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 565
>  10  Interpret(JSContext*, js::RunState&) + 32783
>  11  js::RunScript(JSContext*, js::RunState&) + 382
>  12  js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 1049
>  13  Interpret(JSContext*, js::RunState&) + 32783
>  14  js::RunScript(JSContext*, js::RunState&) + 382
>  15  js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 1049
>  16  js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) + 41
>  17  JS_CallFunctionValue(JSContext*, JS::Handle<JSObject*>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) + 667
>  18  nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS*, unsigned short, XPTMethodDescriptor const*, nsXPTCMiniVariant*) + 3370
>  19  PrepareAndDispatch + 540
>  20  SharedStub + 91
>  21  nsGlobalWindowOuter::AlertOrConfirm(bool, nsTSubstring<char16_t> const&, nsIPrincipal&, mozilla::ErrorResult&) + 1023
>  22  nsGlobalWindowInner::Alert(nsTSubstring<char16_t> const&, nsIPrincipal&, mozilla::ErrorResult&) + 209
>  23  mozilla::dom::WindowBinding::alert(JSContext*, JS::Handle<JSObject*>, nsGlobalWindowInner*, JSJitMethodCallArgs const&) + 363
>  24  mozilla::dom::WindowBinding::genericMethod(JSContext*, unsigned int, JS::Value*) + 447
>  25  js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 565
>  26  Interpret(JSContext*, js::RunState&) + 32783
>  27  js::RunScript(JSContext*, js::RunState&) + 382
>  28  js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct) + 1049
>  29  js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>) + 41
>  30  JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) + 688
>  31  mozilla::dom::EventListener::HandleEvent(JSContext*, JS::Handle<JS::Value>, mozilla::dom::Event&, mozilla::ErrorResult&) + 710
>  32  mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, nsIDOMEvent*, mozilla::dom::EventTarget*) + 336
>  33  mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent**, mozilla::dom::EventTarget*, nsEventStatus*) + 2759
>  34  mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) + 450
>  35  mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, nsIDOMEvent*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) + 2792
>  36  mozilla::EventDispatcher::DispatchDOMEvent(nsISupports*, mozilla::WidgetEvent*, nsIDOMEvent*, nsPresContext*, nsEventStatus*) + 268
>  37  nsINode::DispatchEvent(nsIDOMEvent*, bool*) + 186
>  38  nsContentUtils::DispatchEvent(nsIDocument*, nsISupports*, nsTSubstring<char16_t> const&, bool, bool, bool, bool*, bool) + 181
>  39  nsContentUtils::DispatchTrustedEvent(nsIDocument*, nsISupports*, nsTSubstring<char16_t> const&, bool, bool, bool*) + 28
>  40  nsDocument::UpdateVisibilityState() + 233
>  41  mozilla::detail::RunnableMethodImpl<nsDocument*, void (nsDocument::*)(), true, (mozilla::RunnableKind)0>::Run() + 44
>  42  mozilla::SchedulerGroup::Runnable::Run() + 257
>  43  nsThread::ProcessNextEvent(bool, bool*) + 2027
>  44  NS_ProcessPendingEvents(nsIThread*, unsigned int) + 78
>  45  nsBaseAppShell::NativeEventCallback() + 113
>  46  nsAppShell::ProcessGeckoEvents(void*) + 246
>  47  __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
>  48  __CFRunLoopDoSources0 + 269
>  49  __CFRunLoopRun + 927
>  50  CFRunLoopRunSpecific + 296
>  51  RunCurrentEventLoopInMode + 235
>  52  ReceiveNextEventCommon + 431
>  53  _BlockUntilNextEventMatchingListInModeWithFilter + 71
>  54  _DPSNextEvent + 978
>  55  -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 346
>  56  -[GeckoNSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 86
>  57  -[NSApplication run] + 594
>  58  nsAppShell::Run() + 249
>  59  XRE_RunAppShell() + 270
>  60  MessageLoop::Run() + 73
>  61  XRE_InitChildProcess(int, char**, XREChildData const*) + 1878
>  62  main + 89
>  63  start + 52

so, both are handled by nsThreadManager::SpinEventLoopUntil called by alert.

https://searchfox.org/mozilla-central/rev/51d4c2d9ce39faec9d74e9597b69d5cc697bd93f/browser/base/content/test/tabPrompts/openPromptOffTimeout.html#6
https://searchfox.org/mozilla-central/rev/51d4c2d9ce39faec9d74e9597b69d5cc697bd93f/toolkit/components/prompts/src/nsPrompter.js#510
> function openRemotePrompt(domWin, args, tabPrompt) {
> ...
>     Services.tm.spinEventLoopUntil(() => closed);
> }

if the delayed task is handled by the nsThread::ProcessNextEvent there,
the content process won't shutdown until the alert gets closed.

I don't observe such issue locally, and I wonder what the difference is...
Taking this bug to follow up.
Assignee: nobody → btseng
Priority: -- → P3
Update finding so far:
I hit once locally on linux 64 with additional logs added:
1. The child process is spinning the event loop at:
https://searchfox.org/mozilla-central/rev/51d4c2d9ce39faec9d74e9597b69d5cc697bd93f/toolkit/components/prompts/src/nsPrompter.js#510
> function openRemotePrompt(domWin, args, tabPrompt) {
>     ...
>     Services.tm.spinEventLoopUntil(() => closed);
> }
  until the closed flag is set at the "PromptClose" listener:
https://searchfox.org/mozilla-central/rev/51d4c2d9ce39faec9d74e9597b69d5cc697bd93f/toolkit/components/prompts/src/nsPrompter.js#482
> messageManager.addMessageListener("Prompt:Close", function listener(message) {
>     ...
>     // Exit our nested event loop when we unwind.
>     closed = true;
> });
  which is sent from parent at 
https://searchfox.org/mozilla-central/rev/51d4c2d9ce39faec9d74e9597b69d5cc697bd93f/browser/modules/RemotePrompt.jsm#57
> function onPromptClose(forceCleanup) {
>   ...
>   PromptUtils.fireDialogEvent(window, "DOMModalDialogClosed", browser);
>   browser.messageManager.sendAsyncMessage("Prompt:Close", args);
> }

2. However, when the symptom happens there are 2 abnormal errors compared to the correct one after BrowserTestUtils.removeTab(openedTab) is called:
  a. the onPromptClose() is called due to an excepton of "TypeError: browser.parentNode is null" thrown from:
     https://searchfox.org/mozilla-central/rev/137f1b2f434346a0c3756ebfcbdbee4069e15dc8/browser/base/content/browser.js#8961
>    browser.parentNode.insertBefore(newPrompt, browser.nextSibling);
     instead of "TabClose" in tabprompts.xml: https://searchfox.org/mozilla-central/rev/137f1b2f434346a0c3756ebfcbdbee4069e15dc8/toolkit/components/prompts/content/tabprompts.xml#227
  b. Even though the onPromptClose() is called eventually, the browser.messageManager is null when sendAsyncMessage() is called.
> function onPromptClose(forceCleanup) {
>   ...
>   browser.messageManager.sendAsyncMessage("Prompt:Close", args);
> }

Still trying to figure why this is related to the promise scheduling change in bug 1193394.
With the conformant promising scheduling in bug 1193394, the promise callback can be performed earlier while returning from a event listener when possible instead of at the end of current task.

Hence, the resolving of "selected" change of the openedTab [1] becomes part of the process of RemotePrompt.openTabPrompt() where the 'DOMWillOpenModalDialog' event is fired [2~7].

We should resume the test at next tick [8] to ensure that the openTabPrompt() is done without being interleaved by the removal of the openedTab [9] to allow parent to send "Prompt:Close" properly to child for the return of 'Services.tm.spinEventLoopUntil(() => closed)' [10] call in child process.

BTW, the try result of this patch with/without the fix of bug 1193394 looks good:
(With) https://treeherder.mozilla.org/#/jobs?repo=try&revision=2f1b3d827047df28f60c89cc769062428f8d0dfa&group_state=expanded&selectedJob=156510911
(Without) https://treeherder.mozilla.org/#/jobs?repo=try&revision=e9a2c98398d7b7d3e5a59bb55b281d8f964fba47&selectedJob=156511047


[1] https://searchfox.org/mozilla-central/rev/137f1b2f434346a0c3756ebfcbdbee4069e15dc8/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm#1325
[2] https://searchfox.org/mozilla-central/rev/41925c0b6c6d58578690121de439d2a8d3d690f3/browser/modules/RemotePrompt.jsm#79
[3] https://searchfox.org/mozilla-central/rev/137f1b2f434346a0c3756ebfcbdbee4069e15dc8/browser/base/content/tabbrowser.xml#6157
[4] https://searchfox.org/mozilla-central/rev/41925c0b6c6d58578690121de439d2a8d3d690f3/toolkit/content/widgets/tabbox.xml#99
[5] https://searchfox.org/mozilla-central/rev/41925c0b6c6d58578690121de439d2a8d3d690f3/toolkit/content/widgets/tabbox.xml#429
[6] https://searchfox.org/mozilla-central/rev/41925c0b6c6d58578690121de439d2a8d3d690f3/toolkit/content/widgets/tabbox.xml#387
[7] https://searchfox.org/mozilla-central/rev/41925c0b6c6d58578690121de439d2a8d3d690f3/toolkit/content/widgets/tabbox.xml#739
[8] https://searchfox.org/mozilla-central/rev/41925c0b6c6d58578690121de439d2a8d3d690f3/browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js#74
[9] https://searchfox.org/mozilla-central/rev/41925c0b6c6d58578690121de439d2a8d3d690f3/browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js#78
[10] https://searchfox.org/mozilla-central/rev/137f1b2f434346a0c3756ebfcbdbee4069e15dc8/toolkit/components/prompts/src/nsPrompter.js#510
Attachment #8942832 - Flags: review?(gijskruitbosch+bugs)
Status: NEW → ASSIGNED
Comment on attachment 8942832 [details] [diff] [review]
(v1) Patch: Resume the test at next tick after the resolve of openTabSelectedPromise.

Review of attachment 8942832 [details] [diff] [review]:
-----------------------------------------------------------------

In the future, please use reviewboard / phabricator, or, if that is not usable for you for some reason, please configure hg/git to export bigger diffs, ie 8 or 10 lines of context. I believe ./mach mercurial-setup can help with this for hg.


r=me with the `waitForTick()` moved after the check for which tab is selected.

::: browser/base/content/test/tabPrompts/browser_openPromptInBackgroundTab.js
@@ +76,5 @@
> +  // In e10s, with the conformant promise scheduling, we have to wait for next tick
> +  // to ensure that the prompt is open before removing the opened tab, because the
> +  // promise callback of 'openedTabSelectedPromise' could be done at the middle of
> +  // RemotePrompt.openTabPrompt() while 'DOMModalDialogClosed' event is fired.
> +  await TestUtils.waitForTick();

This comment and code doesn't make sense in this location. It should go after the assertion that the correct tab is selected (but before the `removeTab()` call). Based on what you describe in the comments in the bug, the `openedTabSelectedPromise` is only resolved when the selected tab has changed, so the assert should succeed immediately, without waiting, even if the promise is resolved in the middle of `openTabPrompt` being called.
Attachment #8942832 - Flags: review?(gijskruitbosch+bugs) → review+
(In reply to :Gijs from comment #20)
> Comment on attachment 8942832 [details] [diff] [review]
> (v1) Patch: Resume the test at next tick after the resolve of
> openTabSelectedPromise.
> 
> Review of attachment 8942832 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> In the future, please use reviewboard / phabricator, or, if that is not
> usable for you for some reason, please configure hg/git to export bigger
> diffs, ie 8 or 10 lines of context. I believe ./mach mercurial-setup can
> help with this for hg.
> 
> 
> r=me with the `waitForTick()` moved after the check for which tab is
> selected.
Will do, thanks!
Pushed by btseng@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/37c38f403e4d
Resume the test at next tick after the resolve of openTabSelectedPromise. r=:Gijs.
https://hg.mozilla.org/mozilla-central/rev/37c38f403e4d
Status: ASSIGNED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → Firefox 59
You need to log in before you can comment on or make changes to this bug.