Index: include/lldb/Host/Socket.h =================================================================== --- include/lldb/Host/Socket.h +++ include/lldb/Host/Socket.h @@ -50,6 +50,9 @@ ~Socket() override; + static llvm::Error Initialize(); + static void Terminate(); + static std::unique_ptr Create(const SocketProtocol protocol, bool child_processes_inherit, Status &error); Index: source/Host/common/Socket.cpp =================================================================== --- source/Host/common/Socket.cpp +++ source/Host/common/Socket.cpp @@ -19,6 +19,8 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Errno.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/WindowsError.h" #ifndef LLDB_DISABLE_POSIX #include "lldb/Host/posix/DomainSocket.h" @@ -78,6 +80,32 @@ Socket::~Socket() { Close(); } +llvm::Error Socket::Initialize() { +#if defined(_WIN32) + auto wVersion = WINSOCK_VERSION; + WSADATA wsaData; + int err = ::WSAStartup(wVersion, &wsaData); + if (err == 0) { + if (wsaData.wVersion < wVersion) { + WSACleanup(); + return llvm::make_error( + "WSASock version is not expected.", llvm::inconvertibleErrorCode()); + } + } else { + return llvm::make_error( + "WSAStartup error.", llvm::mapWindowsError(::WSAGetLastError())); + } +#endif + + return llvm::Error::success(); +} + +void Socket::Terminate(void) { +#if defined(_WIN32) + ::WSACleanup(); +#endif +} + std::unique_ptr Socket::Create(const SocketProtocol protocol, bool child_processes_inherit, Status &error) { Index: source/Initialization/SystemInitializerCommon.cpp =================================================================== --- source/Initialization/SystemInitializerCommon.cpp +++ source/Initialization/SystemInitializerCommon.cpp @@ -17,6 +17,7 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Host/Socket.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Reproducer.h" #include "lldb/Utility/Timer.h" @@ -114,6 +115,10 @@ ProcessWindowsLog::Initialize(); #endif + llvm::Error error = Socket::Initialize(); + if (error) + return error; + return llvm::Error::success(); } @@ -128,6 +133,8 @@ ObjectContainerUniversalMachO::Terminate(); + Socket::Terminate(); + #if defined(_MSC_VER) ProcessWindowsLog::Terminate(); #endif Index: source/Plugins/Platform/Windows/PlatformWindows.cpp =================================================================== --- source/Plugins/Platform/Windows/PlatformWindows.cpp +++ source/Plugins/Platform/Windows/PlatformWindows.cpp @@ -125,8 +125,6 @@ if (g_initialize_count++ == 0) { #if defined(_WIN32) - WSADATA dummy; - WSAStartup(MAKEWORD(2, 2), &dummy); // Force a host flag to true for the default platform object. PlatformSP default_platform_sp(new PlatformWindows(true)); default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); @@ -142,9 +140,6 @@ void PlatformWindows::Terminate(void) { if (g_initialize_count > 0) { if (--g_initialize_count == 0) { -#ifdef _WIN32 - WSACleanup(); -#endif PluginManager::UnregisterPlugin(PlatformWindows::CreateInstance); } } Index: unittests/Host/MainLoopTest.cpp =================================================================== --- unittests/Host/MainLoopTest.cpp +++ unittests/Host/MainLoopTest.cpp @@ -19,16 +19,11 @@ class MainLoopTest : public testing::Test { public: static void SetUpTestCase() { -#ifdef _MSC_VER - WSADATA data; - ASSERT_EQ(0, WSAStartup(MAKEWORD(2, 2), &data)); -#endif + ASSERT_TRUE(!Socket::Initialize().operator bool()); } static void TearDownTestCase() { -#ifdef _MSC_VER - ASSERT_EQ(0, WSACleanup()); -#endif + Socket::Terminate(); } void SetUp() override { Index: unittests/Host/SocketAddressTest.cpp =================================================================== --- unittests/Host/SocketAddressTest.cpp +++ unittests/Host/SocketAddressTest.cpp @@ -8,27 +8,23 @@ #include "gtest/gtest.h" +#include "lldb/Host/Socket.h" #include "lldb/Host/SocketAddress.h" +using namespace lldb_private; + namespace { class SocketAddressTest : public testing::Test { public: static void SetUpTestCase() { -#ifdef _MSC_VER - WSADATA data; - ASSERT_EQ(0, WSAStartup(MAKEWORD(2, 2), &data)); -#endif + ASSERT_TRUE(!Socket::Initialize().operator bool()); } static void TearDownTestCase() { -#ifdef _MSC_VER - ASSERT_EQ(0, WSACleanup()); -#endif + Socket::Terminate(); } }; } // namespace -using namespace lldb_private; - TEST_F(SocketAddressTest, Set) { SocketAddress sa; ASSERT_TRUE(sa.SetToLocalhost(AF_INET, 1138)); Index: unittests/Host/SocketTest.cpp =================================================================== --- unittests/Host/SocketTest.cpp +++ unittests/Host/SocketTest.cpp @@ -28,16 +28,11 @@ class SocketTest : public testing::Test { public: void SetUp() override { -#if defined(_MSC_VER) - WSADATA data; - ::WSAStartup(MAKEWORD(2, 2), &data); -#endif + ASSERT_TRUE(!Socket::Initialize().operator bool()); } void TearDown() override { -#if defined(_MSC_VER) - ::WSACleanup(); -#endif + Socket::Terminate(); } protected: Index: unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp =================================================================== --- unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp +++ unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp @@ -7,26 +7,17 @@ //===----------------------------------------------------------------------===// #include "GDBRemoteTestUtils.h" - -#if defined(_MSC_VER) -#include "lldb/Host/windows/windows.h" -#include -#endif +#include "lldb/Host/Socket.h" namespace lldb_private { namespace process_gdb_remote { void GDBRemoteTest::SetUpTestCase() { -#if defined(_MSC_VER) - WSADATA data; - ::WSAStartup(MAKEWORD(2, 2), &data); -#endif + ASSERT_TRUE(!Socket::Initialize().operator bool()); } void GDBRemoteTest::TearDownTestCase() { -#if defined(_MSC_VER) - ::WSACleanup(); -#endif + Socket::Terminate(); } } // namespace process_gdb_remote