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