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

Unified Diff: base/win/scoped_handle_test_dll.cc

Issue 1779333003: Add test for multithreaded ActiveVerifier behavior. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@handlecreate
Patch Set: change to loadable_module Created 4 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/win/scoped_handle.cc ('k') | base/win/scoped_handle_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/win/scoped_handle_test_dll.cc
diff --git a/base/win/scoped_handle_test_dll.cc b/base/win/scoped_handle_test_dll.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e6e1215d5990aab5c8b1988699f78c69300b1f19
--- /dev/null
+++ b/base/win/scoped_handle_test_dll.cc
@@ -0,0 +1,126 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <windows.h>
+
+#include <vector>
+
+#include "base/win/scoped_handle.h"
+
+// http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
+extern "C" IMAGE_DOS_HEADER __ImageBase;
+
+namespace base {
+namespace win {
+namespace testing {
+
+extern "C" bool __declspec(dllexport) RunTest();
+
+namespace {
+
+struct ThreadParams {
+ HANDLE ready_event;
+ HANDLE start_event;
+};
+
+// Note, this must use all native functions to avoid instantiating the
+// ActiveVerifier. e.g. can't use base::Thread or even base::PlatformThread.
+DWORD __stdcall ThreadFunc(void* params) {
+ ThreadParams* thread_params = reinterpret_cast<ThreadParams*>(params);
+ HANDLE handle = ::CreateMutex(nullptr, false, nullptr);
+
+ ::SetEvent(thread_params->ready_event);
+ ::WaitForSingleObject(thread_params->start_event, INFINITE);
+ ScopedHandle handle_holder(handle);
+ return 0;
+}
+
+bool InternalRunThreadTest() {
+ std::vector<HANDLE> threads_;
+ // From manual testing, the bug fixed by crrev.com/678736a starts reliably
+ // causing handle verifier asserts to trigger at around 100 threads, so make
+ // it 200 to be sure to detect any future regressions.
+ const size_t kNumThreads = 200;
+
+ // bManualReset is set to true to allow signalling multiple threads.
+ HANDLE start_event = ::CreateEvent(nullptr, true, false, nullptr);
+ if (!start_event)
+ return false;
+
+ HANDLE ready_event = CreateEvent(nullptr, false, false, nullptr);
+ if (!ready_event)
+ return false;
+
+ ThreadParams thread_params = { ready_event, start_event };
+
+ for (size_t i = 0; i < kNumThreads; i++) {
+ HANDLE thread_handle =
+ ::CreateThread(nullptr, 0, ThreadFunc,
+ reinterpret_cast<void*>(&thread_params), 0, nullptr);
+ if (!thread_handle)
+ break;
+ ::WaitForSingleObject(ready_event, INFINITE);
+ threads_.push_back(thread_handle);
+ }
+
+ ::CloseHandle(ready_event);
+
+ if (threads_.size() != kNumThreads) {
+ for (const auto& thread : threads_)
+ ::CloseHandle(thread);
+ ::CloseHandle(start_event);
+ return false;
+ }
+
+ ::SetEvent(start_event);
+ ::CloseHandle(start_event);
+ for (const auto& thread : threads_) {
+ ::WaitForSingleObject(thread, INFINITE);
+ ::CloseHandle(thread);
+ }
+
+ return true;
+}
+
+bool InternalRunLocationTest() {
+ // Create a new handle and then set LastError again.
+ HANDLE handle = ::CreateMutex(nullptr, false, nullptr);
+ if (!handle)
+ return false;
+ ScopedHandle handle_holder(handle);
+
+ HMODULE verifier_module = GetHandleVerifierModuleForTesting();
+ if (!verifier_module)
+ return false;
+
+ // Get my module
+ HMODULE my_module = reinterpret_cast<HMODULE>(&__ImageBase);
+ if (!my_module)
+ return false;
+
+ HMODULE main_module = ::GetModuleHandle(NULL);
+
+#if defined(COMPONENT_BUILD)
+ // In a component build ActiveVerifier will always be created inside base.dll
+ // as the code always lives there.
+ if (verifier_module == my_module || verifier_module == main_module)
+ return false;
+#else
+ // In a non-component build, ActiveVerifier should always be created in the
+ // version of base linked with the main executable.
+ if (verifier_module == my_module || verifier_module != main_module)
+ return false;
+#endif
+ return true;
+}
+
+} // namespace
+
+bool RunTest() {
+ return InternalRunThreadTest() && InternalRunLocationTest();
+}
+
+} // testing
+} // win
+} // base
« no previous file with comments | « base/win/scoped_handle.cc ('k') | base/win/scoped_handle_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698