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