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