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