Add more information to loggings when the session tries to write data after connection disconnected. PiperOrigin-RevId: 491343655
diff --git a/quiche/quic/core/frames/quic_frame.cc b/quiche/quic/core/frames/quic_frame.cc index 89c7234..2ed0550 100644 --- a/quiche/quic/core/frames/quic_frame.cc +++ b/quiche/quic/core/frames/quic_frame.cc
@@ -514,6 +514,12 @@ return os; } +QUIC_EXPORT_PRIVATE std::string QuicFrameToString(const QuicFrame& frame) { + std::ostringstream os; + os << frame; + return os.str(); +} + std::string QuicFramesToString(const QuicFrames& frames) { std::ostringstream os; for (const QuicFrame& frame : frames) {
diff --git a/quiche/quic/core/frames/quic_frame.h b/quiche/quic/core/frames/quic_frame.h index 358b20e..3b7196e 100644 --- a/quiche/quic/core/frames/quic_frame.h +++ b/quiche/quic/core/frames/quic_frame.h
@@ -166,6 +166,7 @@ quiche::QuicheBufferAllocator* allocator, const QuicFrames& frames); // Human-readable description suitable for logging. +QUIC_EXPORT_PRIVATE std::string QuicFrameToString(const QuicFrame& frame); QUIC_EXPORT_PRIVATE std::string QuicFramesToString(const QuicFrames& frames); } // namespace quic
diff --git a/quiche/quic/core/quic_session.cc b/quiche/quic/core/quic_session.cc index b94250f..242b9fc 100644 --- a/quiche/quic/core/quic_session.cc +++ b/quiche/quic/core/quic_session.cc
@@ -452,6 +452,7 @@ if (on_closed_frame_.quic_error_code == QUIC_NO_ERROR) { // Save all of the connection close information on_closed_frame_ = frame; + source_ = source; } GetMutableCryptoStream()->OnConnectionClosed(frame.quic_error_code, source); @@ -789,8 +790,13 @@ StreamSendingState state, TransmissionType type, EncryptionLevel level) { - QUICHE_DCHECK(connection_->connected()) - << ENDPOINT << "Try to write stream data when connection is closed."; + QUIC_BUG_IF(session writevdata when disconnected, !connection()->connected()) + << ENDPOINT + << absl::StrCat("Try to write stream data when connection is closed: ", + QuicFrameToString(QuicFrame(&on_closed_frame_)), " ", + source_.has_value() + ? ConnectionCloseSourceToString(source_.value()) + : ""); if (!IsEncryptionEstablished() && !QuicUtils::IsCryptoStreamId(transport_version(), id)) { // Do not let streams write without encryption. The calling stream will end @@ -865,7 +871,13 @@ bool QuicSession::WriteControlFrame(const QuicFrame& frame, TransmissionType type) { QUIC_BUG_IF(quic_bug_12435_11, !connection()->connected()) - << ENDPOINT << "Try to write control frames when connection is closed."; + << ENDPOINT + << absl::StrCat("Try to write control frame: ", QuicFrameToString(frame), + " when connection is closed: ", + QuicFrameToString(QuicFrame(&on_closed_frame_)), " ", + source_.has_value() + ? ConnectionCloseSourceToString(source_.value()) + : ""); if (!IsEncryptionEstablished()) { // Suppress the write before encryption gets established. return false;
diff --git a/quiche/quic/core/quic_session.h b/quiche/quic/core/quic_session.h index 87509a7..07711ac 100644 --- a/quiche/quic/core/quic_session.h +++ b/quiche/quic/core/quic_session.h
@@ -951,6 +951,7 @@ // Received information for a connection close. QuicConnectionCloseFrame on_closed_frame_; + absl::optional<ConnectionCloseSource> source_; // Used for connection-level flow control. QuicFlowController flow_controller_;
diff --git a/quiche/quic/core/quic_session_test.cc b/quiche/quic/core/quic_session_test.cc index 041d5c8..280d8a8 100644 --- a/quiche/quic/core/quic_session_test.cc +++ b/quiche/quic/core/quic_session_test.cc
@@ -3121,8 +3121,7 @@ if (!GetQuicReloadableFlag( quic_no_write_control_frame_upon_connection_close)) { EXPECT_CALL(*connection_, SendControlFrame(_)).WillOnce(Return(false)); - EXPECT_QUIC_BUG(session_.OnCanWrite(), - "Try to write control frames when connection is closed"); + EXPECT_QUIC_BUG(session_.OnCanWrite(), "Try to write control frame"); } else { session_.OnCanWrite(); }