1 //===-- lldb-platform.cpp ---------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/lldb-python.h" 11 12 // C Includes 13 #include <errno.h> 14 #if defined(__APPLE__) 15 #include <netinet/in.h> 16 #endif 17 #include <signal.h> 18 #include <stdint.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <sys/wait.h> 23 24 // C++ Includes 25 26 // Other libraries and framework includes 27 #include "lldb/Core/Error.h" 28 #include "lldb/Core/ConnectionMachPort.h" 29 #include "lldb/Core/Debugger.h" 30 #include "lldb/Core/StreamFile.h" 31 #include "lldb/Host/ConnectionFileDescriptor.h" 32 #include "lldb/Host/HostGetOpt.h" 33 #include "lldb/Host/OptionParser.h" 34 #include "lldb/Host/Socket.h" 35 #include "lldb/Interpreter/CommandInterpreter.h" 36 #include "lldb/Interpreter/CommandReturnObject.h" 37 #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h" 38 #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h" 39 40 using namespace lldb; 41 using namespace lldb_private; 42 using namespace lldb_private::process_gdb_remote; 43 44 //---------------------------------------------------------------------- 45 // option descriptors for getopt_long_only() 46 //---------------------------------------------------------------------- 47 48 static int g_debug = 0; 49 static int g_verbose = 0; 50 static int g_server = 0; 51 52 static struct option g_long_options[] = 53 { 54 { "debug", no_argument, &g_debug, 1 }, 55 { "verbose", no_argument, &g_verbose, 1 }, 56 { "listen", required_argument, NULL, 'L' }, 57 { "port-offset", required_argument, NULL, 'p' }, 58 { "gdbserver-port", required_argument, NULL, 'P' }, 59 { "min-gdbserver-port", required_argument, NULL, 'm' }, 60 { "max-gdbserver-port", required_argument, NULL, 'M' }, 61 { "lldb-command", required_argument, NULL, 'c' }, 62 { "server", no_argument, &g_server, 1 }, 63 { NULL, 0, NULL, 0 } 64 }; 65 66 #if defined (__APPLE__) 67 #define LOW_PORT (IPPORT_RESERVED) 68 #define HIGH_PORT (IPPORT_HIFIRSTAUTO) 69 #else 70 #define LOW_PORT (1024u) 71 #define HIGH_PORT (49151u) 72 #endif 73 74 75 //---------------------------------------------------------------------- 76 // Watch for signals 77 //---------------------------------------------------------------------- 78 static void 79 signal_handler(int signo) 80 { 81 switch (signo) 82 { 83 case SIGHUP: 84 // Use SIGINT first, if that does not work, use SIGHUP as a last resort. 85 // And we should not call exit() here because it results in the global destructors 86 // to be invoked and wreaking havoc on the threads still running. 87 Host::SystemLog(Host::eSystemLogWarning, "SIGHUP received, exiting lldb-server...\n"); 88 abort(); 89 break; 90 } 91 } 92 93 static void 94 display_usage (const char *progname, const char *subcommand) 95 { 96 fprintf(stderr, "Usage:\n %s %s [--log-file log-file-path] [--log-flags flags] --listen port\n", progname, subcommand); 97 exit(0); 98 } 99 100 //---------------------------------------------------------------------- 101 // main 102 //---------------------------------------------------------------------- 103 int 104 main_platform (int argc, char *argv[]) 105 { 106 const char *progname = argv[0]; 107 const char *subcommand = argv[1]; 108 argc--; 109 argv++; 110 signal (SIGPIPE, SIG_IGN); 111 signal (SIGHUP, signal_handler); 112 int long_option_index = 0; 113 Error error; 114 std::string listen_host_port; 115 int ch; 116 117 lldb::DebuggerSP debugger_sp = Debugger::CreateInstance (); 118 119 debugger_sp->SetInputFileHandle(stdin, false); 120 debugger_sp->SetOutputFileHandle(stdout, false); 121 debugger_sp->SetErrorFileHandle(stderr, false); 122 123 GDBRemoteCommunicationServerPlatform::PortMap gdbserver_portmap; 124 int min_gdbserver_port = 0; 125 int max_gdbserver_port = 0; 126 uint16_t port_offset = 0; 127 128 std::vector<std::string> lldb_commands; 129 bool show_usage = false; 130 int option_error = 0; 131 int socket_error = -1; 132 133 std::string short_options(OptionParser::GetShortOptionString(g_long_options)); 134 135 #if __GLIBC__ 136 optind = 0; 137 #else 138 optreset = 1; 139 optind = 1; 140 #endif 141 142 while ((ch = getopt_long_only(argc, argv, short_options.c_str(), g_long_options, &long_option_index)) != -1) 143 { 144 switch (ch) 145 { 146 case 0: // Any optional that auto set themselves will return 0 147 break; 148 149 case 'L': 150 listen_host_port.append (optarg); 151 break; 152 153 case 'p': 154 { 155 char *end = NULL; 156 long tmp_port_offset = strtoul(optarg, &end, 0); 157 if (end && *end == '\0') 158 { 159 if (LOW_PORT <= tmp_port_offset && tmp_port_offset <= HIGH_PORT) 160 { 161 port_offset = (uint16_t)tmp_port_offset; 162 } 163 else 164 { 165 fprintf (stderr, "error: port offset %li is not in the valid user port range of %u - %u\n", tmp_port_offset, LOW_PORT, HIGH_PORT); 166 option_error = 5; 167 } 168 } 169 else 170 { 171 fprintf (stderr, "error: invalid port offset string %s\n", optarg); 172 option_error = 4; 173 } 174 } 175 break; 176 177 case 'P': 178 case 'm': 179 case 'M': 180 { 181 char *end = NULL; 182 long portnum = strtoul(optarg, &end, 0); 183 if (end && *end == '\0') 184 { 185 if (LOW_PORT <= portnum && portnum <= HIGH_PORT) 186 { 187 if (ch == 'P') 188 gdbserver_portmap[(uint16_t)portnum] = LLDB_INVALID_PROCESS_ID; 189 else if (ch == 'm') 190 min_gdbserver_port = portnum; 191 else 192 max_gdbserver_port = portnum; 193 } 194 else 195 { 196 fprintf (stderr, "error: port number %li is not in the valid user port range of %u - %u\n", portnum, LOW_PORT, HIGH_PORT); 197 option_error = 1; 198 } 199 } 200 else 201 { 202 fprintf (stderr, "error: invalid port number string %s\n", optarg); 203 option_error = 2; 204 } 205 } 206 break; 207 208 case 'c': 209 lldb_commands.push_back(optarg); 210 break; 211 212 case 'h': /* fall-through is intentional */ 213 case '?': 214 show_usage = true; 215 break; 216 } 217 } 218 219 // Make a port map for a port range that was specified. 220 if (min_gdbserver_port < max_gdbserver_port) 221 { 222 for (uint16_t port = min_gdbserver_port; port < max_gdbserver_port; ++port) 223 gdbserver_portmap[port] = LLDB_INVALID_PROCESS_ID; 224 } 225 else if (min_gdbserver_port != max_gdbserver_port) 226 { 227 fprintf (stderr, "error: --min-gdbserver-port (%u) is greater than --max-gdbserver-port (%u)\n", min_gdbserver_port, max_gdbserver_port); 228 option_error = 3; 229 230 } 231 232 // Print usage and exit if no listening port is specified. 233 if (listen_host_port.empty()) 234 show_usage = true; 235 236 if (show_usage || option_error) 237 { 238 display_usage(progname, subcommand); 239 exit(option_error); 240 } 241 242 // Execute any LLDB commands that we were asked to evaluate. 243 for (const auto &lldb_command : lldb_commands) 244 { 245 lldb_private::CommandReturnObject result; 246 printf("(lldb) %s\n", lldb_command.c_str()); 247 debugger_sp->GetCommandInterpreter().HandleCommand(lldb_command.c_str(), eLazyBoolNo, result); 248 const char *output = result.GetOutputData(); 249 if (output && output[0]) 250 puts(output); 251 } 252 253 std::unique_ptr<Socket> listening_socket_up; 254 Socket *socket = nullptr; 255 printf ("Listening for a connection from %s...\n", listen_host_port.c_str()); 256 const bool children_inherit_listen_socket = false; 257 258 // the test suite makes many connections in parallel, let's not miss any. 259 // The highest this should get reasonably is a function of the number 260 // of target CPUs. For now, let's just use 100 261 const int backlog = 100; 262 error = Socket::TcpListen(listen_host_port.c_str(), children_inherit_listen_socket, socket, NULL, backlog); 263 if (error.Fail()) 264 { 265 printf("error: %s\n", error.AsCString()); 266 exit(socket_error); 267 } 268 listening_socket_up.reset(socket); 269 270 do { 271 GDBRemoteCommunicationServerPlatform platform; 272 273 if (port_offset > 0) 274 platform.SetPortOffset(port_offset); 275 276 if (!gdbserver_portmap.empty()) 277 { 278 platform.SetPortMap(std::move(gdbserver_portmap)); 279 } 280 281 const bool children_inherit_accept_socket = true; 282 socket = nullptr; 283 error = listening_socket_up->BlockingAccept(listen_host_port.c_str(), children_inherit_accept_socket, socket); 284 if (error.Fail()) 285 { 286 printf ("error: %s\n", error.AsCString()); 287 exit(socket_error); 288 } 289 printf ("Connection established.\n"); 290 if (g_server) 291 { 292 // Collect child zombie processes. 293 while (waitpid(-1, nullptr, WNOHANG) > 0); 294 if (fork()) 295 { 296 // Parent doesn't need a connection to the lldb client 297 delete socket; 298 socket = nullptr; 299 300 // Parent will continue to listen for new connections. 301 continue; 302 } 303 else 304 { 305 // Child process will handle the connection and exit. 306 g_server = 0; 307 // Listening socket is owned by parent process. 308 listening_socket_up.release(); 309 } 310 } 311 else 312 { 313 // If not running as a server, this process will not accept 314 // connections while a connection is active. 315 listening_socket_up.reset(); 316 } 317 platform.SetConnection (new ConnectionFileDescriptor(socket)); 318 319 if (platform.IsConnected()) 320 { 321 // After we connected, we need to get an initial ack from... 322 if (platform.HandshakeWithClient(&error)) 323 { 324 bool interrupt = false; 325 bool done = false; 326 while (!interrupt && !done) 327 { 328 if (platform.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done) != GDBRemoteCommunication::PacketResult::Success) 329 break; 330 } 331 332 if (error.Fail()) 333 { 334 fprintf(stderr, "error: %s\n", error.AsCString()); 335 } 336 } 337 else 338 { 339 fprintf(stderr, "error: handshake with client failed\n"); 340 } 341 } 342 } while (g_server); 343 344 fprintf(stderr, "lldb-server exiting...\n"); 345 346 return 0; 347 } 348