Commit 27b2b57c authored by yhirano's avatar yhirano Committed by Commit bot

[WebSocket] Add NOINLINE function calls to see the stack trace.

We have a crash bug related to redirection, but I couln't understand the
mechanism so far. This CL adds some functions to see the actual path from the
crash dump.

BUG=399535

Review URL: https://codereview.chromium.org/683923003

Cr-Commit-Position: refs/heads/master@{#302069}
parent b3a93a67
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/base64.h" #include "base/base64.h"
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/containers/hash_tables.h" #include "base/containers/hash_tables.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/metrics/histogram.h" #include "base/metrics/histogram.h"
...@@ -46,6 +47,35 @@ ...@@ -46,6 +47,35 @@
namespace net { namespace net {
namespace {
// TODO(yhirano): Remove these functions once http://crbug.com/399535 is fixed.
NOINLINE void RunCallbackWithOk(const CompletionCallback& callback,
int result) {
DCHECK_EQ(result, OK);
callback.Run(OK);
}
NOINLINE void RunCallbackWithInvalidResponseCausedByRedirect(
const CompletionCallback& callback,
int result) {
DCHECK_EQ(result, ERR_INVALID_RESPONSE);
callback.Run(ERR_INVALID_RESPONSE);
}
NOINLINE void RunCallbackWithInvalidResponse(
const CompletionCallback& callback,
int result) {
DCHECK_EQ(result, ERR_INVALID_RESPONSE);
callback.Run(ERR_INVALID_RESPONSE);
}
NOINLINE void RunCallback(const CompletionCallback& callback, int result) {
callback.Run(result);
}
} // namespace
// TODO(ricea): If more extensions are added, replace this with a more general // TODO(ricea): If more extensions are added, replace this with a more general
// mechanism. // mechanism.
struct WebSocketExtensionParams { struct WebSocketExtensionParams {
...@@ -430,7 +460,8 @@ int WebSocketBasicHandshakeStream::ReadResponseHeaders( ...@@ -430,7 +460,8 @@ int WebSocketBasicHandshakeStream::ReadResponseHeaders(
callback)); callback));
if (rv == ERR_IO_PENDING) if (rv == ERR_IO_PENDING)
return rv; return rv;
return ValidateResponse(rv); bool is_redirect = false;
return ValidateResponse(rv, &is_redirect);
} }
int WebSocketBasicHandshakeStream::ReadResponseBody( int WebSocketBasicHandshakeStream::ReadResponseBody(
...@@ -535,7 +566,25 @@ void WebSocketBasicHandshakeStream::SetWebSocketKeyForTesting( ...@@ -535,7 +566,25 @@ void WebSocketBasicHandshakeStream::SetWebSocketKeyForTesting(
void WebSocketBasicHandshakeStream::ReadResponseHeadersCallback( void WebSocketBasicHandshakeStream::ReadResponseHeadersCallback(
const CompletionCallback& callback, const CompletionCallback& callback,
int result) { int result) {
callback.Run(ValidateResponse(result)); bool is_redirect = false;
int rv = ValidateResponse(result, &is_redirect);
// TODO(yhirano): Simplify this statement once http://crbug.com/399535 is
// fixed.
switch (rv) {
case OK:
RunCallbackWithOk(callback, rv);
break;
case ERR_INVALID_RESPONSE:
if (is_redirect)
RunCallbackWithInvalidResponseCausedByRedirect(callback, rv);
else
RunCallbackWithInvalidResponse(callback, rv);
break;
default:
RunCallback(callback, rv);
break;
}
} }
void WebSocketBasicHandshakeStream::OnFinishOpeningHandshake() { void WebSocketBasicHandshakeStream::OnFinishOpeningHandshake() {
...@@ -546,14 +595,17 @@ void WebSocketBasicHandshakeStream::OnFinishOpeningHandshake() { ...@@ -546,14 +595,17 @@ void WebSocketBasicHandshakeStream::OnFinishOpeningHandshake() {
http_response_info_->response_time); http_response_info_->response_time);
} }
int WebSocketBasicHandshakeStream::ValidateResponse(int rv) { int WebSocketBasicHandshakeStream::ValidateResponse(int rv,
bool* is_redirect) {
DCHECK(http_response_info_); DCHECK(http_response_info_);
*is_redirect = false;
// Most net errors happen during connection, so they are not seen by this // Most net errors happen during connection, so they are not seen by this
// method. The histogram for error codes is created in // method. The histogram for error codes is created in
// Delegate::OnResponseStarted in websocket_stream.cc instead. // Delegate::OnResponseStarted in websocket_stream.cc instead.
if (rv >= 0) { if (rv >= 0) {
const HttpResponseHeaders* headers = http_response_info_->headers.get(); const HttpResponseHeaders* headers = http_response_info_->headers.get();
const int response_code = headers->response_code(); const int response_code = headers->response_code();
*is_redirect = HttpResponseHeaders::IsRedirectResponseCode(response_code);
UMA_HISTOGRAM_SPARSE_SLOWLY("Net.WebSocket.ResponseCode", response_code); UMA_HISTOGRAM_SPARSE_SLOWLY("Net.WebSocket.ResponseCode", response_code);
switch (response_code) { switch (response_code) {
case HTTP_SWITCHING_PROTOCOLS: case HTTP_SWITCHING_PROTOCOLS:
......
...@@ -84,7 +84,7 @@ class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream ...@@ -84,7 +84,7 @@ class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream
void OnFinishOpeningHandshake(); void OnFinishOpeningHandshake();
// Validates the response and sends the finished handshake event. // Validates the response and sends the finished handshake event.
int ValidateResponse(int rv); int ValidateResponse(int rv, bool* is_redirect);
// Check that the headers are well-formed for a 101 response, and returns // Check that the headers are well-formed for a 101 response, and returns
// OK if they are, otherwise returns ERR_INVALID_RESPONSE. // OK if they are, otherwise returns ERR_INVALID_RESPONSE.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment