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

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: Grt comments 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) 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 }
51 NOTREACHED();
52 return L"";
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 }
78 NOTREACHED();
79 return L"";
80 }
81
82 } // namespace
83
84 bool GetThreadWaitChain(DWORD thread_id,
85 WaitChainNodeVector* wait_chain,
86 bool* is_deadlock) {
87 DCHECK(wait_chain);
88 DCHECK(is_deadlock);
89
90 // Open a synchronous session.
91 ScopedWaitChainSessionHandle session_handle(
92 ::OpenThreadWaitChainSession(0, nullptr));
93 if (!session_handle) {
94 DPLOG(ERROR) << "Failed to create the Wait Chain session";
95 return false;
96 }
97
98 DWORD nb_nodes = WCT_MAX_NODE_COUNT;
99 wait_chain->resize(nb_nodes);
100 BOOL is_cycle;
101 if (!::GetThreadWaitChain(session_handle.get(), NULL, 0, thread_id, &nb_nodes,
102 wait_chain->data(), &is_cycle)) {
103 DPLOG(ERROR) << "Failed to get the thread wait chain";
104 return false;
105 }
106
107 *is_deadlock = is_cycle ? true : false;
108 wait_chain->resize(nb_nodes);
109
110 return true;
111 }
112
113 std::wstring WaitChainNodeToString(const WAITCHAIN_NODE_INFO& node) {
114 if (node.ObjectType == WctThreadType) {
115 return base::StringPrintf(L"Thread %d in process %d with status %ls",
116 node.ThreadObject.ThreadId,
117 node.ThreadObject.ProcessId,
118 WctObjectStatusToString(node.ObjectStatus));
119 } else {
120 return base::StringPrintf(L"Lock of type %ls with status %ls",
121 WctObjectTypeToString(node.ObjectType),
122 WctObjectStatusToString(node.ObjectStatus));
123 }
124 }
125
126 } // namespace win
127 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698