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

Side by Side Diff: base/win/wait_chain.cc

Issue 1834463002: Identify the hung thread using the Wait Chain Traversal API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added dcheck Created 4 years, 8 months 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
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/win/wait_chain.h"
6
7 #include <memory>
8
9 #include "base/logging.h"
10 #include "base/strings/stringprintf.h"
11
12 namespace base {
13 namespace win {
14
15 namespace {
16
17 // Helper deleter to hold a HWCT into a unique_ptr.
18 struct WaitChainSessionDeleter {
19 using pointer = HWCT;
20 void operator()(HWCT session_handle) {
grt (UTC plus 2) 2016/04/12 14:31:12 const methods
Patrick Monette 2016/04/12 19:13:00 Done.
21 ::CloseThreadWaitChainSession(session_handle);
22 }
23 };
24 using ScopedWaitChainSessionHandle =
grt (UTC plus 2) 2016/04/12 14:31:12 nit: blank line before this
Patrick Monette 2016/04/12 19:13:00 Done.
25 std::unique_ptr<HWCT, WaitChainSessionDeleter>;
26
27 const wchar_t* WctObjectTypeToString(WCT_OBJECT_TYPE type) {
28 switch (type) {
29 case WctCriticalSectionType:
30 return L"CriticalSection";
31 case WctSendMessageType:
32 return L"SendMessage";
33 case WctMutexType:
34 return L"Mutex";
35 case WctAlpcType:
36 return L"Alpc";
37 case WctComType:
38 return L"Com";
39 case WctThreadWaitType:
40 return L"ThreadWait";
41 case WctProcessWaitType:
42 return L"ProcessWait";
43 case WctThreadType:
44 return L"Thread";
45 case WctComActivationType:
46 return L"ComActivation";
47 case WctUnknownType:
48 return L"Unknown";
49 default:
grt (UTC plus 2) 2016/04/12 14:31:12 can you leave off the "default" case so that there
Patrick Monette 2016/04/12 19:13:00 Done.
50 NOTREACHED();
51 return L"";
52 }
53 }
54
55 const wchar_t* WctObjectStatusToString(WCT_OBJECT_STATUS status) {
56 switch (status) {
57 case WctStatusNoAccess:
58 return L"NoAccess";
59 case WctStatusRunning:
60 return L"Running";
61 case WctStatusBlocked:
62 return L"Blocked";
63 case WctStatusPidOnly:
64 return L"PidOnly";
65 case WctStatusPidOnlyRpcss:
66 return L"PidOnlyRpcss";
67 case WctStatusOwned:
68 return L"Owned";
69 case WctStatusNotOwned:
70 return L"NotOwned";
71 case WctStatusAbandoned:
72 return L"Abandoned";
73 case WctStatusUnknown:
74 return L"Unknown";
75 case WctStatusError:
76 return L"Error";
77 default:
grt (UTC plus 2) 2016/04/12 14:31:12 same here?
Patrick Monette 2016/04/12 19:13:00 Done.
78 NOTREACHED();
79 return L"";
80 }
81 }
82
83 } // namespace
84
85 bool GetThreadWaitChain(DWORD thread_id,
86 WaitChain* wait_chain,
87 bool* is_deadlock) {
88 DCHECK(wait_chain);
89 DCHECK(is_deadlock);
90
91 // Open a synchronous session.
92 ScopedWaitChainSessionHandle session_handle(
93 ::OpenThreadWaitChainSession(0, nullptr));
94 if (!session_handle) {
95 DPLOG(ERROR) << "Failed to create the Wait Chain session";
96 return false;
97 }
98
99 DWORD nb_nodes = WCT_MAX_NODE_COUNT;
100 wait_chain->resize(nb_nodes);
101 BOOL is_cycle;
102 if (!::GetThreadWaitChain(session_handle.get(), NULL, 0, thread_id, &nb_nodes,
103 wait_chain->data(), &is_cycle)) {
104 DPLOG(ERROR) << "Failed to get the thread wait chain";
105 return false;
106 }
107
108 *is_deadlock = is_cycle ? true : false;
109 wait_chain->resize(nb_nodes);
110
111 return true;
112 }
113
114 std::wstring WaitChainNodeToString(const WAITCHAIN_NODE_INFO& node) {
115 if (node.ObjectType == WctThreadType) {
116 return base::StringPrintf(L"Thread %d in process %d with status %ls",
117 node.ThreadObject.ThreadId,
118 node.ThreadObject.ProcessId,
119 WctObjectStatusToString(node.ObjectStatus));
120 } else {
121 return base::StringPrintf(L"Lock of type %ls with status %ls",
122 WctObjectTypeToString(node.ObjectType),
123 WctObjectStatusToString(node.ObjectStatus));
124 }
125 }
126
127 } // namespace win
128 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698