Add HTTP2_CODE_COUNT_N API and decompress_failure_3 counters to debug source of
DECOMPRESS_FAILURE errors.

Note that on any code path multiple of these macros are expected to be hit.

gfe-relnote: n/a, add CODE_COUNT macros for debugging.
PiperOrigin-RevId: 292355227
Change-Id: I9b02119c30af03016073307feedee896f397b24c
diff --git a/http2/hpack/decoder/hpack_block_decoder.cc b/http2/hpack/decoder/hpack_block_decoder.cc
index 04e4d29..509a493 100644
--- a/http2/hpack/decoder/hpack_block_decoder.cc
+++ b/http2/hpack/decoder/hpack_block_decoder.cc
@@ -6,6 +6,7 @@
 
 #include <cstdint>
 
+#include "net/third_party/quiche/src/http2/platform/api/http2_flags.h"
 #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h"
 #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
@@ -25,6 +26,7 @@
         DCHECK_EQ(0u, db->Remaining());
         return DecodeStatus::kDecodeInProgress;
       case DecodeStatus::kDecodeError:
+        HTTP2_CODE_COUNT_N(decompress_failure_3, 1, 23);
         return DecodeStatus::kDecodeError;
     }
   }
@@ -41,6 +43,7 @@
         before_entry_ = false;
         return DecodeStatus::kDecodeInProgress;
       case DecodeStatus::kDecodeError:
+        HTTP2_CODE_COUNT_N(decompress_failure_3, 2, 23);
         return DecodeStatus::kDecodeError;
     }
     DCHECK(false);
diff --git a/http2/hpack/decoder/hpack_decoder.cc b/http2/hpack/decoder/hpack_decoder.cc
index 1421c7c..6d1ebbd 100644
--- a/http2/hpack/decoder/hpack_decoder.cc
+++ b/http2/hpack/decoder/hpack_decoder.cc
@@ -6,6 +6,7 @@
 
 #include "net/third_party/quiche/src/http2/decoder/decode_status.h"
 #include "net/third_party/quiche/src/http2/platform/api/http2_estimate_memory_usage.h"
+#include "net/third_party/quiche/src/http2/platform/api/http2_flags.h"
 #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h"
 
 namespace http2 {
@@ -51,6 +52,7 @@
                  << (error_detected() ? "true" : "false")
                  << ", size=" << db->Remaining();
   if (error_detected()) {
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 3, 23);
     return false;
   }
   // Decode contents of db as an HPACK block fragment, forwards the decoded
@@ -60,8 +62,10 @@
   if (status == DecodeStatus::kDecodeError) {
     // This has probably already been reported, but just in case...
     ReportError("HPACK block malformed.");
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 4, 23);
     return false;
   } else if (error_detected()) {
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 5, 23);
     return false;
   }
   // Should be positioned between entries iff decoding is complete.
@@ -77,16 +81,19 @@
   HTTP2_DVLOG(3) << "HpackDecoder::EndDecodingBlock, error_detected="
                  << (error_detected() ? "true" : "false");
   if (error_detected()) {
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 6, 23);
     return false;
   }
   if (!block_decoder_.before_entry()) {
     // The HPACK block ended in the middle of an entry.
     ReportError("HPACK block truncated.");
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 7, 23);
     return false;
   }
   decoder_state_.OnHeaderBlockEnd();
   if (error_detected()) {
     // HpackDecoderState will have reported the error.
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 8, 23);
     return false;
   }
   return true;
@@ -96,9 +103,11 @@
   if (!error_detected_) {
     if (entry_buffer_.error_detected()) {
       HTTP2_DVLOG(2) << "HpackDecoder::error_detected in entry_buffer_";
+      HTTP2_CODE_COUNT_N(decompress_failure_3, 9, 23);
       error_detected_ = true;
     } else if (decoder_state_.error_detected()) {
       HTTP2_DVLOG(2) << "HpackDecoder::error_detected in decoder_state_";
+      HTTP2_CODE_COUNT_N(decompress_failure_3, 10, 23);
       error_detected_ = true;
     }
   }
diff --git a/http2/hpack/decoder/hpack_entry_decoder.cc b/http2/hpack/decoder/hpack_entry_decoder.cc
index 97af6f9..e177728 100644
--- a/http2/hpack/decoder/hpack_entry_decoder.cc
+++ b/http2/hpack/decoder/hpack_entry_decoder.cc
@@ -9,6 +9,7 @@
 #include <cstdint>
 
 #include "net/third_party/quiche/src/http2/platform/api/http2_bug_tracker.h"
+#include "net/third_party/quiche/src/http2/platform/api/http2_flags.h"
 #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h"
 #include "net/third_party/quiche/src/http2/platform/api/http2_macros.h"
 
@@ -78,6 +79,7 @@
       state_ = EntryDecoderState::kResumeDecodingType;
       return status;
     case DecodeStatus::kDecodeError:
+      HTTP2_CODE_COUNT_N(decompress_failure_3, 11, 23);
       // The varint must have been invalid (too long).
       return status;
   }
@@ -100,6 +102,9 @@
         HTTP2_DVLOG(1) << "kResumeDecodingType: db->Remaining="
                        << db->Remaining();
         status = entry_type_decoder_.Resume(db);
+        if (status == DecodeStatus::kDecodeError) {
+          HTTP2_CODE_COUNT_N(decompress_failure_3, 12, 23);
+        }
         if (status != DecodeStatus::kDecodeDone) {
           return status;
         }
@@ -129,6 +134,9 @@
           // that will only happen if the varint encoding the name's length
           // is too long.
           state_ = EntryDecoderState::kResumeDecodingName;
