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

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: multiprocess 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
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..a5a8ef89ba0f77bac06bf180acae6043121da3bb
--- /dev/null
+++ b/base/win/scoped_handle_test_dll.cc
@@ -0,0 +1,110 @@
+// 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 {
+
+// 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) {
+ HANDLE handle = ::CreateMutex(nullptr, false, nullptr);
+ HANDLE event = reinterpret_cast<HANDLE>(params);
+ ::WaitForSingleObject(event, INFINITE);
+ ScopedHandle handle_holder(handle);
scottmg 2016/03/11 22:13:09 Does ActiveVerifier CHECK or DCHECK? Do we need to
Will Harris 2016/03/11 22:23:44 it does a CHECK, so it is certainly quite fatal.
scottmg 2016/03/11 22:29:00 OK, I was more worried about this test becoming po
Will Harris 2016/03/11 23:07:47 Acknowledged.
+ 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;
+
+ for (size_t i = 0; i < kNumThreads; i++) {
+ HANDLE thread_handle =
+ ::CreateThread(nullptr, 0, ThreadFunc,
+ reinterpret_cast<void*>(start_event), 0, nullptr);
+ if (!thread_handle)
+ break;
+ threads_.push_back(thread_handle);
+ }
+
+ if (threads_.size() != kNumThreads) {
scottmg 2016/03/11 22:13:09 I wouldn't bother with this, just return false ins
Will Harris 2016/03/11 22:23:44 bah why u not like my cleanup code?
scottmg 2016/03/11 22:29:00 I don't really care either way. You can keep it if
Will Harris 2016/03/11 23:07:47 I left it. I hate leaks.
scottmg 2016/03/11 23:14:19 You wouldn't appreciate the irony of a handle-chec
+ 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

Powered by Google App Engine
This is Rietveld 408576698