Revert "Port __sanitizer::StopTheWorld to Windows"

This reverts commit 3f5f687e2e.

That commit broke building for mingw, where the sanitizers are
built with -nostdinc++, while the added source file includes
the C++ standard library's <algorithm>.

Additionally, the new code fails to build for i386, as it
unconditionally uses the CONTEXT member Rsp.
This commit is contained in:
Martin Storsjö 2021-12-17 20:37:25 +02:00
parent 9369aa1444
commit cc324af0d6
3 changed files with 2 additions and 176 deletions

View File

@ -34,7 +34,6 @@ set(SANITIZER_SOURCES_NOTERMINATION
sanitizer_solaris.cpp
sanitizer_stoptheworld_fuchsia.cpp
sanitizer_stoptheworld_mac.cpp
sanitizer_stoptheworld_win.cpp
sanitizer_suppressions.cpp
sanitizer_tls_get_addr.cpp
sanitizer_thread_registry.cpp

View File

@ -1,167 +0,0 @@
//===-- sanitizer_stoptheworld_win.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// See sanitizer_stoptheworld.h for details.
//
//===----------------------------------------------------------------------===//
#include "sanitizer_platform.h"
#if SANITIZER_WINDOWS
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
// windows.h needs to be included before tlhelp32.h
# include <tlhelp32.h>
# include <algorithm>
# include "sanitizer_stoptheworld.h"
namespace __sanitizer {
namespace {
struct SuspendedThreadsListWindows final : public SuspendedThreadsList {
InternalMmapVector<HANDLE> threadHandles;
InternalMmapVector<DWORD> threadIds;
SuspendedThreadsListWindows() {
threadIds.reserve(1024);
threadHandles.reserve(1024);
}
PtraceRegistersStatus GetRegistersAndSP(uptr index,
InternalMmapVector<uptr> *buffer,
uptr *sp) const override;
tid_t GetThreadID(uptr index) const override;
uptr ThreadCount() const override;
};
PtraceRegistersStatus SuspendedThreadsListWindows::GetRegistersAndSP(
uptr index, InternalMmapVector<uptr> *buffer, uptr *sp) const {
CHECK_LT(index, threadHandles.size());
CONTEXT thread_context;
thread_context.ContextFlags = CONTEXT_ALL;
CHECK(GetThreadContext(threadHandles[index], &thread_context));
buffer->resize(RoundUpTo(sizeof(thread_context), sizeof(uptr)) /
sizeof(uptr));
internal_memcpy(buffer->data(), &thread_context, sizeof(thread_context));
*sp = thread_context.Rsp;
return REGISTERS_AVAILABLE;
}
tid_t SuspendedThreadsListWindows::GetThreadID(uptr index) const {
CHECK_LT(index, threadIds.size());
return threadIds[index];
}
uptr SuspendedThreadsListWindows::ThreadCount() const {
return threadIds.size();
}
struct RunThreadArgs {
StopTheWorldCallback callback;
void *argument;
};
DWORD WINAPI RunThread(void *argument) {
RunThreadArgs *run_args = (RunThreadArgs *)argument;
const DWORD this_thread = GetCurrentThreadId();
const DWORD this_process = GetCurrentProcessId();
SuspendedThreadsListWindows suspended_threads_list;
bool new_thread_found;
do {
// Take a snapshot of all Threads
const HANDLE threads = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
CHECK(threads != INVALID_HANDLE_VALUE);
THREADENTRY32 thread_entry;
thread_entry.dwSize = sizeof(thread_entry);
new_thread_found = false;
if (!Thread32First(threads, &thread_entry))
break;
do {
if (thread_entry.th32ThreadID == this_thread ||
thread_entry.th32OwnerProcessID != this_process)
continue;
const bool thread_already_suspended =
std::find(suspended_threads_list.threadIds.begin(),
suspended_threads_list.threadIds.end(),
thread_entry.th32ThreadID) !=
suspended_threads_list.threadIds.end();
if (thread_already_suspended)
continue;
const HANDLE thread =
OpenThread(THREAD_ALL_ACCESS, FALSE, thread_entry.th32ThreadID);
CHECK(thread);
if (SuspendThread(thread) == -1) {
DWORD last_error = GetLastError();
VPrintf(1, "Could not suspend thread %lu (error %lu)",
thread_entry.th32ThreadID, last_error);
continue;
}
suspended_threads_list.threadIds.push_back(thread_entry.th32ThreadID);
suspended_threads_list.threadHandles.push_back(thread);
new_thread_found = true;
} while (Thread32Next(threads, &thread_entry));
CloseHandle(threads);
// Between the call to `CreateToolhelp32Snapshot` and suspending the
// relevant Threads, new Threads could have potentially been created. So
// continue to find and suspend new Threads until we don't find any.
} while (new_thread_found);
// Now all Threads of this Process except of this Thread should be suspended.
// Execute the callback function.
run_args->callback(suspended_threads_list, run_args->argument);
// Resume all Threads
for (const auto suspended_thread_handle :
suspended_threads_list.threadHandles) {
CHECK_NE(ResumeThread(suspended_thread_handle), -1);
CloseHandle(suspended_thread_handle);
}
return 0;
}
} // namespace
void StopTheWorld(StopTheWorldCallback callback, void *argument) {
struct RunThreadArgs arg = {callback, argument};
DWORD trace_thread_id;
auto trace_thread =
CreateThread(nullptr, 0, RunThread, &arg, 0, &trace_thread_id);
CHECK(trace_thread);
WaitForSingleObject(trace_thread, INFINITE);
CloseHandle(trace_thread);
}
} // namespace __sanitizer
#endif // SANITIZER_WINDOWS

View File

@ -13,7 +13,7 @@
#include "sanitizer_common/sanitizer_stoptheworld.h"
#include "sanitizer_common/sanitizer_platform.h"
#if (SANITIZER_LINUX || SANITIZER_WINDOWS) && defined(__x86_64__)
#if SANITIZER_LINUX && defined(__x86_64__)
# include <atomic>
# include <mutex>
@ -155,13 +155,7 @@ static void SegvCallback(const SuspendedThreadsList &suspended_threads_list,
*(volatile int *)0x1234 = 0;
}
# if SANITIZER_WINDOWS
# define MAYBE_SegvInCallback DISABLED_SegvInCallback
# else
# define MAYBE_SegvInCallback SegvInCallback
# endif
TEST(StopTheWorld, MAYBE_SegvInCallback) {
TEST(StopTheWorld, SegvInCallback) {
// Test that tracer thread catches SIGSEGV.
StopTheWorld(&SegvCallback, NULL);
}