+          if (status == DecodeStatus::kDecodeError) {
+            HTTP2_CODE_COUNT_N(decompress_failure_3, 13, 23);
+          }
           return status;
         }
         state_ = EntryDecoderState::kStartDecodingValue;
@@ -141,6 +149,9 @@
           ValueDecoderListener vcb(listener);
           status = string_decoder_.Start(db, &vcb);
         }
+        if (status == DecodeStatus::kDecodeError) {
+          HTTP2_CODE_COUNT_N(decompress_failure_3, 14, 23);
+        }
         if (status == DecodeStatus::kDecodeDone) {
           // Done with decoding the literal value, so we've reached the
           // end of the header entry.
@@ -167,6 +178,9 @@
           // that will only happen if the varint encoding the name's length
           // is too long.
           state_ = EntryDecoderState::kResumeDecodingName;
+          if (status == DecodeStatus::kDecodeError) {
+            HTTP2_CODE_COUNT_N(decompress_failure_3, 15, 23);
+          }
           return status;
         }
         state_ = EntryDecoderState::kStartDecodingValue;
@@ -180,6 +194,9 @@
           ValueDecoderListener vcb(listener);
           status = string_decoder_.Resume(db, &vcb);
         }
+        if (status == DecodeStatus::kDecodeError) {
+          HTTP2_CODE_COUNT_N(decompress_failure_3, 16, 23);
+        }
         if (status == DecodeStatus::kDecodeDone) {
           // Done with decoding the value, therefore the entry as a whole.
           return status;
diff --git a/http2/hpack/decoder/hpack_entry_type_decoder.cc b/http2/hpack/decoder/hpack_entry_type_decoder.cc
index ebb5779..5df119f 100644
--- a/http2/hpack/decoder/hpack_entry_type_decoder.cc
+++ b/http2/hpack/decoder/hpack_entry_type_decoder.cc
@@ -5,6 +5,7 @@
 #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_entry_type_decoder.h"
 
 #include "net/third_party/quiche/src/http2/platform/api/http2_bug_tracker.h"
+#include "net/third_party/quiche/src/http2/platform/api/http2_flags.h"
 #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h"
 #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
@@ -353,6 +354,7 @@
       return varint_decoder_.StartExtended(7, db);
   }
   HTTP2_BUG << "Unreachable, byte=" << std::hex << static_cast<uint32_t>(byte);
+  HTTP2_CODE_COUNT_N(decompress_failure_3, 17, 23);
   return DecodeStatus::kDecodeError;
 }
 
diff --git a/http2/hpack/decoder/hpack_whole_entry_buffer.cc b/http2/hpack/decoder/hpack_whole_entry_buffer.cc
index 1f1f4f0..2173756 100644
--- a/http2/hpack/decoder/hpack_whole_entry_buffer.cc
+++ b/http2/hpack/decoder/hpack_whole_entry_buffer.cc
@@ -5,6 +5,7 @@
 #include "net/third_party/quiche/src/http2/hpack/decoder/hpack_whole_entry_buffer.h"
 
 #include "net/third_party/quiche/src/http2/platform/api/http2_estimate_memory_usage.h"
+#include "net/third_party/quiche/src/http2/platform/api/http2_flags.h"
 #include "net/third_party/quiche/src/http2/platform/api/http2_logging.h"
 #include "net/third_party/quiche/src/http2/platform/api/http2_macros.h"
 #include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h"
@@ -58,6 +59,7 @@
       HTTP2_DVLOG(1) << "Name length (" << len << ") is longer than permitted ("
                      << max_string_size_bytes_ << ")";
       ReportError("HPACK entry name size is too long.");
+      HTTP2_CODE_COUNT_N(decompress_failure_3, 18, 23);
       return;
     }
     name_.OnStart(huffman_encoded, len);
@@ -71,6 +73,7 @@
   DCHECK_EQ(maybe_name_index_, 0u);
   if (!error_detected_ && !name_.OnData(data, len)) {
     ReportError("Error decoding HPACK entry name.");
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 19, 23);
   }
 }
 
@@ -79,6 +82,7 @@
   DCHECK_EQ(maybe_name_index_, 0u);
   if (!error_detected_ && !name_.OnEnd()) {
     ReportError("Error decoding HPACK entry name.");
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 20, 23);
   }
 }
 
@@ -91,6 +95,7 @@
                      << ") is longer than permitted (" << max_string_size_bytes_
                      << ")";
       ReportError("HPACK entry value size is too long.");
+      HTTP2_CODE_COUNT_N(decompress_failure_3, 21, 23);
       return;
     }
     value_.OnStart(huffman_encoded, len);
@@ -103,6 +108,7 @@
                  << Http2HexDump(quiche::QuicheStringPiece(data, len));
   if (!error_detected_ && !value_.OnData(data, len)) {
     ReportError("Error decoding HPACK entry value.");
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 22, 23);
   }
 }
 
@@ -113,6 +119,7 @@
   }
   if (!value_.OnEnd()) {
     ReportError("Error decoding HPACK entry value.");
+    HTTP2_CODE_COUNT_N(decompress_failure_3, 23, 23);
     return;
   }
   if (maybe_name_index_ == 0) {
diff --git a/http2/platform/api/http2_flags.h b/http2/platform/api/http2_flags.h
index 08f95da..097d35e 100644
--- a/http2/platform/api/http2_flags.h
+++ b/http2/platform/api/http2_flags.h
@@ -11,4 +11,6 @@
 #define SetHttp2ReloadableFlag(flag, value) \
   SetHttp2ReloadableFlagImpl(flag, value)
 
+#define HTTP2_CODE_COUNT_N HTTP2_CODE_COUNT_N_IMPL
+
 #endif  // QUICHE_HTTP2_PLATFORM_API_HTTP2_FLAGS_H_