Assertion failure: !foundInPendingQ, at checkouts/gecko/netwerk/protocol/http/nsHttpConnectionMgr.cpp:4058
Categories
(Core :: Networking: HTTP, defect, P2)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox-esr115 | --- | unaffected |
| firefox-esr140 | --- | unaffected |
| firefox-esr153 | --- | disabled |
| firefox152 | --- | disabled |
| firefox153 | --- | disabled |
| firefox154 | --- | fixed |
People
(Reporter: tsmith, Assigned: kershaw)
References
(Blocks 2 open bugs, )
Details
(Keywords: assertion, pernosco, Whiteboard: [necko-triaged][necko-priority-next])
Attachments
(1 file)
Found with m-c 20260627-cd8b93a107ef (--enable-debug)
This was found by visiting a live website with a debug build.
STR:
- Launch browser and visit site
This issue was triggered by visiting http://www.bonitas.co.za/. A Pernosco session is available here: https://pernos.co/debug/DxkwkbGC1HrGolu_RB-ueQ/index.html
Assertion failure: !foundInPendingQ, at checkouts/gecko/netwerk/protocol/http/nsHttpConnectionMgr.cpp:4058
7|0|libxul.so|mozilla::net::nsHttpConnectionMgr::CheckTransInPendingQueue(mozilla::net::nsHttpTransaction*)|git:github.com/mozilla-firefox/firefox:netwerk/protocol/http/nsHttpConnectionMgr.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|4058|0x110
7|1|libxul.so|mozilla::net::nsHttpConnectionMgr::AddTransaction(mozilla::net::HttpTransactionShell*, int)|git:github.com/mozilla-firefox/firefox:netwerk/protocol/http/nsHttpConnectionMgr.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|354|0x42
7|2|libxul.so|mozilla::net::HappyEyeballsConnectionAttempt::ProcessTCPConn(mozilla::net::HttpConnectionBase*, mozilla::net::ConnectionEntry*, bool)|git:github.com/mozilla-firefox/firefox:netwerk/protocol/http/HappyEyeballsConnectionAttempt.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|1202|0x37a
7|3|libxul.so|mozilla::net::HappyEyeballsConnectionAttempt::EnterSucceeded()|git:github.com/mozilla-firefox/firefox:netwerk/protocol/http/HappyEyeballsConnectionAttempt.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|1425|0x420
7|4|libxul.so|mozilla::net::HappyEyeballsConnectionAttempt::ProcessHappyEyeballsOutput()|git:github.com/mozilla-firefox/firefox:netwerk/protocol/http/HappyEyeballsConnectionAttempt.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|601|0x252
7|5|libxul.so|mozilla::net::HappyEyeballsConnectionAttempt::ProcessConnectionResult(mozilla::net::NetAddr const&, nsresult, unsigned long)|git:github.com/mozilla-firefox/firefox:netwerk/protocol/http/HappyEyeballsConnectionAttempt.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|397|0x1cd
7|6|libxul.so|mozilla::net::HappyEyeballsConnectionAttempt::HandleConnectionResult(mozilla::Result<RefPtr<mozilla::net::HttpConnectionBase>, nsresult>, mozilla::net::ConnectionEstablisher*, unsigned long)|git:github.com/mozilla-firefox/firefox:netwerk/protocol/http/HappyEyeballsConnectionAttempt.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b||0x39e
7|7|libxul.so|std::_Function_handler<void (mozilla::Result<RefPtr<mozilla::net::HttpConnectionBase>, nsresult>), mozilla::net::HappyEyeballsConnectionAttempt::EstablishTCPConnection(mozilla::net::NetAddr, unsigned short, nsTArray<unsigned char>&&, unsigned long, bool)::$_2>::_M_invoke(std::_Any_data const&, mozilla::Result<RefPtr<mozilla::net::HttpConnectionBase>, nsresult>&&)|/builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/include/c++/10/bits/std_function.h|291|0x61
7|8|libxul.so|mozilla::net::ConnectionEstablisher::FinishInternal(nsresult)|git:github.com/mozilla-firefox/firefox:netwerk/protocol/http/ConnectionEstablisher.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|327|0x2a3
7|9|libxul.so|mozilla::detail::RunnableFunction<mozilla::net::ConnectionEstablisher::ActivateConnectionWithTransaction(RefPtr<mozilla::net::HttpConnectionBase>, std::function<void (nsresult)>)::$_0::operator()(nsresult) const::{lambda()#1}>::Run()|git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThreadUtils.h:9b76a2f882af6691de21dfe290f8175c9bedce7b|536|0x37
7|10|libxul.so|nsThread::ProcessNextEvent(bool, bool*)|git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThread.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|1173|0x7ab
7|11|libxul.so|NS_ProcessNextEvent(nsIThread*, bool)|git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThreadUtils.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|472|0x4f
7|12|libxul.so|mozilla::net::nsSocketTransportService::Run()|git:github.com/mozilla-firefox/firefox:netwerk/base/nsSocketTransportService2.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|1254|0x564
7|13|libxul.so|{virtual override thunk({offset(-32)}, mozilla::net::nsSocketTransportService::Run())}|git:github.com/mozilla-firefox/firefox:netwerk/base/nsSocketTransportService2.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b||0xc
7|14|libxul.so|nsThread::ProcessNextEvent(bool, bool*)|git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThread.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|1173|0x7ab
7|15|libxul.so|NS_ProcessNextEvent(nsIThread*, bool)|git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThreadUtils.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|472|0x4f
7|16|libxul.so|mozilla::ipc::MessagePumpForNonMainThreads::Run(base::MessagePump::Delegate*)|git:github.com/mozilla-firefox/firefox:ipc/glue/MessagePump.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|297|0xc6
7|17|libxul.so|MessageLoop::Run()|git:github.com/mozilla-firefox/firefox:ipc/chromium/src/base/message_loop.cc:9b76a2f882af6691de21dfe290f8175c9bedce7b|346|0x61
7|18|libxul.so|nsThread::ThreadFunc(void*)|git:github.com/mozilla-firefox/firefox:xpcom/threads/nsThread.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|374|0x1ba
7|19|libnspr4.so|_pt_root|git:github.com/mozilla-firefox/firefox:nsprpub/pr/src/pthreads/ptthread.c:9b76a2f882af6691de21dfe290f8175c9bedce7b|190|0x18c
7|20|firefox-bin|set_alt_signal_stack_and_start(PthreadCreateParams*)|git:github.com/mozilla-firefox/firefox:mozglue/interposers/pthread_create_interposer.cpp:9b76a2f882af6691de21dfe290f8175c9bedce7b|81|0x10d
Updated•13 days ago
|
| Assignee | ||
Updated•13 days ago
|
| Assignee | ||
Comment 1•13 days ago
|
||
Root cause
This is a Happy Eyeballs / WebSocket-upgrade race. Two HappyEyeballsConnectionAttempts are created for the same transaction (trans=0x79f093ac6800) and the same, mutated-in-place connection info (ci=0x79f09b777d00):
- attempt #1 —
caps=1075872004→STICKY_CONNECTION | LOAD_UNBLOCKED | ALLOW_SPDY_WITHOUT_KEEPALIVE | DISALLOW_HTTP3 | USE_HAPPY_EYEBALLS— the original WS upgrade, with H2 allowed. - attempt #2 —
caps=1210098052→ the same flags plusDISALLOW_SPDY | CONNECTION_RESTARTABLE | IS_RETRY— the restarted WS upgrade after H2→H1 fallback.
The Pernosco session confirms that the two pending-queue hash keys differ only in the X (NS_HTTP_DISALLOW_SPDY) byte:
.S.P......H[...]chat.talkk.ai:443[!h3]... <- key ProcessTCPConn looks up (no X)
.S.P.X....H[...]chat.talkk.ai:443[!h3]... <- key stored in the transaction (with X)
Flow
-
The WS upgrade transaction
Tis created H2-capable (ALLOW_SPDY_WITHOUT_KEEPALIVE, noX; see the upgrade-caps setup innsHttpChannel::BeginConnect) and queued under entry K1 (noX);T’s hash key (OnPendingQueueInserted) isK1. -
attempt #1 is created for
T(mEntry = K1) and establishes an H2 connection. -
Tis dispatched onto that H2 connection viaTryDispatchExtendedCONNECTTransaction. The server’s H2 does not support extended CONNECT (NO_SUPPORT), so it callsnsHttpTransaction::DisableSpdy(), which ORs inNS_HTTP_DISALLOW_SPDYand mutatesciin place viaSetNoSpdy(true)— adding theXbyte, truncating theh2NPN token, and rebuilding the hash key. It returnsNS_ERROR_HTTP2_FALLBACK_TO_HTTP1. -
Tis restarted (NS_ERROR_HTTP2_FALLBACK_TO_HTTP1is restartable innsHttpTransaction::Close); its caps gainIS_RETRY | CONNECTION_RESTARTABLE. -
The restarted
Tis reinserted into the pending queue under the newXkey → entry K2; its stored hash key becomesK2. attempt #2 is then created for it. -
Meanwhile, attempt #1 still holds
mTransaction = TandmEntry = K1. When it later receives its H2 success event, it goes throughEnterSucceeded→ProcessTCPConn. Because this is an H2 connection for a WS upgrade, it takes thedeferExtendedConnectre-queue path:FindTransaction(removeWhenFound=false, entry=K1, T)misses (becauseTnow lives inK2),T->Connection()is null, and it callsAddTransaction(T). -
CheckTransInPendingQueuelooks upTby its stored key (K2), finds it still pending, andMOZ_ASSERT(!foundInPendingQ)fires. Thetrans_found_in_pending_queuetelemetry just above the assert confirms that this case occurs.
Two contributing defects
-
When
Tfalls back to H1 and is restarted (creating attempt #2), the original H2 attempt (attempt #1) is not cancelled and still holds a reference toT. Its laterEnterSucceededpath then tries to re-queue a transaction it no longer owns. -
The
deferExtendedConnectre-queue guard checksmEntry(K1) rather thanT’s current pending entry (K2, viaT->GetHashKeyOfConnectionEntry()), so it cannot detect thatTis already queued.
| Assignee | ||
Comment 2•12 days ago
|
||
Comment 4•11 days ago
|
||
| bugherder | ||
Updated•11 days ago
|
Description
•