forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
views: wireup widget name to crash data
And specifically set it when processing windows messages. As almost everything starts from a windows message setting the id when processing a windows message should help us better attribute which code is at fault. BUG=966526 TEST=covered by test Change-Id: I48851150fa55523cffb936d0f2f199ade04cac0e Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1626640 Reviewed-by: Lei Zhang <thestig@chromium.org> Reviewed-by: Michael Wasserman <msw@chromium.org> Commit-Queue: Scott Violet <sky@chromium.org> Cr-Commit-Position: refs/heads/master@{#663079}
- Loading branch information
Scott Violet
authored and
Commit Bot
committed
May 24, 2019
1 parent
ebd4817
commit e7eefcf
Showing
13 changed files
with
263 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
include_rules = [ | ||
"+components/crash", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright 2019 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "ui/gfx/win/crash_id_helper.h" | ||
|
||
#include "base/memory/ptr_util.h" | ||
#include "base/strings/string_util.h" | ||
|
||
namespace gfx { | ||
|
||
// static | ||
CrashIdHelper* CrashIdHelper::Get() { | ||
static base::NoDestructor<CrashIdHelper> helper; | ||
return helper.get(); | ||
} | ||
|
||
CrashIdHelper::ScopedLogger::~ScopedLogger() { | ||
CrashIdHelper::Get()->OnDidProcessMessages(); | ||
} | ||
|
||
CrashIdHelper::ScopedLogger::ScopedLogger() = default; | ||
|
||
std::unique_ptr<CrashIdHelper::ScopedLogger> | ||
CrashIdHelper::OnWillProcessMessages(const std::string& id) { | ||
if (!ids_.empty()) | ||
was_nested_ = true; | ||
ids_.push_back(id.empty() ? "unspecified" : id); | ||
debugging_crash_key_.Set(CurrentCrashId()); | ||
// base::WrapUnique() as constructor is private. | ||
return base::WrapUnique(new ScopedLogger); | ||
} | ||
|
||
void CrashIdHelper::OnDidProcessMessages() { | ||
DCHECK(!ids_.empty()); | ||
ids_.pop_back(); | ||
if (ids_.empty()) { | ||
debugging_crash_key_.Clear(); | ||
was_nested_ = false; | ||
} else { | ||
debugging_crash_key_.Set(CurrentCrashId()); | ||
} | ||
} | ||
|
||
CrashIdHelper::CrashIdHelper() = default; | ||
|
||
CrashIdHelper::~CrashIdHelper() = default; | ||
|
||
std::string CrashIdHelper::CurrentCrashId() const { | ||
// This should only be called when there is at least one id. | ||
DCHECK(!ids_.empty()); | ||
// Common case is only one id. | ||
if (ids_.size() == 1) { | ||
// If the size of |ids_| is 1, then the message loop is not nested. If | ||
// |was_nested_| is true, it means in processing the message corresponding | ||
// to ids_[0] another message was processed, resulting in nested message | ||
// loops. A nested message loop can lead to reentrancy and/or problems when | ||
// the stack unravels. For example, it's entirely possible that when a | ||
// nested message loop completes, objects further up in the stack have been | ||
// deleted. "(N)" is added to signify that a nested message loop was run at | ||
// some point during the current message loop. | ||
return was_nested_ ? "(N) " + ids_[0] : ids_[0]; | ||
} | ||
return base::JoinString(ids_, ">"); | ||
} | ||
|
||
} // namespace gfx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// Copyright 2019 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef UI_GFX_WIN_CRASH_ID_HELPER_H_ | ||
#define UI_GFX_WIN_CRASH_ID_HELPER_H_ | ||
|
||
#include <string> | ||
#include <vector> | ||
|
||
#include "base/macros.h" | ||
#include "base/no_destructor.h" | ||
#include "components/crash/core/common/crash_key.h" | ||
#include "ui/gfx/gfx_export.h" | ||
|
||
namespace gfx { | ||
|
||
// CrashIdHelper is used to log (in crash dumps) the id(s) of the window/widget | ||
// currently dispatching an event. Often times crashes occur purely in ui | ||
// code, while the bug lies in client code. Logging an id helps better identify | ||
// the client code that created the window/widget. | ||
// | ||
// Example usage: | ||
// { | ||
// auto logger = CrashIdHelper::Get()->OnWillProcessMessages(crash_id); | ||
// <do message processing> | ||
// } | ||
class GFX_EXPORT CrashIdHelper { | ||
public: | ||
static CrashIdHelper* Get(); | ||
|
||
// RAII style class that unregisters in the destructor. | ||
class GFX_EXPORT ScopedLogger { | ||
public: | ||
~ScopedLogger(); | ||
|
||
private: | ||
friend class CrashIdHelper; | ||
ScopedLogger(); | ||
|
||
DISALLOW_COPY_AND_ASSIGN(ScopedLogger); | ||
}; | ||
|
||
// Adds |id| to the list of active debugging ids. When the returned object | ||
// is destroyed, |id| is removed from the list of active debugging ids. | ||
std::unique_ptr<ScopedLogger> OnWillProcessMessages(const std::string& id); | ||
|
||
private: | ||
friend base::NoDestructor<CrashIdHelper>; | ||
friend class CrashIdHelperTest; | ||
|
||
CrashIdHelper(); | ||
~CrashIdHelper(); | ||
|
||
// Called from ~ScopedLogger. Removes the most recently added id. | ||
void OnDidProcessMessages(); | ||
|
||
// Returns the identifier to put in the crash key. | ||
std::string CurrentCrashId() const; | ||
|
||
// Ordered list of debugging identifiers added. | ||
std::vector<std::string> ids_; | ||
|
||
// Set to true once |ids_| has more than one object, and false once |ids_| is | ||
// empty. That is, this is true once processing the windows message resulted | ||
// in processing another windows message (nested message loops). See comment | ||
// in implementation of CurrentCrashId() as to why this is tracked. | ||
bool was_nested_ = false; | ||
|
||
// This uses the name 'widget' as this code is most commonly triggered from | ||
// views, which uses the term Widget. | ||
crash_reporter::CrashKeyString<128> debugging_crash_key_{"widget-id"}; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(CrashIdHelper); | ||
}; | ||
|
||
} // namespace gfx | ||
|
||
#endif // UI_GFX_WIN_CRASH_ID_HELPER_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright 2019 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "ui/gfx/win/crash_id_helper.h" | ||
|
||
#include "testing/gtest/include/gtest/gtest.h" | ||
|
||
namespace gfx { | ||
|
||
class CrashIdHelperTest : public testing::Test { | ||
public: | ||
CrashIdHelperTest() = default; | ||
~CrashIdHelperTest() override = default; | ||
|
||
std::string CurrentCrashId() { | ||
return CrashIdHelper::Get()->CurrentCrashId(); | ||
} | ||
|
||
private: | ||
DISALLOW_COPY_AND_ASSIGN(CrashIdHelperTest); | ||
}; | ||
|
||
// This test verifies CurrentCrashId(). Ideally this would verify at | ||
// crash_reporter::CrashKeyString, but that class isn't particularly test | ||
// friendly (and the implementation varies depending upon compile time flags). | ||
TEST_F(CrashIdHelperTest, Basic) { | ||
const std::string id1 = "id"; | ||
{ | ||
auto scoper = CrashIdHelper::Get()->OnWillProcessMessages(id1); | ||
EXPECT_EQ(id1, CurrentCrashId()); | ||
} | ||
|
||
// No assertions for empty as CurrentCrashId() DCHECKs there is at least | ||
// one id. | ||
|
||
const std::string id2 = "id2"; | ||
{ | ||
auto scoper = CrashIdHelper::Get()->OnWillProcessMessages(id2); | ||
EXPECT_EQ(id2, CurrentCrashId()); | ||
|
||
{ | ||
auto scoper2 = CrashIdHelper::Get()->OnWillProcessMessages(id1); | ||
EXPECT_EQ("id2>id", CurrentCrashId()); | ||
} | ||
EXPECT_EQ("(N) id2", CurrentCrashId()); | ||
} | ||
} | ||
|
||
} // namespace gfx |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.