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