mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
Improve crash reporting of frame connection retry failures (see #3664)
Introduce different call stacks for different types of disconnects, and log additional state information in the FATAL message.
This commit is contained in:
@ -422,7 +422,7 @@ void CefFrameImpl::OnDetached() {
|
|||||||
browser_->FrameDetached(frame_);
|
browser_->FrameDetached(frame_);
|
||||||
frame_ = nullptr;
|
frame_ = nullptr;
|
||||||
|
|
||||||
OnDisconnect(DisconnectReason::DETACHED);
|
OnDisconnect(DisconnectReason::DETACHED, std::string());
|
||||||
|
|
||||||
browser_ = nullptr;
|
browser_ = nullptr;
|
||||||
|
|
||||||
@ -511,9 +511,8 @@ void CefFrameImpl::ConnectBrowserFrame(ConnectReason reason) {
|
|||||||
// connection.
|
// connection.
|
||||||
browser_frame->FrameAttached(receiver_.BindNewPipeAndPassRemote(),
|
browser_frame->FrameAttached(receiver_.BindNewPipeAndPassRemote(),
|
||||||
reattached);
|
reattached);
|
||||||
receiver_.set_disconnect_handler(
|
receiver_.set_disconnect_with_reason_handler(
|
||||||
base::BindOnce(&CefFrameImpl::OnDisconnect, this,
|
base::BindOnce(&CefFrameImpl::OnRenderFrameDisconnect, this));
|
||||||
DisconnectReason::RENDER_FRAME_DISCONNECT));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const mojo::Remote<cef::mojom::BrowserFrame>& CefFrameImpl::GetBrowserFrame(
|
const mojo::Remote<cef::mojom::BrowserFrame>& CefFrameImpl::GetBrowserFrame(
|
||||||
@ -527,9 +526,8 @@ const mojo::Remote<cef::mojom::BrowserFrame>& CefFrameImpl::GetBrowserFrame(
|
|||||||
// Triggers creation of a CefBrowserFrame in the browser process.
|
// Triggers creation of a CefBrowserFrame in the browser process.
|
||||||
render_frame->GetBrowserInterfaceBroker()->GetInterface(
|
render_frame->GetBrowserInterfaceBroker()->GetInterface(
|
||||||
browser_frame_.BindNewPipeAndPassReceiver());
|
browser_frame_.BindNewPipeAndPassReceiver());
|
||||||
browser_frame_.set_disconnect_handler(
|
browser_frame_.set_disconnect_with_reason_handler(
|
||||||
base::BindOnce(&CefFrameImpl::OnDisconnect, this,
|
base::BindOnce(&CefFrameImpl::OnBrowserFrameDisconnect, this));
|
||||||
DisconnectReason::BROWSER_FRAME_DISCONNECT));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return browser_frame_;
|
return browser_frame_;
|
||||||
@ -537,19 +535,25 @@ const mojo::Remote<cef::mojom::BrowserFrame>& CefFrameImpl::GetBrowserFrame(
|
|||||||
|
|
||||||
void CefFrameImpl::OnBrowserFrameTimeout() {
|
void CefFrameImpl::OnBrowserFrameTimeout() {
|
||||||
LOG(ERROR) << frame_debug_str_ << " connection timeout";
|
LOG(ERROR) << frame_debug_str_ << " connection timeout";
|
||||||
OnDisconnect(DisconnectReason::CONNECT_TIMEOUT);
|
OnDisconnect(DisconnectReason::CONNECT_TIMEOUT, std::string());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameImpl::OnDisconnect(DisconnectReason reason) {
|
void CefFrameImpl::OnBrowserFrameDisconnect(uint32_t custom_reason,
|
||||||
// Ignore multiple calls in close proximity (which may occur if both
|
const std::string& description) {
|
||||||
// |browser_frame_| and |receiver_| disconnect). |frame_| will be nullptr
|
OnDisconnect(DisconnectReason::BROWSER_FRAME_DISCONNECT, description);
|
||||||
// when called from/after OnDetached().
|
|
||||||
if (frame_ &&
|
|
||||||
browser_connection_state_ == ConnectionState::RECONNECT_PENDING) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VLOG_IS_ON(1)) {
|
void CefFrameImpl::OnRenderFrameDisconnect(uint32_t custom_reason,
|
||||||
|
const std::string& description) {
|
||||||
|
OnDisconnect(DisconnectReason::RENDER_FRAME_DISCONNECT, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
std::string CefFrameImpl::GetDisconnectDebugString(
|
||||||
|
ConnectionState connection_state,
|
||||||
|
bool frame_is_valid,
|
||||||
|
DisconnectReason reason,
|
||||||
|
const std::string& description) {
|
||||||
std::string reason_str;
|
std::string reason_str;
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case DisconnectReason::DETACHED:
|
case DisconnectReason::DETACHED:
|
||||||
@ -570,7 +574,7 @@ void CefFrameImpl::OnDisconnect(DisconnectReason reason) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::string state_str;
|
std::string state_str;
|
||||||
switch (browser_connection_state_) {
|
switch (connection_state) {
|
||||||
case ConnectionState::DISCONNECTED:
|
case ConnectionState::DISCONNECTED:
|
||||||
state_str = "DISCONNECTED";
|
state_str = "DISCONNECTED";
|
||||||
break;
|
break;
|
||||||
@ -585,14 +589,33 @@ void CefFrameImpl::OnDisconnect(DisconnectReason reason) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!frame_) {
|
if (!frame_is_valid) {
|
||||||
state_str += ", FRAME_INVALID";
|
state_str += ", FRAME_INVALID";
|
||||||
}
|
}
|
||||||
|
|
||||||
VLOG(1) << frame_debug_str_ << " disconnected (reason=" << reason_str
|
if (!description.empty()) {
|
||||||
<< ", current_state=" << state_str << ")";
|
state_str += ", " + description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return "(reason=" + reason_str + ", current_state=" + state_str + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefFrameImpl::OnDisconnect(DisconnectReason reason,
|
||||||
|
const std::string& description) {
|
||||||
|
// Ignore multiple calls in close proximity (which may occur if both
|
||||||
|
// |browser_frame_| and |receiver_| disconnect). |frame_| will be nullptr
|
||||||
|
// when called from/after OnDetached().
|
||||||
|
if (frame_ &&
|
||||||
|
browser_connection_state_ == ConnectionState::RECONNECT_PENDING) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto connection_state = browser_connection_state_;
|
||||||
|
const bool frame_is_valid = !!frame_;
|
||||||
|
VLOG(1) << frame_debug_str_ << " disconnected "
|
||||||
|
<< GetDisconnectDebugString(connection_state, frame_is_valid,
|
||||||
|
reason, description);
|
||||||
|
|
||||||
browser_frame_.reset();
|
browser_frame_.reset();
|
||||||
receiver_.reset();
|
receiver_.reset();
|
||||||
browser_connection_state_ = ConnectionState::DISCONNECTED;
|
browser_connection_state_ = ConnectionState::DISCONNECTED;
|
||||||
@ -617,7 +640,9 @@ void CefFrameImpl::OnDisconnect(DisconnectReason reason) {
|
|||||||
ConnectReason::RETRY));
|
ConnectReason::RETRY));
|
||||||
} else {
|
} else {
|
||||||
// Trigger a crash in official builds.
|
// Trigger a crash in official builds.
|
||||||
LOG(FATAL) << frame_debug_str_ << " connection retry failed";
|
LOG(FATAL) << frame_debug_str_ << " connection retry failed "
|
||||||
|
<< GetDisconnectDebugString(connection_state, frame_is_valid,
|
||||||
|
reason, description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -690,7 +715,7 @@ void CefFrameImpl::FrameAttachedAck() {
|
|||||||
void CefFrameImpl::FrameDetached() {
|
void CefFrameImpl::FrameDetached() {
|
||||||
// Sent from the browser process in response to CefFrameHostImpl::Detach().
|
// Sent from the browser process in response to CefFrameHostImpl::Detach().
|
||||||
CHECK_EQ(ConnectionState::CONNECTION_ACKED, browser_connection_state_);
|
CHECK_EQ(ConnectionState::CONNECTION_ACKED, browser_connection_state_);
|
||||||
OnDisconnect(DisconnectReason::BROWSER_FRAME_DETACHED);
|
OnDisconnect(DisconnectReason::BROWSER_FRAME_DETACHED, std::string());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefFrameImpl::SendMessage(const std::string& name,
|
void CefFrameImpl::SendMessage(const std::string& name,
|
||||||
|
@ -116,6 +116,13 @@ class CefFrameImpl
|
|||||||
// Called if the BrowserFrame connection attempt times out.
|
// Called if the BrowserFrame connection attempt times out.
|
||||||
void OnBrowserFrameTimeout();
|
void OnBrowserFrameTimeout();
|
||||||
|
|
||||||
|
// Called if the BrowserFrame connection is disconnected.
|
||||||
|
void OnBrowserFrameDisconnect(uint32_t custom_reason,
|
||||||
|
const std::string& description);
|
||||||
|
// Called if the RenderFrame connection is disconnected.
|
||||||
|
void OnRenderFrameDisconnect(uint32_t custom_reason,
|
||||||
|
const std::string& description);
|
||||||
|
|
||||||
enum class DisconnectReason {
|
enum class DisconnectReason {
|
||||||
DETACHED,
|
DETACHED,
|
||||||
BROWSER_FRAME_DETACHED,
|
BROWSER_FRAME_DETACHED,
|
||||||
@ -127,7 +134,7 @@ class CefFrameImpl
|
|||||||
// Called if/when a disconnect occurs. This may occur due to frame navigation,
|
// Called if/when a disconnect occurs. This may occur due to frame navigation,
|
||||||
// destruction, or insertion into the bfcache (when the browser-side frame
|
// destruction, or insertion into the bfcache (when the browser-side frame
|
||||||
// representation is destroyed and closes the connection).
|
// representation is destroyed and closes the connection).
|
||||||
void OnDisconnect(DisconnectReason reason);
|
void OnDisconnect(DisconnectReason reason, const std::string& description);
|
||||||
|
|
||||||
// Send an action to the remote BrowserFrame. This will queue the action if
|
// Send an action to the remote BrowserFrame. This will queue the action if
|
||||||
// the remote frame is not yet attached.
|
// the remote frame is not yet attached.
|
||||||
@ -181,6 +188,11 @@ class CefFrameImpl
|
|||||||
RECONNECT_PENDING,
|
RECONNECT_PENDING,
|
||||||
} browser_connection_state_ = ConnectionState::DISCONNECTED;
|
} browser_connection_state_ = ConnectionState::DISCONNECTED;
|
||||||
|
|
||||||
|
static std::string GetDisconnectDebugString(ConnectionState connection_state,
|
||||||
|
bool frame_is_valid,
|
||||||
|
DisconnectReason reason,
|
||||||
|
const std::string& description);
|
||||||
|
|
||||||
base::OneShotTimer browser_connect_timer_;
|
base::OneShotTimer browser_connect_timer_;
|
||||||
|
|
||||||
std::queue<std::pair<std::string, BrowserFrameAction>>
|
std::queue<std::pair<std::string, BrowserFrameAction>>
|
||||||
|
Reference in New Issue
Block a user