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

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: BASE_EXPORT 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
« no previous file with comments | « base/win/wait_chain.h ('k') | base/win/wait_chain_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) const {
21 ::CloseThreadWaitChainSession(session_handle);
22 }
23 };
24
25 using ScopedWaitChainSessionHandle =
26 std::unique_ptr<HWCT, WaitChainSessionDeleter>;
27
28 const wchar_t* WctObjectTypeToString(WCT_OBJECT_TYPE type) {
29 switch (type) {
30 case WctCriticalSectionType:
31 return L"CriticalSection";
32 case WctSendMessageType:
33 return L"SendMessage";
34 case WctMutexType:
35 return L"Mutex";
36 case WctAlpcType:
37 return L"Alpc";
38 case WctComType:
39 return L"Com";
40 case WctThreadWaitType:
41 return L"ThreadWait";
42 case WctProcessWaitType:
43 return L"ProcessWait";
44 case WctThreadType:
45 return L"Thread";
46 case WctComActivationType:
47 return L"ComActivation";
48 case WctUnknownType:
49 return L"Unknown";
50 case WctSocketIoType:
51 return L"SocketIo";
52 case WctSmbIoType:
53 return L"SmbIo";
54 case WctMaxType:
55 break;
56 }
57 NOTREACHED();
58 return L"";
59 }
60
61 const wchar_t* WctObjectStatusToString(WCT_OBJECT_STATUS status) {
62 switch (status) {
63 case WctStatusNoAccess:
64 return L"NoAccess";
65 case WctStatusRunning:
66 return L"Running";
67 case WctStatusBlocked:
68 return L"Blocked";
69 case WctStatusPidOnly:
70 return L"PidOnly";
71 case WctStatusPidOnlyRpcss:
72 return L"PidOnlyRpcss";
73 case WctStatusOwned:
74 return L"Owned";
75 case WctStatusNotOwned:
76 return L"NotOwned";
77 case WctStatusAbandoned:
78 return L"Abandoned";
79 case WctStatusUnknown:
80 return L"Unknown";
81 case WctStatusError:
82 return L"Error";
83 case WctStatusMax:
84 break;
85 }
86 NOTREACHED();
87 return L"";
88 }
89
90 } // namespace
91
92 bool GetThreadWaitChain(DWORD thread_id,
93 WaitChainNodeVector* wait_chain,
94 bool* is_deadlock) {
95 DCHECK(wait_chain);
96 DCHECK(is_deadlock);
97
98 // Open a synchronous session.
99 ScopedWaitChainSessionHandle session_handle(
100 ::OpenThreadWaitChainSession(0, nullptr));
101 if (!session_handle) {
102 DPLOG(ERROR) << "Failed to create the Wait Chain session";
103 return false;
104 }
105
106 DWORD nb_nodes = WCT_MAX_NODE_COUNT;
107 wait_chain->resize(nb_nodes);
108 BOOL is_cycle;
109 if (!::GetThreadWaitChain(session_handle.get(), NULL, 0, thread_id, &nb_nodes,
110 wait_chain->data(), &is_cycle)) {
111 DPLOG(ERROR) << "Failed to get the thread wait chain";
112 return false;
113 }
114
115 *is_deadlock = is_cycle ? true : false;
116 wait_chain->resize(nb_nodes);
117
118 return true;
119 }
120
121 base::string16 WaitChainNodeToString(const WAITCHAIN_NODE_INFO& node) {
122 if (node.ObjectType == WctThreadType) {
123 return base::StringPrintf(L"Thread %d in process %d with status %ls",
124 node.ThreadObject.ThreadId,
125 node.ThreadObject.ProcessId,
126 WctObjectStatusToString(node.ObjectStatus));
127 } else {
128 return base::StringPrintf(L"Lock of type %ls with status %ls",
129 WctObjectTypeToString(node.ObjectType),
130 WctObjectStatusToString(node.ObjectStatus));
131 }
132 }
133
134 } // namespace win
135 } // namespace base
OLDNEW
« no previous file with comments | « base/win/wait_chain.h ('k') | base/win/wait_chain_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698