1 //===-- lldb-gdbserver.cpp --------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include <cerrno> 10 #include <cstdint> 11 #include <cstdio> 12 #include <cstdlib> 13 #include <cstring> 14 15 #ifndef _WIN32 16 #include <csignal> 17 #include <unistd.h> 18 #endif 19 20 #include "LLDBServerUtilities.h" 21 #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h" 22 #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h" 23 #include "lldb/Host/Config.h" 24 #include "lldb/Host/ConnectionFileDescriptor.h" 25 #include "lldb/Host/FileSystem.h" 26 #include "lldb/Host/Pipe.h" 27 #include "lldb/Host/Socket.h" 28 #include "lldb/Host/common/NativeProcessProtocol.h" 29 #include "lldb/Target/Process.h" 30 #include "lldb/Utility/LLDBLog.h" 31 #include "lldb/Utility/Status.h" 32 #include "llvm/ADT/StringRef.h" 33 #include "llvm/Option/ArgList.h" 34 #include "llvm/Option/OptTable.h" 35 #include "llvm/Option/Option.h" 36 #include "llvm/Support/Errno.h" 37 #include "llvm/Support/WithColor.h" 38 39 #if defined(__linux__) 40 #include "Plugins/Process/Linux/NativeProcessLinux.h" 41 #elif defined(__FreeBSD__) 42 #include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h" 43 #elif defined(__NetBSD__) 44 #include "Plugins/Process/NetBSD/NativeProcessNetBSD.h" 45 #elif defined(__OpenBSD__) 46 #include "Plugins/Process/OpenBSD/NativeProcessOpenBSD.h" 47 #elif defined(_WIN32) 48 #include "Plugins/Process/Windows/Common/NativeProcessWindows.h" 49 #endif 50 51 #ifndef LLGS_PROGRAM_NAME 52 #define LLGS_PROGRAM_NAME "lldb-server" 53 #endif 54 55 #ifndef LLGS_VERSION_STR 56 #define LLGS_VERSION_STR "local_build" 57 #endif 58 59 using namespace llvm; 60 using namespace lldb; 61 using namespace lldb_private; 62 using namespace lldb_private::lldb_server; 63 using namespace lldb_private::process_gdb_remote; 64 65 namespace { 66 #if defined(__linux__) 67 typedef process_linux::NativeProcessLinux::Factory NativeProcessFactory; 68 #elif defined(__FreeBSD__) 69 typedef process_freebsd::NativeProcessFreeBSD::Factory NativeProcessFactory; 70 #elif defined(__NetBSD__) 71 typedef process_netbsd::NativeProcessNetBSD::Factory NativeProcessFactory; 72 #elif defined(__OpenBSD__) 73 typedef process_openbsd::NativeProcessOpenBSD::Factory NativeProcessFactory; 74 #elif defined(_WIN32) 75 typedef NativeProcessWindows::Factory NativeProcessFactory; 76 #else 77 // Dummy implementation to make sure the code compiles 78 class NativeProcessFactory : public NativeProcessProtocol::Factory { 79 public: 80 llvm::Expected<std::unique_ptr<NativeProcessProtocol>> 81 Launch(ProcessLaunchInfo &launch_info, 82 NativeProcessProtocol::NativeDelegate &delegate, 83 MainLoop &mainloop) const override { 84 llvm_unreachable("Not implemented"); 85 } 86 llvm::Expected<std::unique_ptr<NativeProcessProtocol>> 87 Attach(lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &delegate, 88 MainLoop &mainloop) const override { 89 llvm_unreachable("Not implemented"); 90 } 91 }; 92 #endif 93 } 94 95 #ifndef _WIN32 96 // Watch for signals 97 static int g_sighup_received_count = 0; 98 99 static void sighup_handler(MainLoopBase &mainloop) { 100 ++g_sighup_received_count; 101 102 Log *log = GetLog(LLDBLog::Process); 103 LLDB_LOGF(log, "lldb-server:%s swallowing SIGHUP (receive count=%d)", 104 __FUNCTION__, g_sighup_received_count); 105 106 if (g_sighup_received_count >= 2) 107 mainloop.RequestTermination(); 108 } 109 #endif // #ifndef _WIN32 110 111 void handle_attach_to_pid(GDBRemoteCommunicationServerLLGS &gdb_server, 112 lldb::pid_t pid) { 113 Status error = gdb_server.AttachToProcess(pid); 114 if (error.Fail()) { 115 fprintf(stderr, "error: failed to attach to pid %" PRIu64 ": %s\n", pid, 116 error.AsCString()); 117 exit(1); 118 } 119 } 120 121 void handle_attach_to_process_name(GDBRemoteCommunicationServerLLGS &gdb_server, 122 const std::string &process_name) { 123 // FIXME implement. 124 } 125 126 void handle_attach(GDBRemoteCommunicationServerLLGS &gdb_server, 127 const std::string &attach_target) { 128 assert(!attach_target.empty() && "attach_target cannot be empty"); 129 130 // First check if the attach_target is convertible to a long. If so, we'll use 131 // it as a pid. 132 char *end_p = nullptr; 133 const long int pid = strtol(attach_target.c_str(), &end_p, 10); 134 135 // We'll call it a match if the entire argument is consumed. 136 if (end_p && 137 static_cast<size_t>(end_p - attach_target.c_str()) == 138 attach_target.size()) 139 handle_attach_to_pid(gdb_server, static_cast<lldb::pid_t>(pid)); 140 else 141 handle_attach_to_process_name(gdb_server, attach_target); 142 } 143 144 void handle_launch(GDBRemoteCommunicationServerLLGS &gdb_server, 145 llvm::ArrayRef<llvm::StringRef> Arguments) { 146 ProcessLaunchInfo info; 147 info.GetFlags().Set(eLaunchFlagStopAtEntry | eLaunchFlagDebug | 148 eLaunchFlagDisableASLR); 149 info.SetArguments(Args(Arguments), true); 150 151 llvm::SmallString<64> cwd; 152 if (std::error_code ec = llvm::sys::fs::current_path(cwd)) { 153 llvm::errs() << "Error getting current directory: " << ec.message() << "\n"; 154 exit(1); 155 } 156 FileSpec cwd_spec(cwd); 157 FileSystem::Instance().Resolve(cwd_spec); 158 info.SetWorkingDirectory(cwd_spec); 159 info.GetEnvironment() = Host::GetEnvironment(); 160 161 gdb_server.SetLaunchInfo(info); 162 163 Status error = gdb_server.LaunchProcess(); 164 if (error.Fail()) { 165 llvm::errs() << llvm::formatv("error: failed to launch '{0}': {1}\n", 166 Arguments[0], error); 167 exit(1); 168 } 169 } 170 171 Status writeSocketIdToPipe(Pipe &port_pipe, llvm::StringRef socket_id) { 172 size_t bytes_written = 0; 173 // Write the port number as a C string with the NULL terminator. 174 return port_pipe.Write(socket_id.data(), socket_id.size() + 1, bytes_written); 175 } 176 177 Status writeSocketIdToPipe(const char *const named_pipe_path, 178 llvm::StringRef socket_id) { 179 Pipe port_name_pipe; 180 // Wait for 10 seconds for pipe to be opened. 181 auto error = port_name_pipe.OpenAsWriterWithTimeout(named_pipe_path, false, 182 std::chrono::seconds{10}); 183 if (error.Fail()) 184 return error; 185 return writeSocketIdToPipe(port_name_pipe, socket_id); 186 } 187 188 Status writeSocketIdToPipe(lldb::pipe_t unnamed_pipe, 189 llvm::StringRef socket_id) { 190 Pipe port_pipe{LLDB_INVALID_PIPE, unnamed_pipe}; 191 return writeSocketIdToPipe(port_pipe, socket_id); 192 } 193 194 void ConnectToRemote(MainLoop &mainloop, 195 GDBRemoteCommunicationServerLLGS &gdb_server, 196 bool reverse_connect, llvm::StringRef host_and_port, 197 const char *const progname, const char *const subcommand, 198 const char *const named_pipe_path, pipe_t unnamed_pipe, 199 int connection_fd) { 200 Status error; 201 202 std::unique_ptr<Connection> connection_up; 203 std::string url; 204 205 if (connection_fd != -1) { 206 url = llvm::formatv("fd://{0}", connection_fd).str(); 207 208 // Create the connection. 209 #if LLDB_ENABLE_POSIX && !defined _WIN32 210 ::fcntl(connection_fd, F_SETFD, FD_CLOEXEC); 211 #endif 212 } else if (!host_and_port.empty()) { 213 llvm::Expected<std::string> url_exp = 214 LLGSArgToURL(host_and_port, reverse_connect); 215 if (!url_exp) { 216 llvm::errs() << llvm::formatv("error: invalid host:port or URL '{0}': " 217 "{1}\n", 218 host_and_port, 219 llvm::toString(url_exp.takeError())); 220 exit(-1); 221 } 222 223 url = std::move(url_exp.get()); 224 } 225 226 if (!url.empty()) { 227 // Create the connection or server. 228 std::unique_ptr<ConnectionFileDescriptor> conn_fd_up{ 229 new ConnectionFileDescriptor}; 230 auto connection_result = conn_fd_up->Connect( 231 url, 232 [named_pipe_path, unnamed_pipe](llvm::StringRef socket_id) { 233 // If we have a named pipe to write the socket id back to, do that 234 // now. 235 if (named_pipe_path && named_pipe_path[0]) { 236 Status error = writeSocketIdToPipe(named_pipe_path, socket_id); 237 if (error.Fail()) 238 llvm::errs() << llvm::formatv( 239 "failed to write to the named peipe '{0}': {1}\n", 240 named_pipe_path, error.AsCString()); 241 } 242 // If we have an unnamed pipe to write the socket id back to, do 243 // that now. 244 else if (unnamed_pipe != LLDB_INVALID_PIPE) { 245 Status error = writeSocketIdToPipe(unnamed_pipe, socket_id); 246 if (error.Fail()) 247 llvm::errs() << llvm::formatv( 248 "failed to write to the unnamed pipe: {0}\n", error); 249 } 250 }, 251 &error); 252 253 if (error.Fail()) { 254 llvm::errs() << llvm::formatv( 255 "error: failed to connect to client at '{0}': {1}\n", url, error); 256 exit(-1); 257 } 258 if (connection_result != eConnectionStatusSuccess) { 259 llvm::errs() << llvm::formatv( 260 "error: failed to connect to client at '{0}' " 261 "(connection status: {1})\n", 262 url, static_cast<int>(connection_result)); 263 exit(-1); 264 } 265 connection_up = std::move(conn_fd_up); 266 } 267 error = gdb_server.InitializeConnection(std::move(connection_up)); 268 if (error.Fail()) { 269 llvm::errs() << llvm::formatv("failed to initialize connection\n", error); 270 exit(-1); 271 } 272 llvm::outs() << "Connection established.\n"; 273 } 274 275 namespace { 276 enum ID { 277 OPT_INVALID = 0, // This is not an option ID. 278 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ 279 HELPTEXT, METAVAR, VALUES) \ 280 OPT_##ID, 281 #include "LLGSOptions.inc" 282 #undef OPTION 283 }; 284 285 #define PREFIX(NAME, VALUE) \ 286 constexpr llvm::StringLiteral NAME##_init[] = VALUE; \ 287 constexpr llvm::ArrayRef<llvm::StringLiteral> NAME( \ 288 NAME##_init, std::size(NAME##_init) - 1); 289 #include "LLGSOptions.inc" 290 #undef PREFIX 291 292 static constexpr opt::OptTable::Info InfoTable[] = { 293 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ 294 HELPTEXT, METAVAR, VALUES) \ 295 { \ 296 PREFIX, NAME, HELPTEXT, \ 297 METAVAR, OPT_##ID, opt::Option::KIND##Class, \ 298 PARAM, FLAGS, OPT_##GROUP, \ 299 OPT_##ALIAS, ALIASARGS, VALUES}, 300 #include "LLGSOptions.inc" 301 #undef OPTION 302 }; 303 304 class LLGSOptTable : public opt::GenericOptTable { 305 public: 306 LLGSOptTable() : opt::GenericOptTable(InfoTable) {} 307 308 void PrintHelp(llvm::StringRef Name) { 309 std::string Usage = 310 (Name + " [options] [[host]:port] [[--] program args...]").str(); 311 OptTable::printHelp(llvm::outs(), Usage.c_str(), "lldb-server"); 312 llvm::outs() << R"( 313 DESCRIPTION 314 lldb-server connects to the LLDB client, which drives the debugging session. 315 If no connection options are given, the [host]:port argument must be present 316 and will denote the address that lldb-server will listen on. [host] defaults 317 to "localhost" if empty. Port can be zero, in which case the port number will 318 be chosen dynamically and written to destinations given by --named-pipe and 319 --pipe arguments. 320 321 If no target is selected at startup, lldb-server can be directed by the LLDB 322 client to launch or attach to a process. 323 324 )"; 325 } 326 }; 327 } // namespace 328 329 int main_gdbserver(int argc, char *argv[]) { 330 Status error; 331 MainLoop mainloop; 332 #ifndef _WIN32 333 // Setup signal handlers first thing. 334 signal(SIGPIPE, SIG_IGN); 335 MainLoop::SignalHandleUP sighup_handle = 336 mainloop.RegisterSignal(SIGHUP, sighup_handler, error); 337 #endif 338 339 const char *progname = argv[0]; 340 const char *subcommand = argv[1]; 341 std::string attach_target; 342 std::string named_pipe_path; 343 std::string log_file; 344 StringRef 345 log_channels; // e.g. "lldb process threads:gdb-remote default:linux all" 346 lldb::pipe_t unnamed_pipe = LLDB_INVALID_PIPE; 347 bool reverse_connect = false; 348 int connection_fd = -1; 349 350 // ProcessLaunchInfo launch_info; 351 ProcessAttachInfo attach_info; 352 353 LLGSOptTable Opts; 354 llvm::BumpPtrAllocator Alloc; 355 llvm::StringSaver Saver(Alloc); 356 bool HasError = false; 357 opt::InputArgList Args = Opts.parseArgs(argc - 1, argv + 1, OPT_UNKNOWN, 358 Saver, [&](llvm::StringRef Msg) { 359 WithColor::error() << Msg << "\n"; 360 HasError = true; 361 }); 362 std::string Name = 363 (llvm::sys::path::filename(argv[0]) + " g[dbserver]").str(); 364 std::string HelpText = 365 "Use '" + Name + " --help' for a complete list of options.\n"; 366 if (HasError) { 367 llvm::errs() << HelpText; 368 return 1; 369 } 370 371 if (Args.hasArg(OPT_help)) { 372 Opts.PrintHelp(Name); 373 return 0; 374 } 375 376 #ifndef _WIN32 377 if (Args.hasArg(OPT_setsid)) { 378 // Put llgs into a new session. Terminals group processes 379 // into sessions and when a special terminal key sequences 380 // (like control+c) are typed they can cause signals to go out to 381 // all processes in a session. Using this --setsid (-S) option 382 // will cause debugserver to run in its own sessions and be free 383 // from such issues. 384 // 385 // This is useful when llgs is spawned from a command 386 // line application that uses llgs to do the debugging, 387 // yet that application doesn't want llgs receiving the 388 // signals sent to the session (i.e. dying when anyone hits ^C). 389 { 390 const ::pid_t new_sid = setsid(); 391 if (new_sid == -1) { 392 WithColor::warning() 393 << llvm::formatv("failed to set new session id for {0} ({1})\n", 394 LLGS_PROGRAM_NAME, llvm::sys::StrError()); 395 } 396 } 397 } 398 #endif 399 400 log_file = Args.getLastArgValue(OPT_log_file).str(); 401 log_channels = Args.getLastArgValue(OPT_log_channels); 402 named_pipe_path = Args.getLastArgValue(OPT_named_pipe).str(); 403 reverse_connect = Args.hasArg(OPT_reverse_connect); 404 attach_target = Args.getLastArgValue(OPT_attach).str(); 405 if (Args.hasArg(OPT_pipe)) { 406 uint64_t Arg; 407 if (!llvm::to_integer(Args.getLastArgValue(OPT_pipe), Arg)) { 408 WithColor::error() << "invalid '--pipe' argument\n" << HelpText; 409 return 1; 410 } 411 unnamed_pipe = (pipe_t)Arg; 412 } 413 if (Args.hasArg(OPT_fd)) { 414 if (!llvm::to_integer(Args.getLastArgValue(OPT_fd), connection_fd)) { 415 WithColor::error() << "invalid '--fd' argument\n" << HelpText; 416 return 1; 417 } 418 } 419 420 if (!LLDBServerUtilities::SetupLogging( 421 log_file, log_channels, 422 LLDB_LOG_OPTION_PREPEND_TIMESTAMP | 423 LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION)) 424 return -1; 425 426 std::vector<llvm::StringRef> Inputs; 427 for (opt::Arg *Arg : Args.filtered(OPT_INPUT)) 428 Inputs.push_back(Arg->getValue()); 429 if (opt::Arg *Arg = Args.getLastArg(OPT_REM)) { 430 for (const char *Val : Arg->getValues()) 431 Inputs.push_back(Val); 432 } 433 if (Inputs.empty() && connection_fd == -1) { 434 WithColor::error() << "no connection arguments\n" << HelpText; 435 return 1; 436 } 437 438 NativeProcessFactory factory; 439 GDBRemoteCommunicationServerLLGS gdb_server(mainloop, factory); 440 441 llvm::StringRef host_and_port; 442 if (!Inputs.empty()) { 443 host_and_port = Inputs.front(); 444 Inputs.erase(Inputs.begin()); 445 } 446 447 // Any arguments left over are for the program that we need to launch. If 448 // there 449 // are no arguments, then the GDB server will start up and wait for an 'A' 450 // packet 451 // to launch a program, or a vAttach packet to attach to an existing process, 452 // unless 453 // explicitly asked to attach with the --attach={pid|program_name} form. 454 if (!attach_target.empty()) 455 handle_attach(gdb_server, attach_target); 456 else if (!Inputs.empty()) 457 handle_launch(gdb_server, Inputs); 458 459 // Print version info. 460 printf("%s-%s\n", LLGS_PROGRAM_NAME, LLGS_VERSION_STR); 461 462 ConnectToRemote(mainloop, gdb_server, reverse_connect, host_and_port, 463 progname, subcommand, named_pipe_path.c_str(), 464 unnamed_pipe, connection_fd); 465 466 if (!gdb_server.IsConnected()) { 467 fprintf(stderr, "no connection information provided, unable to run\n"); 468 return 1; 469 } 470 471 Status ret = mainloop.Run(); 472 if (ret.Fail()) { 473 fprintf(stderr, "lldb-server terminating due to error: %s\n", 474 ret.AsCString()); 475 return 1; 476 } 477 fprintf(stderr, "lldb-server exiting...\n"); 478 479 return 0; 480 } 481