1 // Copyright (c) 2012 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.
5 #include "base/win/scoped_handle.h"
7 #include <unordered_map>
9 #include "base/debug/alias.h"
10 #include "base/hash.h"
11 #include "base/lazy_instance.h"
12 #include "base/logging.h"
13 #include "base/synchronization/lock_impl.h"
16 __declspec(dllexport
) void* GetHandleVerifier();
17 typedef void* (*GetHandleVerifierFn
)();
23 size_t operator()(const HANDLE
& handle
) const {
24 char buffer
[sizeof(handle
)];
25 memcpy(buffer
, &handle
, sizeof(handle
));
26 return base::Hash(buffer
, sizeof(buffer
));
36 typedef std::unordered_map
<HANDLE
, Info
, HandleHash
> HandleMap
;
38 // g_lock protects the handle map and setting g_active_verifier.
39 typedef base::internal::LockImpl NativeLock
;
40 base::LazyInstance
<NativeLock
>::Leaky g_lock
= LAZY_INSTANCE_INITIALIZER
;
42 bool CloseHandleWrapper(HANDLE handle
) {
43 if (!::CloseHandle(handle
))
48 // Simple automatic locking using a native critical section so it supports
50 class AutoNativeLock
{
52 explicit AutoNativeLock(NativeLock
& lock
) : lock_(lock
) {
62 DISALLOW_COPY_AND_ASSIGN(AutoNativeLock
);
65 // Implements the actual object that is verifying handles for this process.
66 // The active instance is shared across the module boundary but there is no
67 // way to delete this object from the wrong side of it (or any side, actually).
68 class ActiveVerifier
{
70 explicit ActiveVerifier(bool enabled
)
71 : enabled_(enabled
), closing_(false), lock_(g_lock
.Pointer()) {
74 // Retrieves the current verifier.
75 static ActiveVerifier
* Get();
77 // The methods required by HandleTraits. They are virtual because we need to
78 // forward the call execution to another module, instead of letting the
79 // compiler call the version that is linked in the current module.
80 virtual bool CloseHandle(HANDLE handle
);
81 virtual void StartTracking(HANDLE handle
, const void* owner
,
82 const void* pc1
, const void* pc2
);
83 virtual void StopTracking(HANDLE handle
, const void* owner
,
84 const void* pc1
, const void* pc2
);
85 virtual void Disable();
86 virtual void OnHandleBeingClosed(HANDLE handle
);
89 ~ActiveVerifier(); // Not implemented.
91 static void InstallVerifier();
97 DISALLOW_COPY_AND_ASSIGN(ActiveVerifier
);
99 ActiveVerifier
* g_active_verifier
= NULL
;
102 ActiveVerifier
* ActiveVerifier::Get() {
103 if (!g_active_verifier
)
104 ActiveVerifier::InstallVerifier();
106 return g_active_verifier
;
110 void ActiveVerifier::InstallVerifier() {
111 #if defined(COMPONENT_BUILD)
112 AutoNativeLock
lock(g_lock
.Get());
113 g_active_verifier
= new ActiveVerifier(true);
115 // If you are reading this, wondering why your process seems deadlocked, take
116 // a look at your DllMain code and remove things that should not be done
117 // there, like doing whatever gave you that nice windows handle you are trying
118 // to store in a ScopedHandle.
119 HMODULE main_module
= ::GetModuleHandle(NULL
);
120 GetHandleVerifierFn get_handle_verifier
=
121 reinterpret_cast<GetHandleVerifierFn
>(::GetProcAddress(
122 main_module
, "GetHandleVerifier"));
124 if (!get_handle_verifier
) {
125 g_active_verifier
= new ActiveVerifier(false);
129 ActiveVerifier
* verifier
=
130 reinterpret_cast<ActiveVerifier
*>(get_handle_verifier());
132 // This lock only protects against races in this module, which is fine.
133 AutoNativeLock
lock(g_lock
.Get());
134 g_active_verifier
= verifier
? verifier
: new ActiveVerifier(true);
138 bool ActiveVerifier::CloseHandle(HANDLE handle
) {
140 return CloseHandleWrapper(handle
);
142 AutoNativeLock
lock(*lock_
);
144 CloseHandleWrapper(handle
);
150 void ActiveVerifier::StartTracking(HANDLE handle
, const void* owner
,
151 const void* pc1
, const void* pc2
) {
155 // Grab the thread id before the lock.
156 DWORD thread_id
= GetCurrentThreadId();
158 AutoNativeLock
lock(*lock_
);
160 Info handle_info
= { owner
, pc1
, pc2
, thread_id
};
161 std::pair
<HANDLE
, Info
> item(handle
, handle_info
);
162 std::pair
<HandleMap::iterator
, bool> result
= map_
.insert(item
);
163 if (!result
.second
) {
164 Info other
= result
.first
->second
;
165 base::debug::Alias(&other
);
170 void ActiveVerifier::StopTracking(HANDLE handle
, const void* owner
,
171 const void* pc1
, const void* pc2
) {
175 AutoNativeLock
lock(*lock_
);
176 HandleMap::iterator i
= map_
.find(handle
);
180 Info other
= i
->second
;
181 if (other
.owner
!= owner
) {
182 base::debug::Alias(&other
);
189 void ActiveVerifier::Disable() {
193 void ActiveVerifier::OnHandleBeingClosed(HANDLE handle
) {
194 AutoNativeLock
lock(*lock_
);
198 HandleMap::iterator i
= map_
.find(handle
);
202 Info other
= i
->second
;
203 base::debug::Alias(&other
);
209 void* GetHandleVerifier() {
210 return g_active_verifier
;
217 bool HandleTraits::CloseHandle(HANDLE handle
) {
218 return ActiveVerifier::Get()->CloseHandle(handle
);
222 void VerifierTraits::StartTracking(HANDLE handle
, const void* owner
,
223 const void* pc1
, const void* pc2
) {
224 return ActiveVerifier::Get()->StartTracking(handle
, owner
, pc1
, pc2
);
228 void VerifierTraits::StopTracking(HANDLE handle
, const void* owner
,
229 const void* pc1
, const void* pc2
) {
230 return ActiveVerifier::Get()->StopTracking(handle
, owner
, pc1
, pc2
);
233 void DisableHandleVerifier() {
234 return ActiveVerifier::Get()->Disable();
237 void OnHandleBeingClosed(HANDLE handle
) {
238 return ActiveVerifier::Get()->OnHandleBeingClosed(handle
);