blob: 112dc9ed04c8c103c61ea466a6f95120f16b0202 [file] [log] [blame]
Greg Claytonb43767a2011-03-22 01:34:44 +00001//===-- 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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Greg Claytond314e812011-03-23 00:09:55 +000012// C Includes
Greg Claytonb43767a2011-03-22 01:34:44 +000013#include <errno.h>
14#include <getopt.h>
15#include <signal.h>
16#include <stdint.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20
Greg Claytond314e812011-03-23 00:09:55 +000021// C++ Includes
22
23// Other libraries and framework includes
24#include "lldb/Core/Error.h"
25#include "lldb/Core/ConnectionFileDescriptor.h"
Greg Clayton9b1e1cd2011-04-04 18:18:57 +000026#include "lldb/Core/ConnectionMachPort.h"
Greg Clayton1cb64962011-03-24 04:28:38 +000027#include "lldb/Core/Debugger.h"
28#include "lldb/Core/StreamFile.h"
Greg Clayton59b4fa12012-03-29 17:46:11 +000029#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h"
Greg Clayton1cb64962011-03-24 04:28:38 +000030#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
Greg Claytond314e812011-03-23 00:09:55 +000031using namespace lldb;
32using namespace lldb_private;
33
Greg Claytonb43767a2011-03-22 01:34:44 +000034//----------------------------------------------------------------------
Greg Claytonb7ad58a2013-04-04 20:35:24 +000035// option descriptors for getopt_long_only()
Greg Claytonb43767a2011-03-22 01:34:44 +000036//----------------------------------------------------------------------
37
38int g_debug = 0;
39int g_verbose = 0;
40
41static struct option g_long_options[] =
42{
43 { "debug", no_argument, &g_debug, 1 },
44 { "verbose", no_argument, &g_verbose, 1 },
45 { "log-file", required_argument, NULL, 'l' },
46 { "log-flags", required_argument, NULL, 'f' },
Greg Claytond314e812011-03-23 00:09:55 +000047 { "listen", required_argument, NULL, 'L' },
Greg Claytonb43767a2011-03-22 01:34:44 +000048 { NULL, 0, NULL, 0 }
49};
50
51//----------------------------------------------------------------------
52// Watch for signals
53//----------------------------------------------------------------------
54int g_sigpipe_received = 0;
55void
56signal_handler(int signo)
57{
58 switch (signo)
59 {
60 case SIGPIPE:
61 g_sigpipe_received = 1;
62 break;
63 }
64}
65
66//----------------------------------------------------------------------
67// main
68//----------------------------------------------------------------------
69int
70main (int argc, char *argv[])
71{
72 signal (SIGPIPE, signal_handler);
73 int long_option_index = 0;
Greg Clayton1cb64962011-03-24 04:28:38 +000074 StreamSP log_stream_sp;
75 Args log_args;
Greg Clayton9b1e1cd2011-04-04 18:18:57 +000076 Error error;
Greg Clayton73bf5db2011-06-17 01:22:15 +000077 std::string listen_host_port;
Greg Clayton9d3d6882011-10-31 23:51:19 +000078 int ch;
Greg Clayton1cb64962011-03-24 04:28:38 +000079 Debugger::Initialize();
80
Greg Clayton9b1e1cd2011-04-04 18:18:57 +000081// ConnectionMachPort a;
82// ConnectionMachPort b;
83//
84// lldb::ConnectionStatus status;
85// const char *bootstrap_service_name = "HelloWorld";
86// status = a.BootstrapCheckIn(bootstrap_service_name, &error);
87//
88// if (status != eConnectionStatusSuccess)
89// {
90// fprintf(stderr, "%s", error.AsCString());
91// return 1;
92// }
93// status = b.BootstrapLookup (bootstrap_service_name, &error);
94// if (status != eConnectionStatusSuccess)
95// {
96// fprintf(stderr, "%s", error.AsCString());
97// return 2;
98// }
99//
100// if (a.Write ("hello", 5, status, &error) == 5)
101// {
102// char buf[32];
103// memset(buf, 0, sizeof(buf));
104// if (b.Read (buf, 5, status, &error))
105// {
106// printf("read returned bytes: %s", buf);
107// }
108// else
109// {
110// fprintf(stderr, "%s", error.AsCString());
111// return 4;
112// }
113// }
114// else
115// {
116// fprintf(stderr, "%s", error.AsCString());
117// return 3;
118// }
119
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000120 while ((ch = getopt_long_only(argc, argv, "l:f:L:", g_long_options, &long_option_index)) != -1)
Greg Claytonb43767a2011-03-22 01:34:44 +0000121 {
122// DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n",
123// ch, (uint8_t)ch,
124// g_long_options[long_option_index].name,
125// g_long_options[long_option_index].has_arg ? '=' : ' ',
126// optarg ? optarg : "");
127 switch (ch)
128 {
129 case 0: // Any optional that auto set themselves will return 0
130 break;
131
132 case 'l': // Set Log File
133 if (optarg && optarg[0])
134 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000135 if ((strcasecmp(optarg, "stdout") == 0) || (strcmp(optarg, "/dev/stdout") == 0))
136 {
137 log_stream_sp.reset (new StreamFile (stdout, false));
138 }
139 else if ((strcasecmp(optarg, "stderr") == 0) || (strcmp(optarg, "/dev/stderr") == 0))
140 {
141 log_stream_sp.reset (new StreamFile (stderr, false));
142 }
Greg Claytonb43767a2011-03-22 01:34:44 +0000143 else
144 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000145 FILE *log_file = fopen(optarg, "w");
146 if (log_file)
147 {
Greg Claytonb43767a2011-03-22 01:34:44 +0000148 setlinebuf(log_file);
Greg Clayton1cb64962011-03-24 04:28:38 +0000149 log_stream_sp.reset (new StreamFile (log_file, true));
150 }
151 else
152 {
153 const char *errno_str = strerror(errno);
154 fprintf (stderr, "Failed to open log file '%s' for writing: errno = %i (%s)", optarg, errno, errno_str ? errno_str : "unknown error");
155 }
156
Greg Claytonb43767a2011-03-22 01:34:44 +0000157 }
158
Greg Claytonb43767a2011-03-22 01:34:44 +0000159 }
160 break;
161
162 case 'f': // Log Flags
163 if (optarg && optarg[0])
Greg Clayton1cb64962011-03-24 04:28:38 +0000164 log_args.AppendArgument(optarg);
Greg Claytonb43767a2011-03-22 01:34:44 +0000165 break;
Greg Claytond314e812011-03-23 00:09:55 +0000166
167 case 'L':
Greg Clayton73bf5db2011-06-17 01:22:15 +0000168 listen_host_port.append (optarg);
Greg Claytond314e812011-03-23 00:09:55 +0000169 break;
Greg Claytonb43767a2011-03-22 01:34:44 +0000170 }
171 }
172
Greg Clayton1cb64962011-03-24 04:28:38 +0000173 if (log_stream_sp)
174 {
175 if (log_args.GetArgumentCount() == 0)
176 log_args.AppendArgument("default");
Jim Ingham228063c2012-02-21 02:23:08 +0000177 ProcessGDBRemoteLog::EnableLog (log_stream_sp, 0,log_args.GetConstArgumentVector(), log_stream_sp.get());
Greg Clayton1cb64962011-03-24 04:28:38 +0000178 }
179
Greg Claytonb7ad58a2013-04-04 20:35:24 +0000180 // Skip any options we consumed with getopt_long_only
Greg Claytonb43767a2011-03-22 01:34:44 +0000181 argc -= optind;
182 argv += optind;
183
184
Greg Clayton8b82f082011-04-12 05:54:46 +0000185 GDBRemoteCommunicationServer gdb_server (true);
Greg Clayton73bf5db2011-06-17 01:22:15 +0000186 if (!listen_host_port.empty())
Greg Claytond314e812011-03-23 00:09:55 +0000187 {
Greg Clayton7b0992d2013-04-18 22:45:39 +0000188 std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
Greg Claytond314e812011-03-23 00:09:55 +0000189 if (conn_ap.get())
190 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000191 std::string connect_url ("listen://");
Greg Clayton73bf5db2011-06-17 01:22:15 +0000192 connect_url.append(listen_host_port.c_str());
Greg Clayton1cb64962011-03-24 04:28:38 +0000193
Greg Clayton73bf5db2011-06-17 01:22:15 +0000194 printf ("Listening for a connection on %s...\n", listen_host_port.c_str());
Greg Clayton1cb64962011-03-24 04:28:38 +0000195 if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess)
Greg Claytond314e812011-03-23 00:09:55 +0000196 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000197 printf ("Connection established.\n");
198 gdb_server.SetConnection (conn_ap.release());
Greg Claytond314e812011-03-23 00:09:55 +0000199 }
200 }
201 }
202
203
204 if (gdb_server.IsConnected())
205 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000206 // After we connected, we need to get an initial ack from...
207 if (gdb_server.HandshakeWithClient(&error))
Greg Claytond314e812011-03-23 00:09:55 +0000208 {
209 bool interrupt = false;
210 bool done = false;
211 while (!interrupt && !done)
212 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000213 if (!gdb_server.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done))
Greg Clayton1cb64962011-03-24 04:28:38 +0000214 break;
Greg Claytond314e812011-03-23 00:09:55 +0000215 }
Greg Clayton644247c2011-07-07 01:59:51 +0000216
217 if (error.Fail())
218 {
219 fprintf(stderr, "error: %s\n", error.AsCString());
220 }
Greg Claytond314e812011-03-23 00:09:55 +0000221 }
222 else
223 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000224 fprintf(stderr, "error: handshake with client failed\n");
Greg Claytond314e812011-03-23 00:09:55 +0000225 }
226 }
Greg Claytonb43767a2011-03-22 01:34:44 +0000227
Greg Clayton1cb64962011-03-24 04:28:38 +0000228 Debugger::Terminate();
229
Greg Claytonb43767a2011-03-22 01:34:44 +0000230 return 0;
231}