[Lldb-commits] [PATCH] D59104: [lldb-vscode] Make server mode work on Windows
This revision was automatically updated to reflect the committed changes. Closed by commit rL355637: [lldb-vscode] Support running in server mode on Windows. (authored by zturner, committed by ). Herald added a project: LLVM. Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D59104?vs=189759&id=189777#toc Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D59104/new/ https://reviews.llvm.org/D59104 Files: lldb/trunk/tools/lldb-vscode/CMakeLists.txt lldb/trunk/tools/lldb-vscode/IOStream.cpp lldb/trunk/tools/lldb-vscode/IOStream.h lldb/trunk/tools/lldb-vscode/VSCode.cpp lldb/trunk/tools/lldb-vscode/VSCode.h lldb/trunk/tools/lldb-vscode/lldb-vscode.cpp lldb/trunk/tools/lldb-vscode/package.json Index: lldb/trunk/tools/lldb-vscode/lldb-vscode.cpp === --- lldb/trunk/tools/lldb-vscode/lldb-vscode.cpp +++ lldb/trunk/tools/lldb-vscode/lldb-vscode.cpp @@ -23,6 +23,7 @@ #define NOMINMAX #include #undef GetObject +#include #else #include #include @@ -53,7 +54,6 @@ constexpr const char *dev_null_path = "nul"; #else -typedef int SOCKET; constexpr const char *dev_null_path = "/dev/null"; #endif @@ -68,9 +68,9 @@ enum VSCodeBroadcasterBits { eBroadcastBitStopEventThread = 1u << 0 }; -int AcceptConnection(int portno) { +SOCKET AcceptConnection(int portno) { // Accept a socket connection from any host on "portno". - int newsockfd = -1; + SOCKET newsockfd = -1; struct sockaddr_in serv_addr, cli_addr; SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { @@ -2635,23 +2635,19 @@ #endif int portno = atoi(arg); printf("Listening on port %i...\n", portno); - int socket_fd = AcceptConnection(portno); + SOCKET socket_fd = AcceptConnection(portno); if (socket_fd >= 0) { -// We must open two FILE objects, one for reading and one for writing -// the FILE objects have a mutex in them that won't allow reading and -// writing to the socket stream. -g_vsc.in = fdopen(socket_fd, "r"); -g_vsc.out = fdopen(socket_fd, "w"); -if (g_vsc.in == nullptr || g_vsc.out == nullptr) { - if (g_vsc.log) -*g_vsc.log << "fdopen failed (" << strerror(errno) << ")" - << std::endl; - exit(1); -} +g_vsc.input.descriptor = StreamDescriptor::from_socket(socket_fd, true); +g_vsc.output.descriptor = +StreamDescriptor::from_socket(socket_fd, false); } else { exit(1); } } + } else { +g_vsc.input.descriptor = StreamDescriptor::from_file(fileno(stdin), false); +g_vsc.output.descriptor = +StreamDescriptor::from_file(fileno(stdout), false); } auto request_handlers = GetRequestHandlers(); uint32_t packet_idx = 0; Index: lldb/trunk/tools/lldb-vscode/CMakeLists.txt === --- lldb/trunk/tools/lldb-vscode/CMakeLists.txt +++ lldb/trunk/tools/lldb-vscode/CMakeLists.txt @@ -15,6 +15,7 @@ BreakpointBase.cpp ExceptionBreakpoint.cpp FunctionBreakpoint.cpp + IOStream.cpp JSONUtils.cpp LLDBUtils.cpp SourceBreakpoint.cpp Index: lldb/trunk/tools/lldb-vscode/IOStream.h === --- lldb/trunk/tools/lldb-vscode/IOStream.h +++ lldb/trunk/tools/lldb-vscode/IOStream.h @@ -0,0 +1,69 @@ +//===-- IOStream.h --*- C++ -*-===// +// +// 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 +// +//===--===// + +#ifndef LLDBVSCODE_IOSTREAM_H_ +#define LLDBVSCODE_IOSTREAM_H_ + +#if defined(_WIN32) +// We need to #define NOMINMAX in order to skip `min()` and `max()` macro +// definitions that conflict with other system headers. +// We also need to #undef GetObject (which is defined to GetObjectW) because +// the JSON code we use also has methods named `GetObject()` and we conflict +// against these. +#define NOMINMAX +#include +#else +typedef int SOCKET; +#endif + +#include "llvm/ADT/StringRef.h" + +#include +#include + +// Windows requires different system calls for dealing with sockets and other +// types of files, so we can't simply have one code path that just uses read +// and write everywhere. So we need an abstraction in order to allow us to +// treat them identically. +namespace lldb_vscode { +struct StreamDescriptor { + StreamDescriptor(); + ~StreamDescriptor(); + StreamDescriptor(StreamDescriptor &&other); + + StreamDescriptor &operator=(StreamDescriptor &&other); + + static StreamDescriptor from_socket(SOCKET s, bool close); + static StreamDescriptor from_file(int fd, bool
[Lldb-commits] [PATCH] D59104: [lldb-vscode] Make server mode work on Windows
zturner created this revision. zturner added a reviewer: clayborg. Herald added a subscriber: mgorny. For historical reasons, Windows unfortunately doesn't support using sockets in standard system calls like read/write, which means that they also can't be buffered with a `FILE*`. This violates some fundamental assumptions of how lldb-vscode was written, so fixing it requires some replumbing of the guts. I introduced an abstraction called `IOStream` which basically knows whether the descriptor is a socket or a non-socket, and then delegates to the appropriate underlying APIs accordingly. This means calling `read/write` on `stdin/stdout` and calling `recv/send` on sockets. Luckily this same strategy will also work on non-Windows platforms, so the abstractions needed aren't too egregious. https://reviews.llvm.org/D59104 Files: lldb/tools/lldb-vscode/CMakeLists.txt lldb/tools/lldb-vscode/IOStream.cpp lldb/tools/lldb-vscode/IOStream.h lldb/tools/lldb-vscode/VSCode.cpp lldb/tools/lldb-vscode/VSCode.h lldb/tools/lldb-vscode/lldb-vscode.cpp lldb/tools/lldb-vscode/package.json Index: lldb/tools/lldb-vscode/package.json === --- lldb/tools/lldb-vscode/package.json +++ lldb/tools/lldb-vscode/package.json @@ -56,6 +56,9 @@ ] }, "program": "./bin/lldb-vscode", +"windows": { + "program": "./bin/lldb-vscode.exe" +}, "configurationAttributes": { "launch": { "required": [ Index: lldb/tools/lldb-vscode/lldb-vscode.cpp === --- lldb/tools/lldb-vscode/lldb-vscode.cpp +++ lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -23,6 +23,7 @@ #define NOMINMAX #include #undef GetObject +#include #else #include #include @@ -68,9 +69,9 @@ enum VSCodeBroadcasterBits { eBroadcastBitStopEventThread = 1u << 0 }; -int AcceptConnection(int portno) { +SOCKET AcceptConnection(int portno) { // Accept a socket connection from any host on "portno". - int newsockfd = -1; + SOCKET newsockfd = -1; struct sockaddr_in serv_addr, cli_addr; SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { @@ -2635,23 +2636,19 @@ #endif int portno = atoi(arg); printf("Listening on port %i...\n", portno); - int socket_fd = AcceptConnection(portno); + SOCKET socket_fd = AcceptConnection(portno); if (socket_fd >= 0) { -// We must open two FILE objects, one for reading and one for writing -// the FILE objects have a mutex in them that won't allow reading and -// writing to the socket stream. -g_vsc.in = fdopen(socket_fd, "r"); -g_vsc.out = fdopen(socket_fd, "w"); -if (g_vsc.in == nullptr || g_vsc.out == nullptr) { - if (g_vsc.log) -*g_vsc.log << "fdopen failed (" << strerror(errno) << ")" - << std::endl; - exit(1); -} +g_vsc.input.descriptor = StreamDescriptor::from_socket(socket_fd, true); +g_vsc.output.descriptor = +StreamDescriptor::from_socket(socket_fd, false); } else { exit(1); } } + } else { +g_vsc.input.descriptor = StreamDescriptor::from_file(fileno(stdin), false); +g_vsc.output.descriptor = +StreamDescriptor::from_file(fileno(stdout), false); } auto request_handlers = GetRequestHandlers(); uint32_t packet_idx = 0; Index: lldb/tools/lldb-vscode/VSCode.h === --- lldb/tools/lldb-vscode/VSCode.h +++ lldb/tools/lldb-vscode/VSCode.h @@ -19,6 +19,7 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" #include "lldb/API/SBAttachInfo.h" #include "lldb/API/SBBreakpoint.h" @@ -43,6 +44,7 @@ #include "ExceptionBreakpoint.h" #include "FunctionBreakpoint.h" +#include "IOStream.h" #include "SourceBreakpoint.h" #include "SourceReference.h" @@ -62,8 +64,8 @@ enum class OutputType { Console, Stdout, Stderr, Telemetry }; struct VSCode { - FILE *in; - FILE *out; + InputStream input; + OutputStream output; lldb::SBDebugger debugger; lldb::SBTarget target; lldb::SBAttachInfo attach_info; @@ -94,8 +96,6 @@ ~VSCode(); VSCode(const VSCode &rhs) = delete; void operator=(const VSCode &rhs) = delete; - void CloseInputStream(); - void CloseOutputStream(); int64_t GetLineForPC(int64_t sourceReference, lldb::addr_t pc) const; ExceptionBreakpoint *GetExceptionBreakpoint(const std::string &filter); ExceptionBreakpoint *GetExceptionBreakpoint(const lldb::break_id_t bp_id); Index: lldb/tools/lldb-vscode/VSCode.cpp === --- lldb/tools/lldb-vscode/VSCode.cpp +++ lldb/tools/lldb-vscode/VSCode.cpp @@ -10,12 +10,15 @@ #include #include -#include "VSCode.h" #include "LLDBUtils.h" +#incl