[Lldb-commits] [lldb] [lldb-dap] Refactoring lldb-dap port listening mode to allow multiple connections. (PR #116392)
John Harrison via lldb-commits
lldb-commits at lists.llvm.org
Thu Jan 30 10:43:45 PST 2025
================
@@ -5058,72 +5053,148 @@ 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 HandleClient =
+ [=, log = log.get()](std::string name, StreamDescriptor input,
+ StreamDescriptor output, std::FILE *redirectOut,
+ std::FILE *redirectErr) -> bool {
+ DAP dap = DAP(name, program_path.str(), log, default_repl_mode,
+ std::move(input), std::move(output));
- 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 EXIT_FAILURE;
}
- redirectOut = stdout;
- redirectErr = stderr;
+ RegisterRequestCallbacks(dap);
- input = StreamDescriptor::from_file(fileno(stdin), false);
- output = StreamDescriptor::from_file(stdout_fd, false);
- }
+ dap.pre_init_commands = pre_init_commands;
- DAP dap = DAP(program_path.str(), log.get(), default_repl_mode,
- std::move(input), std::move(output));
+ // used only by TestVSCode_redirection_to_console.py
+ if (getenv("LLDB_DAP_TEST_STDOUT_STDERR_REDIRECTION") != nullptr)
+ redirection_test();
- // 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;
- }
+ if (auto Err = dap.Loop()) {
+ if (log)
+ *log << "Transport Error: " << llvm::toString(std::move(Err)) << "\n";
+ return false;
+ }
+ return true;
+ };
- RegisterRequestCallbacks(dap);
+ if (!connection.empty()) {
+ auto maybeProtoclAndName = parseConnection(connection);
+ if (auto Err = maybeProtoclAndName.takeError()) {
+ llvm::errs() << "Invalid connection specification " << Err << "\n";
+ return EXIT_FAILURE;
+ }
- for (const std::string &arg :
- input_args.getAllArgValues(OPT_pre_init_command)) {
- dap.pre_init_commands.push_back(arg);
- }
+ Socket::SocketProtocol protocol;
+ std::string name;
+ std::tie(protocol, name) = *maybeProtoclAndName;
- // used only by TestVSCode_redirection_to_console.py
- if (getenv("LLDB_DAP_TEST_STDOUT_STDERR_REDIRECTION") != nullptr)
- redirection_test();
+ Status error;
+ std::unique_ptr<Socket> listener = Socket::Create(protocol, error);
+ if (error.Fail()) {
+ llvm::errs() << "Failed to create listener for protocol "
+ << Socket::FindSchemeByProtocol(protocol)
+ << ", error: " << error.takeError() << "\n";
+ return EXIT_FAILURE;
+ }
- bool CleanExit = true;
- if (auto Err = dap.Loop()) {
+ error = listener->Listen(name, /* backlog */ 5);
+ if (error.Fail()) {
+ llvm::errs() << "Failed to listen, error: " << error.takeError() << "\n";
+ return EXIT_FAILURE;
+ }
+
+ std::string address =
+ llvm::join(listener->GetListeningConnectionURI(), ", ");
if (log)
- *log << "Transport Error: " << llvm::toString(std::move(Err)) << "\n";
- CleanExit = false;
+ *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();
+
+ MainLoop mainloop;
+ mainloop.RegisterSignal(
+ SIGHUP, [](auto &RL) { RL.RequestTermination(); }, error);
----------------
ashgti wrote:
I ended up removing this at the moment. If the process is signal it will shutdown all debugger sessions. We may want to adjust this in the future but for now this is removed.
https://github.com/llvm/llvm-project/pull/116392
More information about the lldb-commits
mailing list