Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: net/quic/core/quic_stream_sequencer_buffer.cc

Issue 2519333006: Add CHECK's to debug QuicStreamSequencerBuffer in weird state. Add a destruction indicator to detec… (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/core/quic_stream_sequencer_buffer.h" 5 #include "net/quic/core/quic_stream_sequencer_buffer.h"
6 6
7 #include "base/debug/stack_trace.h"
7 #include "base/format_macros.h" 8 #include "base/format_macros.h"
8 #include "base/logging.h" 9 #include "base/logging.h"
9 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
11 #include "net/quic/core/quic_bug_tracker.h" 12 #include "net/quic/core/quic_bug_tracker.h"
12 #include "net/quic/core/quic_flags.h" 13 #include "net/quic/core/quic_flags.h"
13 14
14 using base::StringPrintf; 15 using base::StringPrintf;
15 using std::min; 16 using std::min;
16 using std::string; 17 using std::string;
(...skipping 26 matching lines...) Expand all
43 44
44 QuicStreamSequencerBuffer::FrameInfo::FrameInfo(size_t length, 45 QuicStreamSequencerBuffer::FrameInfo::FrameInfo(size_t length,
45 QuicTime timestamp) 46 QuicTime timestamp)
46 : length(length), timestamp(timestamp) {} 47 : length(length), timestamp(timestamp) {}
47 48
48 QuicStreamSequencerBuffer::QuicStreamSequencerBuffer(size_t max_capacity_bytes) 49 QuicStreamSequencerBuffer::QuicStreamSequencerBuffer(size_t max_capacity_bytes)
49 : max_buffer_capacity_bytes_(max_capacity_bytes), 50 : max_buffer_capacity_bytes_(max_capacity_bytes),
50 blocks_count_( 51 blocks_count_(
51 ceil(static_cast<double>(max_capacity_bytes) / kBlockSizeBytes)), 52 ceil(static_cast<double>(max_capacity_bytes) / kBlockSizeBytes)),
52 total_bytes_read_(0), 53 total_bytes_read_(0),
53 blocks_(nullptr) { 54 blocks_(nullptr),
55 destruction_indicator_(123456) {
56 CHECK(blocks_count_ > 1) << "blocks_count_ = " << blocks_count_
Ryan Hamilton 2016/11/23 20:42:40 nit: CHECK_GT()
danzh1 2016/11/23 21:39:24 Done.
57 << ", max_buffer_capacity_bytes_ = "
58 << max_buffer_capacity_bytes_;
54 Clear(); 59 Clear();
55 } 60 }
56 61
57 QuicStreamSequencerBuffer::~QuicStreamSequencerBuffer() { 62 QuicStreamSequencerBuffer::~QuicStreamSequencerBuffer() {
58 Clear(); 63 Clear();
64 destruction_indicator_ = 654321;
59 } 65 }
60 66
61 void QuicStreamSequencerBuffer::Clear() { 67 void QuicStreamSequencerBuffer::Clear() {
62 if (blocks_ != nullptr) { 68 if (blocks_ != nullptr) {
63 for (size_t i = 0; i < blocks_count_; ++i) { 69 for (size_t i = 0; i < blocks_count_; ++i) {
64 if (blocks_[i] != nullptr) { 70 if (blocks_[i] != nullptr) {
65 RetireBlock(i); 71 RetireBlock(i);
66 } 72 }
67 } 73 }
68 } 74 }
(...skipping 16 matching lines...) Expand all
85 DVLOG(1) << "Retired block with index: " << idx; 91 DVLOG(1) << "Retired block with index: " << idx;
86 return true; 92 return true;
87 } 93 }
88 94
89 QuicErrorCode QuicStreamSequencerBuffer::OnStreamData( 95 QuicErrorCode QuicStreamSequencerBuffer::OnStreamData(
90 QuicStreamOffset starting_offset, 96 QuicStreamOffset starting_offset,
91 base::StringPiece data, 97 base::StringPiece data,
92 QuicTime timestamp, 98 QuicTime timestamp,
93 size_t* const bytes_buffered, 99 size_t* const bytes_buffered,
94 std::string* error_details) { 100 std::string* error_details) {
101 CHECK_EQ(destruction_indicator_, 123456) << "This object has been destructed";
95 *bytes_buffered = 0; 102 *bytes_buffered = 0;
96 QuicStreamOffset offset = starting_offset; 103 QuicStreamOffset offset = starting_offset;
97 size_t size = data.size(); 104 size_t size = data.size();
98 if (size == 0) { 105 if (size == 0) {
99 *error_details = "Received empty stream frame without FIN."; 106 *error_details = "Received empty stream frame without FIN.";
100 return QUIC_EMPTY_STREAM_FRAME_NO_FIN; 107 return QUIC_EMPTY_STREAM_FRAME_NO_FIN;
101 } 108 }
102 109
103 // Find the first gap not ending before |offset|. This gap maybe the gap to 110 // Find the first gap not ending before |offset|. This gap maybe the gap to
104 // fill if the arriving frame doesn't overlaps with previous ones. 111 // fill if the arriving frame doesn't overlaps with previous ones.
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 start_offset + bytes_written) { 273 start_offset + bytes_written) {
267 // This gap has been filled with new data. So it's no longer a gap. 274 // This gap has been filled with new data. So it's no longer a gap.
268 gaps_.erase(gap_with_new_data_written); 275 gaps_.erase(gap_with_new_data_written);
269 } 276 }
270 } 277 }
271 278
272 QuicErrorCode QuicStreamSequencerBuffer::Readv(const iovec* dest_iov, 279 QuicErrorCode QuicStreamSequencerBuffer::Readv(const iovec* dest_iov,
273 size_t dest_count, 280 size_t dest_count,
274 size_t* bytes_read, 281 size_t* bytes_read,
275 string* error_details) { 282 string* error_details) {
283 CHECK_EQ(destruction_indicator_, 123456) << "This object has been destructed";
284
276 *bytes_read = 0; 285 *bytes_read = 0;
277 for (size_t i = 0; i < dest_count && ReadableBytes() > 0; ++i) { 286 for (size_t i = 0; i < dest_count && ReadableBytes() > 0; ++i) {
278 char* dest = reinterpret_cast<char*>(dest_iov[i].iov_base); 287 char* dest = reinterpret_cast<char*>(dest_iov[i].iov_base);
288 CHECK_NE(dest, nullptr);
279 size_t dest_remaining = dest_iov[i].iov_len; 289 size_t dest_remaining = dest_iov[i].iov_len;
280 while (dest_remaining > 0 && ReadableBytes() > 0) { 290 while (dest_remaining > 0 && ReadableBytes() > 0) {
281 size_t block_idx = NextBlockToRead(); 291 size_t block_idx = NextBlockToRead();
282 size_t start_offset_in_block = ReadOffset(); 292 size_t start_offset_in_block = ReadOffset();
283 size_t block_capacity = GetBlockCapacity(block_idx); 293 size_t block_capacity = GetBlockCapacity(block_idx);
284 size_t bytes_available_in_block = 294 size_t bytes_available_in_block =
285 min<size_t>(ReadableBytes(), block_capacity - start_offset_in_block); 295 min<size_t>(ReadableBytes(), block_capacity - start_offset_in_block);
286 size_t bytes_to_copy = 296 size_t bytes_to_copy =
287 min<size_t>(bytes_available_in_block, dest_remaining); 297 min<size_t>(bytes_available_in_block, dest_remaining);
288 DCHECK_GT(bytes_to_copy, 0UL); 298 DCHECK_GT(bytes_to_copy, 0UL);
289 if (blocks_[block_idx] == nullptr || dest == nullptr) { 299 if (blocks_[block_idx] == nullptr || dest == nullptr) {
290 *error_details = StringPrintf( 300 *error_details = StringPrintf(
291 "QuicStreamSequencerBuffer error:" 301 "QuicStreamSequencerBuffer error:"
292 " Readv() dest == nullptr: %s" 302 " Readv() dest == nullptr: %s"
293 " blocks_[%" PRIuS "] == nullptr: %s", 303 " blocks_[%" PRIuS "] == nullptr: %s, stack trace %s",
294 (dest == nullptr ? "true" : "false"), block_idx, 304 (dest == nullptr ? "true" : "false"), block_idx,
295 (blocks_[block_idx] == nullptr ? "true" : "false")); 305 (blocks_[block_idx] == nullptr ? "true" : "false"),
306 base::debug::StackTrace().ToString().c_str());
Ryan Hamilton 2016/11/23 20:42:40 I'm not sure that sending stack traces to google i
danzh1 2016/11/23 21:39:24 removed as I switch to crashing right above.
296 return QUIC_STREAM_SEQUENCER_INVALID_STATE; 307 return QUIC_STREAM_SEQUENCER_INVALID_STATE;
297 } 308 }
298 memcpy(dest, blocks_[block_idx]->buffer + start_offset_in_block, 309 memcpy(dest, blocks_[block_idx]->buffer + start_offset_in_block,
299 bytes_to_copy); 310 bytes_to_copy);
300 dest += bytes_to_copy; 311 dest += bytes_to_copy;
301 dest_remaining -= bytes_to_copy; 312 dest_remaining -= bytes_to_copy;
302 num_bytes_buffered_ -= bytes_to_copy; 313 num_bytes_buffered_ -= bytes_to_copy;
303 total_bytes_read_ += bytes_to_copy; 314 total_bytes_read_ += bytes_to_copy;
304 *bytes_read += bytes_to_copy; 315 *bytes_read += bytes_to_copy;
305 316
(...skipping 16 matching lines...) Expand all
322 } 333 }
323 334
324 if (*bytes_read > 0) { 335 if (*bytes_read > 0) {
325 UpdateFrameArrivalMap(total_bytes_read_); 336 UpdateFrameArrivalMap(total_bytes_read_);
326 } 337 }
327 return QUIC_NO_ERROR; 338 return QUIC_NO_ERROR;
328 } 339 }
329 340
330 int QuicStreamSequencerBuffer::GetReadableRegions(struct iovec* iov, 341 int QuicStreamSequencerBuffer::GetReadableRegions(struct iovec* iov,
331 int iov_count) const { 342 int iov_count) const {
343 CHECK_EQ(destruction_indicator_, 123456) << "This object has been destructed";
344
332 DCHECK(iov != nullptr); 345 DCHECK(iov != nullptr);
333 DCHECK_GT(iov_count, 0); 346 DCHECK_GT(iov_count, 0);
334 347
335 if (ReadableBytes() == 0) { 348 if (ReadableBytes() == 0) {
336 iov[0].iov_base = nullptr; 349 iov[0].iov_base = nullptr;
337 iov[0].iov_len = 0; 350 iov[0].iov_len = 0;
338 return 0; 351 return 0;
339 } 352 }
340 353
341 size_t start_block_idx = NextBlockToRead(); 354 size_t start_block_idx = NextBlockToRead();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 iov[iov_used].iov_base = blocks_[end_block_idx]->buffer; 393 iov[iov_used].iov_base = blocks_[end_block_idx]->buffer;
381 iov[iov_used].iov_len = end_block_offset + 1; 394 iov[iov_used].iov_len = end_block_offset + 1;
382 DVLOG(1) << "Got last block with index: " << end_block_idx; 395 DVLOG(1) << "Got last block with index: " << end_block_idx;
383 ++iov_used; 396 ++iov_used;
384 } 397 }
385 return iov_used; 398 return iov_used;
386 } 399 }
387 400
388 bool QuicStreamSequencerBuffer::GetReadableRegion(iovec* iov, 401 bool QuicStreamSequencerBuffer::GetReadableRegion(iovec* iov,
389 QuicTime* timestamp) const { 402 QuicTime* timestamp) const {
403 CHECK_EQ(destruction_indicator_, 123456) << "This object has been destructed";
404
390 if (ReadableBytes() == 0) { 405 if (ReadableBytes() == 0) {
391 iov[0].iov_base = nullptr; 406 iov[0].iov_base = nullptr;
392 iov[0].iov_len = 0; 407 iov[0].iov_len = 0;
393 return false; 408 return false;
394 } 409 }
395 410
396 size_t start_block_idx = NextBlockToRead(); 411 size_t start_block_idx = NextBlockToRead();
397 iov->iov_base = blocks_[start_block_idx]->buffer + ReadOffset(); 412 iov->iov_base = blocks_[start_block_idx]->buffer + ReadOffset();
398 size_t readable_bytes_in_block = min<size_t>( 413 size_t readable_bytes_in_block = min<size_t>(
399 GetBlockCapacity(start_block_idx) - ReadOffset(), ReadableBytes()); 414 GetBlockCapacity(start_block_idx) - ReadOffset(), ReadableBytes());
(...skipping 18 matching lines...) Expand all
418 // If encountered the end of readable bytes before reaching a different 433 // If encountered the end of readable bytes before reaching a different
419 // timestamp. 434 // timestamp.
420 DVLOG(1) << "Got all readable bytes in first block."; 435 DVLOG(1) << "Got all readable bytes in first block.";
421 region_len = readable_bytes_in_block; 436 region_len = readable_bytes_in_block;
422 } 437 }
423 iov->iov_len = region_len; 438 iov->iov_len = region_len;
424 return true; 439 return true;
425 } 440 }
426 441
427 bool QuicStreamSequencerBuffer::MarkConsumed(size_t bytes_used) { 442 bool QuicStreamSequencerBuffer::MarkConsumed(size_t bytes_used) {
443 CHECK_EQ(destruction_indicator_, 123456) << "This object has been destructed";
444
428 if (bytes_used > ReadableBytes()) { 445 if (bytes_used > ReadableBytes()) {
429 return false; 446 return false;
430 } 447 }
431 size_t bytes_to_consume = bytes_used; 448 size_t bytes_to_consume = bytes_used;
432 while (bytes_to_consume > 0) { 449 while (bytes_to_consume > 0) {
433 size_t block_idx = NextBlockToRead(); 450 size_t block_idx = NextBlockToRead();
434 size_t offset_in_block = ReadOffset(); 451 size_t offset_in_block = ReadOffset();
435 size_t bytes_available = min<size_t>( 452 size_t bytes_available = min<size_t>(
436 ReadableBytes(), GetBlockCapacity(block_idx) - offset_in_block); 453 ReadableBytes(), GetBlockCapacity(block_idx) - offset_in_block);
437 size_t bytes_read = min<size_t>(bytes_to_consume, bytes_available); 454 size_t bytes_read = min<size_t>(bytes_to_consume, bytes_available);
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 QuicStreamOffset current_frame_end_offset = 599 QuicStreamOffset current_frame_end_offset =
583 it.second.length + current_frame_begin_offset; 600 it.second.length + current_frame_begin_offset;
584 current_frames_string = string(StringPrintf( 601 current_frames_string = string(StringPrintf(
585 "%s[%" PRIu64 ", %" PRIu64 ") ", current_frames_string.c_str(), 602 "%s[%" PRIu64 ", %" PRIu64 ") ", current_frames_string.c_str(),
586 current_frame_begin_offset, current_frame_end_offset)); 603 current_frame_begin_offset, current_frame_end_offset));
587 } 604 }
588 return current_frames_string; 605 return current_frames_string;
589 } 606 }
590 607
591 } // namespace net 608 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698