OLD | NEW |
---|---|
(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 <windows.h> | |
6 | |
7 #include <vector> | |
8 | |
9 #include "base/win/scoped_handle.h" | |
10 | |
11 // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx | |
12 extern "C" IMAGE_DOS_HEADER __ImageBase; | |
13 | |
14 namespace base { | |
15 namespace win { | |
16 namespace testing { | |
17 | |
18 extern "C" bool __declspec(dllexport) RunTest(); | |
19 | |
20 namespace { | |
21 | |
22 struct ThreadParams { | |
23 HANDLE ready_event; | |
24 HANDLE start_event; | |
25 }; | |
26 | |
27 // Note, this must use all native functions to avoid instantiating the | |
28 // ActiveVerifier. e.g. can't use base::Thread or even base::PlatformThread. | |
29 DWORD __stdcall ThreadFunc(void* params) { | |
30 ThreadParams* thread_params = reinterpret_cast<ThreadParams*>(params); | |
31 HANDLE handle = ::CreateMutex(nullptr, false, nullptr); | |
32 | |
33 ::SetEvent(thread_params->ready_event); | |
34 ::WaitForSingleObject(thread_params->start_event, INFINITE); | |
35 ScopedHandle handle_holder(handle); | |
Nico
2016/03/11 23:26:58
this is just a CloseHandle call, right?
Nico
2016/03/11 23:34:21
wfh patiently explained to me that the point of th
Will Harris
2016/03/12 00:00:01
Acknowledged.
| |
36 return 0; | |
37 } | |
38 | |
39 bool InternalRunThreadTest() { | |
40 std::vector<HANDLE> threads_; | |
41 // From manual testing, the bug fixed by crrev.com/678736a starts reliably | |
42 // causing handle verifier asserts to trigger at around 100 threads, so make | |
43 // it 200 to be sure to detect any future regressions. | |
44 const size_t kNumThreads = 200; | |
45 | |
46 // bManualReset is set to true to allow signalling multiple threads. | |
47 HANDLE start_event = ::CreateEvent(nullptr, true, false, nullptr); | |
48 if (!start_event) | |
49 return false; | |
50 | |
51 HANDLE ready_event = CreateEvent(nullptr, false, false, nullptr); | |
52 if (!ready_event) | |
53 return false; | |
54 | |
55 ThreadParams thread_params = { ready_event, start_event }; | |
56 | |
57 for (size_t i = 0; i < kNumThreads; i++) { | |
58 HANDLE thread_handle = | |
59 ::CreateThread(nullptr, 0, ThreadFunc, | |
60 reinterpret_cast<void*>(&thread_params), 0, nullptr); | |
61 if (!thread_handle) | |
62 break; | |
63 ::WaitForSingleObject(ready_event, INFINITE); | |
64 threads_.push_back(thread_handle); | |
65 } | |
66 | |
67 ::CloseHandle(ready_event); | |
68 | |
69 if (threads_.size() != kNumThreads) { | |
70 for (const auto& thread : threads_) | |
71 ::CloseHandle(thread); | |
72 ::CloseHandle(start_event); | |
73 return false; | |
74 } | |
75 | |
76 ::SetEvent(start_event); | |
77 ::CloseHandle(start_event); | |
78 for (const auto& thread : threads_) { | |
79 ::WaitForSingleObject(thread, INFINITE); | |
80 ::CloseHandle(thread); | |
81 } | |
82 | |
83 return true; | |
84 } | |
85 | |
86 bool InternalRunLocationTest() { | |
87 // Create a new handle and then set LastError again. | |
88 HANDLE handle = ::CreateMutex(nullptr, false, nullptr); | |
89 if (!handle) | |
90 return false; | |
91 ScopedHandle handle_holder(handle); | |
Nico
2016/03/11 23:26:58
linking this against base just for one scoped hand
| |
92 | |
93 HMODULE verifier_module = GetHandleVerifierModuleForTesting(); | |
94 if (!verifier_module) | |
95 return false; | |
96 | |
97 // Get my module | |
98 HMODULE my_module = reinterpret_cast<HMODULE>(&__ImageBase); | |
99 if (!my_module) | |
100 return false; | |
101 | |
102 HMODULE main_module = ::GetModuleHandle(NULL); | |
103 | |
104 #if defined(COMPONENT_BUILD) | |
105 // In a component build ActiveVerifier will always be created inside base.dll | |
106 // as the code always lives there. | |
107 if (verifier_module == my_module || verifier_module == main_module) | |
108 return false; | |
109 #else | |
110 // In a non-component build, ActiveVerifier should always be created in the | |
111 // version of base linked with the main executable. | |
112 if (verifier_module == my_module || verifier_module != main_module) | |
113 return false; | |
114 #endif | |
115 return true; | |
116 } | |
117 | |
118 } // namespace | |
119 | |
120 bool RunTest() { | |
121 return InternalRunThreadTest() && InternalRunLocationTest(); | |
122 } | |
123 | |
124 } // testing | |
125 } // win | |
126 } // base | |
OLD | NEW |