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