================
@@ -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:
Are you sure about that? I haven't tried this, but looking at the source code,
it definitely looks like it is [limiting
something](https://github.com/llvm/llvm-project/blob/409fa785d99b3e9f8210b72641d58947e6687fb1/llvm/lib/Support/Threading.cpp#L60).
And although the implementation appears to be stubbed out, it looks like it
has some ambition to mess with [cpu
affinities](https://github.com/llvm/llvm-project/blob/409fa785d99b3e9f8210b72641d58947e6687fb1/llvm/include/llvm/Support/Threading.h#L135)
which, I guess, is fine if you have a a lot of work to do and you want to
avoid cpu migrations, but maybe not so fine when in practice you just have one
task most of the time, and you want to make sure that task gets access to all
cpus.
I have feeling this class just wasn't designed for this use case. We may need
to roll our own solution. The detached thread approach is "almost" right in
that we don't care about a single thread exiting. What we want to wait for is
*all* threads to exit. So maybe have a counter of active threads which is
decreased (and signaled with
[std::notify_all_at_thread_exit](https://en.cppreference.com/w/cpp/thread/notify_all_at_thread_exit)?)
when the thread exits?
https://github.com/llvm/llvm-project/pull/116392
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits