Skip to content

Commit

Permalink
fix: panic in pop_frame()
Browse files Browse the repository at this point in the history
    We met the panic in our production environment, so handle this panic
    condition before panic. stack backtrace:
       0: rust_begin_unwind
                 at
    /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/panicking.rs:517:5
       1: core::panicking::panic_fmt
                 at
    /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/panicking.rs:101:14
       2: core::panicking::panic
                 at
    /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/panicking.rs:50:5
       3: h2::proto::streams::flow_control::FlowControl::send_data
                 at
    /build/vendor/h2/src/proto/streams/flow_control.rs:176:9
       4: h2::proto::streams::prioritize::Prioritize::pop_frame::{{closure}}
                 at
    /build/vendor/h2/src/proto/streams/prioritize.rs:737:33
       5: tracing::span::Span::in_scope
                 at /build/vendor/tracing/src/span.rs:982:9
       6: h2::proto::streams::prioritize::Prioritize::pop_frame
                 at
    /build/vendor/h2/src/proto/streams/prioritize.rs:736:29
       7: h2::proto::streams::prioritize::Prioritize::poll_complete
                 at
    /build/vendor/h2/src/proto/streams/prioritize.rs:497:19
       8: h2::proto::streams::send::Send::poll_complete
                 at /build/vendor/h2/src/proto/streams/send.rs:297:9
       9: h2::proto::streams::streams::Inner::poll_complete
                 at /build/vendor/h2/src/proto/streams/streams.rs:850:16
      10: h2::proto::streams::streams::Streams<B,P>::poll_complete
                 at /build/vendor/h2/src/proto/streams/streams.rs:180:9
      11: h2::proto::connection::Connection<T,P,B>::poll
                 at /build/vendor/h2/src/proto/connection.rs:253:36
      12: <h2::client::Connection<T,B> as
    core::future::future::Future>::poll
      13: ...
  • Loading branch information
winters.zc committed Jan 6, 2023
1 parent 07d20b1 commit d312edf
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
18 changes: 13 additions & 5 deletions src/proto/streams/flow_control.rs
Expand Up @@ -61,6 +61,11 @@ impl FlowControl {
self.window_size.as_size()
}

/// Check if send window is available
pub fn window_available(&mut self, sz: WindowSize) -> bool {
self.window_size >= sz as usize
}

/// Returns the window size available to the consumer
pub fn available(&self) -> Window {
self.available
Expand Down Expand Up @@ -173,12 +178,15 @@ impl FlowControl {
self.available
);

// Ensure that the argument is correct
assert!(self.window_size >= sz as usize);
// If send size is zero it's meaningless to update flow control window
if sz > 0 {
// Ensure that the argument is correct
assert!(self.window_size >= sz as usize);

// Update values
self.window_size -= sz;
self.available -= sz;
// Update values
self.window_size -= sz;
self.available -= sz;
}
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/proto/streams/prioritize.rs
Expand Up @@ -744,6 +744,14 @@ impl Prioritize {
// capacity at this point.
debug_assert!(len <= self.flow.window_size());

// Check if the stream level window the peer knows is available. In some
// scenarios, maybe the window we know is available but the window which
// peer knows is not.
if len > 0 && !stream.send_flow.window_available(len) {
stream.pending_send.push_front(buffer, frame.into());
continue;
}

tracing::trace!(len, "sending data frame");

// Update the flow control
Expand Down

0 comments on commit d312edf

Please sign in to comment.