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_