1b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//===-- lldb-platform.cpp ---------------------------------------*- C++ -*-===// 2b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// 3b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// The LLVM Compiler Infrastructure 4b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// 5b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// This file is distributed under the University of Illinois Open Source 6b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// License. See LICENSE.TXT for details. 7b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// 8b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//===----------------------------------------------------------------------===// 9b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton 10d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea#include "lldb/lldb-python.h" 11d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea 12cb8977d726be451df9978a74088435667fa37da2Greg Clayton// C Includes 13b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton#include <errno.h> 14b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton#include <getopt.h> 15b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton#include <signal.h> 16b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton#include <stdint.h> 17b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton#include <stdio.h> 18b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton#include <stdlib.h> 19b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton#include <string.h> 20b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton 21cb8977d726be451df9978a74088435667fa37da2Greg Clayton// C++ Includes 22cb8977d726be451df9978a74088435667fa37da2Greg Clayton 23cb8977d726be451df9978a74088435667fa37da2Greg Clayton// Other libraries and framework includes 24cb8977d726be451df9978a74088435667fa37da2Greg Clayton#include "lldb/Core/Error.h" 25cb8977d726be451df9978a74088435667fa37da2Greg Clayton#include "lldb/Core/ConnectionFileDescriptor.h" 2606d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton#include "lldb/Core/ConnectionMachPort.h" 2758e26e0935138225477fd61283215ceff2068899Greg Clayton#include "lldb/Core/Debugger.h" 2858e26e0935138225477fd61283215ceff2068899Greg Clayton#include "lldb/Core/StreamFile.h" 2927cf23214479177c83f115b4dbac92b2dba2b3b2Greg Clayton#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h" 3058e26e0935138225477fd61283215ceff2068899Greg Clayton#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h" 31cb8977d726be451df9978a74088435667fa37da2Greg Claytonusing namespace lldb; 32cb8977d726be451df9978a74088435667fa37da2Greg Claytonusing namespace lldb_private; 33cb8977d726be451df9978a74088435667fa37da2Greg Clayton 34b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//---------------------------------------------------------------------- 353f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton// option descriptors for getopt_long_only() 36b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//---------------------------------------------------------------------- 37b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton 38b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonint g_debug = 0; 39b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonint g_verbose = 0; 40b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton 41b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonstatic struct option g_long_options[] = 42b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton{ 43b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton { "debug", no_argument, &g_debug, 1 }, 44b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton { "verbose", no_argument, &g_verbose, 1 }, 45b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton { "log-file", required_argument, NULL, 'l' }, 46b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton { "log-flags", required_argument, NULL, 'f' }, 47cb8977d726be451df9978a74088435667fa37da2Greg Clayton { "listen", required_argument, NULL, 'L' }, 48b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton { NULL, 0, NULL, 0 } 49b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton}; 50b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton 51b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//---------------------------------------------------------------------- 52b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// Watch for signals 53b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//---------------------------------------------------------------------- 54b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonint g_sigpipe_received = 0; 55b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonvoid 56b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonsignal_handler(int signo) 57b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton{ 58b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton switch (signo) 59b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton { 60b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton case SIGPIPE: 61b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton g_sigpipe_received = 1; 62b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton break; 63b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton } 64b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton} 65b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton 66b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//---------------------------------------------------------------------- 67b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// main 68b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton//---------------------------------------------------------------------- 69b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonint 70b622560b2c28c95379edea0bd295555c4d686a13Greg Claytonmain (int argc, char *argv[]) 71b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton{ 72b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton signal (SIGPIPE, signal_handler); 73b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton int long_option_index = 0; 7458e26e0935138225477fd61283215ceff2068899Greg Clayton StreamSP log_stream_sp; 7558e26e0935138225477fd61283215ceff2068899Greg Clayton Args log_args; 7606d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton Error error; 7763afdb07641f04aa7b60d895120b056124d3469bGreg Clayton std::string listen_host_port; 78b51693999473f5dc7cb9681bbbc4a65028eea35bGreg Clayton int ch; 7958e26e0935138225477fd61283215ceff2068899Greg Clayton Debugger::Initialize(); 8058e26e0935138225477fd61283215ceff2068899Greg Clayton 8106d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// ConnectionMachPort a; 8206d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// ConnectionMachPort b; 8306d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// 8406d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// lldb::ConnectionStatus status; 8506d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// const char *bootstrap_service_name = "HelloWorld"; 8606d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// status = a.BootstrapCheckIn(bootstrap_service_name, &error); 8706d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// 8806d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// if (status != eConnectionStatusSuccess) 8906d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// { 9006d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// fprintf(stderr, "%s", error.AsCString()); 9106d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// return 1; 9206d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// } 9306d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// status = b.BootstrapLookup (bootstrap_service_name, &error); 9406d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// if (status != eConnectionStatusSuccess) 9506d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// { 9606d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// fprintf(stderr, "%s", error.AsCString()); 9706d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// return 2; 9806d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// } 9906d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// 10006d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// if (a.Write ("hello", 5, status, &error) == 5) 10106d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// { 10206d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// char buf[32]; 10306d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// memset(buf, 0, sizeof(buf)); 10406d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// if (b.Read (buf, 5, status, &error)) 10506d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// { 10606d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// printf("read returned bytes: %s", buf); 10706d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// } 10806d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// else 10906d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// { 11006d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// fprintf(stderr, "%s", error.AsCString()); 11106d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// return 4; 11206d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// } 11306d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// } 11406d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// else 11506d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// { 11606d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// fprintf(stderr, "%s", error.AsCString()); 11706d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// return 3; 11806d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton// } 11906d7cc86937caca0acf2b990a02a641dc9c7579aGreg Clayton 1203f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton while ((ch = getopt_long_only(argc, argv, "l:f:L:", g_long_options, &long_option_index)) != -1) 121b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton { 122b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n", 123b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// ch, (uint8_t)ch, 124b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// g_long_options[long_option_index].name, 125b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// g_long_options[long_option_index].has_arg ? '=' : ' ', 126b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton// optarg ? optarg : ""); 127b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton switch (ch) 128b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton { 129b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton case 0: // Any optional that auto set themselves will return 0 130b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton break; 131b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton 132b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton case 'l': // Set Log File 133b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton if (optarg && optarg[0]) 134b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton { 13558e26e0935138225477fd61283215ceff2068899Greg Clayton if ((strcasecmp(optarg, "stdout") == 0) || (strcmp(optarg, "/dev/stdout") == 0)) 13658e26e0935138225477fd61283215ceff2068899Greg Clayton { 13758e26e0935138225477fd61283215ceff2068899Greg Clayton log_stream_sp.reset (new StreamFile (stdout, false)); 13858e26e0935138225477fd61283215ceff2068899Greg Clayton } 13958e26e0935138225477fd61283215ceff2068899Greg Clayton else if ((strcasecmp(optarg, "stderr") == 0) || (strcmp(optarg, "/dev/stderr") == 0)) 14058e26e0935138225477fd61283215ceff2068899Greg Clayton { 14158e26e0935138225477fd61283215ceff2068899Greg Clayton log_stream_sp.reset (new StreamFile (stderr, false)); 14258e26e0935138225477fd61283215ceff2068899Greg Clayton } 143b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton else 144b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton { 14558e26e0935138225477fd61283215ceff2068899Greg Clayton FILE *log_file = fopen(optarg, "w"); 14658e26e0935138225477fd61283215ceff2068899Greg Clayton if (log_file) 14758e26e0935138225477fd61283215ceff2068899Greg Clayton { 148b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton setlinebuf(log_file); 14958e26e0935138225477fd61283215ceff2068899Greg Clayton log_stream_sp.reset (new StreamFile (log_file, true)); 15058e26e0935138225477fd61283215ceff2068899Greg Clayton } 15158e26e0935138225477fd61283215ceff2068899Greg Clayton else 15258e26e0935138225477fd61283215ceff2068899Greg Clayton { 15358e26e0935138225477fd61283215ceff2068899Greg Clayton const char *errno_str = strerror(errno); 15458e26e0935138225477fd61283215ceff2068899Greg Clayton fprintf (stderr, "Failed to open log file '%s' for writing: errno = %i (%s)", optarg, errno, errno_str ? errno_str : "unknown error"); 15558e26e0935138225477fd61283215ceff2068899Greg Clayton } 15658e26e0935138225477fd61283215ceff2068899Greg Clayton 157b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton } 158b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton 159b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton } 160b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton break; 161b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton 162b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton case 'f': // Log Flags 163b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton if (optarg && optarg[0]) 16458e26e0935138225477fd61283215ceff2068899Greg Clayton log_args.AppendArgument(optarg); 165b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton break; 166cb8977d726be451df9978a74088435667fa37da2Greg Clayton 167cb8977d726be451df9978a74088435667fa37da2Greg Clayton case 'L': 16863afdb07641f04aa7b60d895120b056124d3469bGreg Clayton listen_host_port.append (optarg); 169cb8977d726be451df9978a74088435667fa37da2Greg Clayton break; 170b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton } 171b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton } 172b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton 17358e26e0935138225477fd61283215ceff2068899Greg Clayton if (log_stream_sp) 17458e26e0935138225477fd61283215ceff2068899Greg Clayton { 17558e26e0935138225477fd61283215ceff2068899Greg Clayton if (log_args.GetArgumentCount() == 0) 17658e26e0935138225477fd61283215ceff2068899Greg Clayton log_args.AppendArgument("default"); 1776c530f2201be4788dedf3d5970399220fbd50b11Jim Ingham ProcessGDBRemoteLog::EnableLog (log_stream_sp, 0,log_args.GetConstArgumentVector(), log_stream_sp.get()); 17858e26e0935138225477fd61283215ceff2068899Greg Clayton } 17958e26e0935138225477fd61283215ceff2068899Greg Clayton 1803f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton // Skip any options we consumed with getopt_long_only 181b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton argc -= optind; 182b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton argv += optind; 183b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton 184b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton 185b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton GDBRemoteCommunicationServer gdb_server (true); 18663afdb07641f04aa7b60d895120b056124d3469bGreg Clayton if (!listen_host_port.empty()) 187cb8977d726be451df9978a74088435667fa37da2Greg Clayton { 188102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor()); 189cb8977d726be451df9978a74088435667fa37da2Greg Clayton if (conn_ap.get()) 190cb8977d726be451df9978a74088435667fa37da2Greg Clayton { 19158e26e0935138225477fd61283215ceff2068899Greg Clayton std::string connect_url ("listen://"); 19263afdb07641f04aa7b60d895120b056124d3469bGreg Clayton connect_url.append(listen_host_port.c_str()); 193cb8977d726be451df9978a74088435667fa37da2Greg Clayton 19463afdb07641f04aa7b60d895120b056124d3469bGreg Clayton printf ("Listening for a connection on %s...\n", listen_host_port.c_str()); 19558e26e0935138225477fd61283215ceff2068899Greg Clayton if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess) 19658e26e0935138225477fd61283215ceff2068899Greg Clayton { 19758e26e0935138225477fd61283215ceff2068899Greg Clayton printf ("Connection established.\n"); 19858e26e0935138225477fd61283215ceff2068899Greg Clayton gdb_server.SetConnection (conn_ap.release()); 199cb8977d726be451df9978a74088435667fa37da2Greg Clayton } 200cb8977d726be451df9978a74088435667fa37da2Greg Clayton } 201cb8977d726be451df9978a74088435667fa37da2Greg Clayton } 202cb8977d726be451df9978a74088435667fa37da2Greg Clayton 203cb8977d726be451df9978a74088435667fa37da2Greg Clayton 204cb8977d726be451df9978a74088435667fa37da2Greg Clayton if (gdb_server.IsConnected()) 205cb8977d726be451df9978a74088435667fa37da2Greg Clayton { 20658e26e0935138225477fd61283215ceff2068899Greg Clayton // After we connected, we need to get an initial ack from... 20758e26e0935138225477fd61283215ceff2068899Greg Clayton if (gdb_server.HandshakeWithClient(&error)) 208cb8977d726be451df9978a74088435667fa37da2Greg Clayton { 209cb8977d726be451df9978a74088435667fa37da2Greg Clayton bool interrupt = false; 210cb8977d726be451df9978a74088435667fa37da2Greg Clayton bool done = false; 211cb8977d726be451df9978a74088435667fa37da2Greg Clayton while (!interrupt && !done) 212cb8977d726be451df9978a74088435667fa37da2Greg Clayton { 21363afdb07641f04aa7b60d895120b056124d3469bGreg Clayton if (!gdb_server.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done)) 21458e26e0935138225477fd61283215ceff2068899Greg Clayton break; 215cb8977d726be451df9978a74088435667fa37da2Greg Clayton } 216801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton 217801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton if (error.Fail()) 218801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton { 219801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton fprintf(stderr, "error: %s\n", error.AsCString()); 220801417e453f8531ac176cd952200587bf15d9ccfGreg Clayton } 221cb8977d726be451df9978a74088435667fa37da2Greg Clayton } 222cb8977d726be451df9978a74088435667fa37da2Greg Clayton else 223cb8977d726be451df9978a74088435667fa37da2Greg Clayton { 22458e26e0935138225477fd61283215ceff2068899Greg Clayton fprintf(stderr, "error: handshake with client failed\n"); 225cb8977d726be451df9978a74088435667fa37da2Greg Clayton } 226cb8977d726be451df9978a74088435667fa37da2Greg Clayton } 227b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton 22858e26e0935138225477fd61283215ceff2068899Greg Clayton Debugger::Terminate(); 22958e26e0935138225477fd61283215ceff2068899Greg Clayton 230b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton return 0; 231b622560b2c28c95379edea0bd295555c4d686a13Greg Clayton} 232