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();
}