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