blob: 7426d21a75ebdcf9d2752abed39c5911ec8aa522 [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
Greg Claytond314e812011-03-23 00:09:55 +000010// C Includes
Greg Claytonb43767a2011-03-22 01:34:44 +000011#include <errno.h>
12#include <getopt.h>
13#include <signal.h>
14#include <stdint.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18
Greg Claytond314e812011-03-23 00:09:55 +000019// C++ Includes
20
21// Other libraries and framework includes
22#include "lldb/Core/Error.h"
23#include "lldb/Core/ConnectionFileDescriptor.h"
Greg Clayton9b1e1cd2011-04-04 18:18:57 +000024#include "lldb/Core/ConnectionMachPort.h"
Greg Clayton1cb64962011-03-24 04:28:38 +000025#include "lldb/Core/Debugger.h"
26#include "lldb/Core/StreamFile.h"
Greg Clayton576d8832011-03-22 04:00:09 +000027#include "GDBRemoteCommunicationServer.h"
Greg Clayton1cb64962011-03-24 04:28:38 +000028#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
Greg Claytond314e812011-03-23 00:09:55 +000029using namespace lldb;
30using namespace lldb_private;
31
Greg Claytonb43767a2011-03-22 01:34:44 +000032//----------------------------------------------------------------------
33// option descriptors for getopt_long()
34//----------------------------------------------------------------------
35
36int g_debug = 0;
37int g_verbose = 0;
38
39static struct option g_long_options[] =
40{
41 { "debug", no_argument, &g_debug, 1 },
42 { "verbose", no_argument, &g_verbose, 1 },
43 { "log-file", required_argument, NULL, 'l' },
44 { "log-flags", required_argument, NULL, 'f' },
Greg Claytond314e812011-03-23 00:09:55 +000045 { "listen", required_argument, NULL, 'L' },
Greg Claytonb43767a2011-03-22 01:34:44 +000046 { NULL, 0, NULL, 0 }
47};
48
49//----------------------------------------------------------------------
50// Watch for signals
51//----------------------------------------------------------------------
52int g_sigpipe_received = 0;
53void
54signal_handler(int signo)
55{
56 switch (signo)
57 {
58 case SIGPIPE:
59 g_sigpipe_received = 1;
60 break;
61 }
62}
63
64//----------------------------------------------------------------------
65// main
66//----------------------------------------------------------------------
67int
68main (int argc, char *argv[])
69{
70 signal (SIGPIPE, signal_handler);
71 int long_option_index = 0;
Greg Clayton1cb64962011-03-24 04:28:38 +000072 StreamSP log_stream_sp;
73 Args log_args;
Greg Clayton9b1e1cd2011-04-04 18:18:57 +000074 Error error;
Greg Clayton73bf5db2011-06-17 01:22:15 +000075 std::string listen_host_port;
Greg Clayton9d3d6882011-10-31 23:51:19 +000076 int ch;
Greg Clayton1cb64962011-03-24 04:28:38 +000077 Debugger::Initialize();
78
Greg Clayton9b1e1cd2011-04-04 18:18:57 +000079// ConnectionMachPort a;
80// ConnectionMachPort b;
81//
82// lldb::ConnectionStatus status;
83// const char *bootstrap_service_name = "HelloWorld";
84// status = a.BootstrapCheckIn(bootstrap_service_name, &error);
85//
86// if (status != eConnectionStatusSuccess)
87// {
88// fprintf(stderr, "%s", error.AsCString());
89// return 1;
90// }
91// status = b.BootstrapLookup (bootstrap_service_name, &error);
92// if (status != eConnectionStatusSuccess)
93// {
94// fprintf(stderr, "%s", error.AsCString());
95// return 2;
96// }
97//
98// if (a.Write ("hello", 5, status, &error) == 5)
99// {
100// char buf[32];
101// memset(buf, 0, sizeof(buf));
102// if (b.Read (buf, 5, status, &error))
103// {
104// printf("read returned bytes: %s", buf);
105// }
106// else
107// {
108// fprintf(stderr, "%s", error.AsCString());
109// return 4;
110// }
111// }
112// else
113// {
114// fprintf(stderr, "%s", error.AsCString());
115// return 3;
116// }
117
Greg Clayton1cb64962011-03-24 04:28:38 +0000118 while ((ch = getopt_long(argc, argv, "l:f:L:", g_long_options, &long_option_index)) != -1)
Greg Claytonb43767a2011-03-22 01:34:44 +0000119 {
120// DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n",
121// ch, (uint8_t)ch,
122// g_long_options[long_option_index].name,
123// g_long_options[long_option_index].has_arg ? '=' : ' ',
124// optarg ? optarg : "");
125 switch (ch)
126 {
127 case 0: // Any optional that auto set themselves will return 0
128 break;
129
130 case 'l': // Set Log File
131 if (optarg && optarg[0])
132 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000133 if ((strcasecmp(optarg, "stdout") == 0) || (strcmp(optarg, "/dev/stdout") == 0))
134 {
135 log_stream_sp.reset (new StreamFile (stdout, false));
136 }
137 else if ((strcasecmp(optarg, "stderr") == 0) || (strcmp(optarg, "/dev/stderr") == 0))
138 {
139 log_stream_sp.reset (new StreamFile (stderr, false));
140 }
Greg Claytonb43767a2011-03-22 01:34:44 +0000141 else
142 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000143 FILE *log_file = fopen(optarg, "w");
144 if (log_file)
145 {
Greg Claytonb43767a2011-03-22 01:34:44 +0000146 setlinebuf(log_file);
Greg Clayton1cb64962011-03-24 04:28:38 +0000147 log_stream_sp.reset (new StreamFile (log_file, true));
148 }
149 else
150 {
151 const char *errno_str = strerror(errno);
152 fprintf (stderr, "Failed to open log file '%s' for writing: errno = %i (%s)", optarg, errno, errno_str ? errno_str : "unknown error");
153 }
154
Greg Claytonb43767a2011-03-22 01:34:44 +0000155 }
156
Greg Claytonb43767a2011-03-22 01:34:44 +0000157 }
158 break;
159
160 case 'f': // Log Flags
161 if (optarg && optarg[0])
Greg Clayton1cb64962011-03-24 04:28:38 +0000162 log_args.AppendArgument(optarg);
Greg Claytonb43767a2011-03-22 01:34:44 +0000163 break;
Greg Claytond314e812011-03-23 00:09:55 +0000164
165 case 'L':
Greg Clayton73bf5db2011-06-17 01:22:15 +0000166 listen_host_port.append (optarg);
Greg Claytond314e812011-03-23 00:09:55 +0000167 break;
Greg Claytonb43767a2011-03-22 01:34:44 +0000168 }
169 }
170
Greg Clayton1cb64962011-03-24 04:28:38 +0000171 if (log_stream_sp)
172 {
173 if (log_args.GetArgumentCount() == 0)
174 log_args.AppendArgument("default");
175 ProcessGDBRemoteLog::EnableLog (log_stream_sp, 0,log_args, log_stream_sp.get());
176 }
177
Greg Claytonb43767a2011-03-22 01:34:44 +0000178 // Skip any options we consumed with getopt_long
179 argc -= optind;
180 argv += optind;
181
182
Greg Clayton8b82f082011-04-12 05:54:46 +0000183 GDBRemoteCommunicationServer gdb_server (true);
Greg Clayton73bf5db2011-06-17 01:22:15 +0000184 if (!listen_host_port.empty())
Greg Claytond314e812011-03-23 00:09:55 +0000185 {
186 std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
187 if (conn_ap.get())
188 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000189 std::string connect_url ("listen://");
Greg Clayton73bf5db2011-06-17 01:22:15 +0000190 connect_url.append(listen_host_port.c_str());
Greg Clayton1cb64962011-03-24 04:28:38 +0000191
Greg Clayton73bf5db2011-06-17 01:22:15 +0000192 printf ("Listening for a connection on %s...\n", listen_host_port.c_str());
Greg Clayton1cb64962011-03-24 04:28:38 +0000193 if (conn_ap->Connect(connect_url.c_str(), &error) == eConnectionStatusSuccess)
Greg Claytond314e812011-03-23 00:09:55 +0000194 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000195 printf ("Connection established.\n");
196 gdb_server.SetConnection (conn_ap.release());
Greg Claytond314e812011-03-23 00:09:55 +0000197 }
198 }
199 }
200
201
202 if (gdb_server.IsConnected())
203 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000204 // After we connected, we need to get an initial ack from...
205 if (gdb_server.HandshakeWithClient(&error))
Greg Claytond314e812011-03-23 00:09:55 +0000206 {
207 bool interrupt = false;
208 bool done = false;
209 while (!interrupt && !done)
210 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000211 if (!gdb_server.GetPacketAndSendResponse (UINT32_MAX, error, interrupt, done))
Greg Clayton1cb64962011-03-24 04:28:38 +0000212 break;
Greg Claytond314e812011-03-23 00:09:55 +0000213 }
Greg Clayton644247c2011-07-07 01:59:51 +0000214
215 if (error.Fail())
216 {
217 fprintf(stderr, "error: %s\n", error.AsCString());
218 }
Greg Claytond314e812011-03-23 00:09:55 +0000219 }
220 else
221 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000222 fprintf(stderr, "error: handshake with client failed\n");
Greg Claytond314e812011-03-23 00:09:55 +0000223 }
224 }
Greg Claytonb43767a2011-03-22 01:34:44 +0000225
Greg Clayton1cb64962011-03-24 04:28:38 +0000226 Debugger::Terminate();
227
Greg Claytonb43767a2011-03-22 01:34:44 +0000228 return 0;
229}