================ @@ -5058,72 +5053,144 @@ int main(int argc, char *argv[]) { auto terminate_debugger = llvm::make_scope_exit([] { lldb::SBDebugger::Terminate(); }); - StreamDescriptor input; - StreamDescriptor output; - std::FILE *redirectOut = nullptr; - std::FILE *redirectErr = nullptr; - if (portno != -1) { - printf("Listening on port %i...\n", portno); - SOCKET socket_fd = AcceptConnection(log.get(), portno); - if (socket_fd < 0) - return EXIT_FAILURE; + std::vector<std::string> pre_init_commands; + for (const std::string &arg : + input_args.getAllArgValues(OPT_pre_init_command)) { + pre_init_commands.push_back(arg); + } - input = StreamDescriptor::from_socket(socket_fd, true); - output = StreamDescriptor::from_socket(socket_fd, false); - } else { -#if defined(_WIN32) - // Windows opens stdout and stdin in text mode which converts \n to 13,10 - // while the value is just 10 on Darwin/Linux. Setting the file mode to - // binary fixes this. - int result = _setmode(fileno(stdout), _O_BINARY); - assert(result); - result = _setmode(fileno(stdin), _O_BINARY); - UNUSED_IF_ASSERT_DISABLED(result); - assert(result); -#endif + auto RunDAP = [](llvm::StringRef program_path, ReplMode repl_mode, + std::vector<std::string> pre_init_commands, + std::ofstream *log, std::string name, StreamDescriptor input, + StreamDescriptor output, std::FILE *redirectOut = nullptr, + std::FILE *redirectErr = nullptr) -> bool { + DAP dap = DAP(name, program_path, log, std::move(input), std::move(output), + repl_mode, pre_init_commands); - int stdout_fd = DuplicateFileDescriptor(fileno(stdout)); - if (stdout_fd == -1) { + // stdout/stderr redirection to the IDE's console + if (auto Err = dap.ConfigureIO(redirectOut, redirectErr)) { llvm::logAllUnhandledErrors( - llvm::errorCodeToError(llvm::errnoAsErrorCode()), llvm::errs(), - "Failed to configure stdout redirect: "); + std::move(Err), llvm::errs(), + "Failed to configure lldb-dap IO operations: "); + return false; + } + + RegisterRequestCallbacks(dap); + + // used only by TestVSCode_redirection_to_console.py + if (getenv("LLDB_DAP_TEST_STDOUT_STDERR_REDIRECTION") != nullptr) + redirection_test(); + + if (auto Err = dap.Loop()) { + std::string errorMessage = llvm::toString(std::move(Err)); + if (log) + *log << "Transport Error: " << errorMessage << "\n"; + return false; + } + return true; + }; + + if (!connection.empty()) { + auto maybeProtoclAndName = validateConnection(connection); + if (auto Err = maybeProtoclAndName.takeError()) { + llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), + "Invalid connection: "); return EXIT_FAILURE; } - redirectOut = stdout; - redirectErr = stderr; + Socket::SocketProtocol protocol; + std::string name; + std::tie(protocol, name) = *maybeProtoclAndName; - input = StreamDescriptor::from_file(fileno(stdin), false); - output = StreamDescriptor::from_file(stdout_fd, false); - } + Status error; + std::unique_ptr<Socket> listener = Socket::Create(protocol, error); + if (error.Fail()) { + llvm::logAllUnhandledErrors(error.takeError(), llvm::errs(), + "Failed to create socket listener: "); + return EXIT_FAILURE; + } - DAP dap = DAP(program_path.str(), log.get(), default_repl_mode, - std::move(input), std::move(output)); + error = listener->Listen(name, /* backlog */ 5); + if (error.Fail()) { + llvm::logAllUnhandledErrors(error.takeError(), llvm::errs(), + "Failed to listen for connections: "); + return EXIT_FAILURE; + } - // stdout/stderr redirection to the IDE's console - if (auto Err = dap.ConfigureIO(redirectOut, redirectErr)) { - llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), - "Failed to configure lldb-dap IO operations: "); - return EXIT_FAILURE; - } + std::string address = + llvm::join(listener->GetListeningConnectionURI(), ", "); + if (log) + *log << "started with connection listeners " << address << "\n"; + + llvm::outs() << "Listening for: " << address << "\n"; + // Ensure listening address are flushed for calles to retrieve the resolve + // address. + llvm::outs().flush(); + + llvm::DefaultThreadPool pool(llvm::optimal_concurrency()); ---------------- labath wrote:
Isn't this (not picking up new connections if the pool is full) going to be a problem? I mean some sort of rate limiting might be reasonable, but I'm not sure if that was the intention behind this (last thing we were talking about here were detached threads). FWIW, even though you didn't say so explicitly, I get the impression that the only way that lldb-dap running in this mode can exit is for it to be killed. If that's the case (and lldb-dap owners are okay with that), then I think detached threads are sort of acceptable (my main problem with detached threads is that it's very hard to do a clean shutdown, but since you're not shutting down anyway...). If you do that, it'd be nice to leave a comment about it. (i.e. that we're not bothering with joining the threads as there's noone to join them) https://github.com/llvm/llvm-project/pull/116392 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits