OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "bin/dbg_connection.h" | 5 #include "bin/dbg_connection.h" |
6 #include "bin/dbg_message.h" | 6 #include "bin/dbg_message.h" |
7 #include "bin/dartutils.h" | 7 #include "bin/dartutils.h" |
8 #include "bin/socket.h" | 8 #include "bin/socket.h" |
9 #include "bin/thread.h" | 9 #include "bin/thread.h" |
10 #include "bin/utils.h" | 10 #include "bin/utils.h" |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 } | 160 } |
161 | 161 |
162 | 162 |
163 void DebuggerConnectionHandler::HandleUnknownMsg() { | 163 void DebuggerConnectionHandler::HandleUnknownMsg() { |
164 int msg_id = msgbuf_->MessageId(); | 164 int msg_id = msgbuf_->MessageId(); |
165 ASSERT(msg_id >= 0); | 165 ASSERT(msg_id >= 0); |
166 SendError(debug_fd_, msg_id, "unknown debugger command"); | 166 SendError(debug_fd_, msg_id, "unknown debugger command"); |
167 } | 167 } |
168 | 168 |
169 | 169 |
170 typedef void (*CommandHandler)(DebuggerConnectionHandler* handler); | 170 typedef void (*CommandHandler)(DbgMessage* msg); |
171 | 171 |
172 struct JSONDebuggerCommand { | 172 struct JSONDebuggerCommand { |
173 const char* cmd_string; | 173 const char* cmd_string; |
174 CommandHandler handler_function; | 174 CommandHandler handler_function; |
175 }; | 175 }; |
176 | 176 |
177 | 177 |
178 void DebuggerConnectionHandler::HandleMessages() { | 178 void DebuggerConnectionHandler::HandleMessages() { |
179 static JSONDebuggerCommand generic_debugger_commands[] = { | 179 static JSONDebuggerCommand generic_debugger_commands[] = { |
180 { "interrupt", HandleInterruptCmd }, | 180 { "interrupt", HandleInterruptCmd }, |
181 { "isolates", HandleIsolatesListCmd }, | 181 { "isolates", HandleIsolatesListCmd }, |
182 { "quit", HandleQuitCmd }, | |
183 { NULL, NULL } | 182 { NULL, NULL } |
184 }; | 183 }; |
185 | 184 |
186 for (;;) { | 185 for (;;) { |
187 // Read a message. | 186 // Read a message. |
188 while (!msgbuf_->IsValidMessage() && msgbuf_->Alive()) { | 187 while (!msgbuf_->IsValidMessage() && msgbuf_->Alive()) { |
189 msgbuf_->ReadData(); | 188 msgbuf_->ReadData(); |
190 } | 189 } |
191 if (!msgbuf_->Alive()) { | 190 if (!msgbuf_->Alive()) { |
192 return; | 191 return; |
193 } | 192 } |
194 | 193 |
195 // Parse out the command portion from the message. | 194 // Parse out the command portion from the message. |
196 dart::JSONReader r(msgbuf_->buf()); | 195 dart::JSONReader r(msgbuf_->buf()); |
197 bool found = r.Seek("command"); | 196 bool found = r.Seek("command"); |
198 if (r.Error()) { | 197 if (r.Error()) { |
199 FATAL("Illegal JSON message received"); | 198 FATAL("Illegal JSON message received"); |
200 } | 199 } |
201 if (!found) { | 200 if (!found) { |
202 printf("'command' not found in JSON message: '%s'\n", msgbuf_->buf()); | 201 printf("'command' not found in JSON message: '%s'\n", msgbuf_->buf()); |
203 msgbuf_->PopMessage(); | 202 msgbuf_->PopMessage(); |
204 } | 203 } |
205 | 204 |
206 // Check if this is a generic command (not isolate specific). | 205 // Check if this is a generic command (not isolate specific). |
207 int i = 0; | 206 int i = 0; |
208 bool is_handled = false; | 207 bool is_handled = false; |
209 while (generic_debugger_commands[i].cmd_string != NULL) { | 208 while (generic_debugger_commands[i].cmd_string != NULL) { |
210 if (r.IsStringLiteral(generic_debugger_commands[i].cmd_string)) { | 209 if (r.IsStringLiteral(generic_debugger_commands[i].cmd_string)) { |
211 (*generic_debugger_commands[i].handler_function)(this); | 210 DbgMessage* msg = new DbgMessage(i, |
| 211 msgbuf_->buf(), |
| 212 r.EndOfObject(), |
| 213 debug_fd_); |
| 214 (*generic_debugger_commands[i].handler_function)(msg); |
212 is_handled = true; | 215 is_handled = true; |
213 msgbuf_->PopMessage(); | 216 msgbuf_->PopMessage(); |
| 217 delete msg; |
214 break; | 218 break; |
215 } | 219 } |
216 i++; | 220 i++; |
217 } | 221 } |
218 if (!is_handled) { | 222 if (!is_handled) { |
219 // Check if this is an isolate specific command. | 223 // Check if this is an isolate specific command. |
220 int32_t cmd_idx = DbgMessageQueue::LookupIsolateCommand(r.ValueChars(), | 224 int32_t cmd_idx = DbgMsgQueueList::LookupIsolateCommand(r.ValueChars(), |
221 r.ValueLen()); | 225 r.ValueLen()); |
222 if (cmd_idx != DbgMessageQueue::kInvalidCommand) { | 226 if (cmd_idx != DbgMsgQueueList::kInvalidCommand) { |
223 // Get debug message queue corresponding to isolate. | 227 // Get debug message queue corresponding to isolate. |
224 // TODO(asiva): Need to read the isolate id, map it to the appropriate | 228 // TODO(asiva): Once we have support for including the isolate id |
225 // isolate and pass it down to GetIsolateMessageQueue to get the | 229 // in the debug wire protocol we need to read the isolate id and |
226 // appropriate debug message queue. | 230 // pass it down to GetIsolateMsgQueue to get the appropriate debug |
227 DbgMessageQueue* queue = DbgMessageQueue::GetIsolateMessageQueue(NULL); | 231 // message queue. |
| 232 DbgMsgQueue* queue = |
| 233 DbgMsgQueueList::GetIsolateMsgQueue(ILLEGAL_ISOLATE_ID); |
228 ASSERT(queue != NULL); | 234 ASSERT(queue != NULL); |
229 queue->AddMessage(cmd_idx, msgbuf_->buf(), r.EndOfObject(), debug_fd_); | 235 queue->AddMessage(cmd_idx, msgbuf_->buf(), r.EndOfObject(), debug_fd_); |
230 msgbuf_->PopMessage(); | 236 msgbuf_->PopMessage(); |
231 continue; | 237 continue; |
232 } | 238 } |
233 | 239 |
234 // This is an unrecognized command, report error and move on to next. | 240 // This is an unrecognized command, report error and move on to next. |
235 printf("unrecognized command received: '%s'\n", msgbuf_->buf()); | 241 printf("unrecognized command received: '%s'\n", msgbuf_->buf()); |
236 HandleUnknownMsg(); | 242 HandleUnknownMsg(); |
237 msgbuf_->PopMessage(); | 243 msgbuf_->PopMessage(); |
(...skipping 25 matching lines...) Expand all Loading... |
263 | 269 |
264 | 270 |
265 void DebuggerConnectionHandler::StartHandler(const char* address, | 271 void DebuggerConnectionHandler::StartHandler(const char* address, |
266 int port_number) { | 272 int port_number) { |
267 MonitorLocker ml(&handler_lock_); | 273 MonitorLocker ml(&handler_lock_); |
268 if (listener_fd_ != -1) { | 274 if (listener_fd_ != -1) { |
269 return; // The debugger connection handler was already started. | 275 return; // The debugger connection handler was already started. |
270 } | 276 } |
271 | 277 |
272 // First setup breakpoint, exception and delayed breakpoint handlers. | 278 // First setup breakpoint, exception and delayed breakpoint handlers. |
273 DbgMessageQueue::Initialize(); | 279 DbgMsgQueueList::Initialize(); |
274 | 280 |
275 // Now setup a listener socket and start a thread which will | 281 // Now setup a listener socket and start a thread which will |
276 // listen, accept connections from debuggers, read and handle/dispatch | 282 // listen, accept connections from debuggers, read and handle/dispatch |
277 // debugger commands received on these connections. | 283 // debugger commands received on these connections. |
278 ASSERT(listener_fd_ == -1); | 284 ASSERT(listener_fd_ == -1); |
279 listener_fd_ = ServerSocket::CreateBindListen(address, port_number, 1); | 285 listener_fd_ = ServerSocket::CreateBindListen(address, port_number, 1); |
280 DebuggerConnectionImpl::StartHandler(port_number); | 286 DebuggerConnectionImpl::StartHandler(port_number); |
281 } | 287 } |
282 | 288 |
283 | 289 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 // corresponding to that fd and invoke HandleMessages on it. | 361 // corresponding to that fd and invoke HandleMessages on it. |
356 // For now we run that code here. | 362 // For now we run that code here. |
357 DebuggerConnectionHandler* handler = GetDebuggerConnectionHandler(debug_fd); | 363 DebuggerConnectionHandler* handler = GetDebuggerConnectionHandler(debug_fd); |
358 if (handler != NULL) { | 364 if (handler != NULL) { |
359 handler->HandleMessages(); | 365 handler->HandleMessages(); |
360 delete handler; | 366 delete handler; |
361 } | 367 } |
362 } | 368 } |
363 | 369 |
364 | 370 |
365 void DebuggerConnectionHandler::HandleInterruptCmd( | 371 void DebuggerConnectionHandler::HandleInterruptCmd(DbgMessage* in_msg) { |
366 DebuggerConnectionHandler* handler) { | 372 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len()); |
367 int msg_id = handler->MessageId(); | 373 int msg_id = msg_parser.MessageId(); |
368 ASSERT(msg_id >= 0); | 374 Dart_IsolateId isolate_id = |
369 SendError(handler->debug_fd(), msg_id, "interrupt command unimplemented"); | 375 static_cast<Dart_IsolateId>(msg_parser.GetIntParam("isolateId")); |
| 376 if (isolate_id == ILLEGAL_ISOLATE_ID || Dart_GetIsolate(isolate_id) == NULL) { |
| 377 in_msg->SendErrorReply(msg_id, "Invalid isolate specified"); |
| 378 return; |
| 379 } |
| 380 DbgMsgQueue* queue = DbgMsgQueueList::GetIsolateMsgQueue(isolate_id); |
| 381 ASSERT(queue != NULL); |
| 382 queue->InterruptIsolate(); |
| 383 dart::TextBuffer msg(64); |
| 384 msg.Printf("{ \"id\": %d }", msg_id); |
| 385 in_msg->SendReply(&msg); |
370 } | 386 } |
371 | 387 |
372 | 388 |
373 void DebuggerConnectionHandler::HandleIsolatesListCmd( | 389 void DebuggerConnectionHandler::HandleIsolatesListCmd(DbgMessage* in_msg) { |
374 DebuggerConnectionHandler* handler) { | 390 MessageParser msg_parser(in_msg->buffer(), in_msg->buffer_len()); |
375 int msg_id = handler->MessageId(); | 391 int msg_id = msg_parser.MessageId(); |
376 ASSERT(msg_id >= 0); | 392 ASSERT(msg_id >= 0); |
377 SendError(handler->debug_fd(), msg_id, "isolate list command unimplemented"); | 393 in_msg->SendErrorReply(msg_id, "isolate list command unimplemented"); |
378 } | |
379 | |
380 | |
381 void DebuggerConnectionHandler::HandleQuitCmd( | |
382 DebuggerConnectionHandler* handler) { | |
383 int msg_id = handler->MessageId(); | |
384 ASSERT(msg_id >= 0); | |
385 SendError(handler->debug_fd(), msg_id, "quit command unimplemented"); | |
386 } | 394 } |
387 | 395 |
388 | 396 |
389 void DebuggerConnectionHandler::AddNewDebuggerConnection(int debug_fd) { | 397 void DebuggerConnectionHandler::AddNewDebuggerConnection(int debug_fd) { |
390 // TODO(asiva): Support multiple debugger connections, for now we just | 398 // TODO(asiva): Support multiple debugger connections, for now we just |
391 // create one handler, store it in a static variable and use it. | 399 // create one handler, store it in a static variable and use it. |
392 ASSERT(singleton_handler == NULL); | 400 ASSERT(singleton_handler == NULL); |
393 singleton_handler = new DebuggerConnectionHandler(debug_fd); | 401 singleton_handler = new DebuggerConnectionHandler(debug_fd); |
394 } | 402 } |
395 | 403 |
(...skipping 13 matching lines...) Expand all Loading... |
409 ASSERT(singleton_handler != NULL); | 417 ASSERT(singleton_handler != NULL); |
410 return singleton_handler; | 418 return singleton_handler; |
411 } | 419 } |
412 | 420 |
413 | 421 |
414 bool DebuggerConnectionHandler::IsConnected() { | 422 bool DebuggerConnectionHandler::IsConnected() { |
415 // TODO(asiva): Support multiple debugger connections. | 423 // TODO(asiva): Support multiple debugger connections. |
416 // Return true if a connection has been established. | 424 // Return true if a connection has been established. |
417 return singleton_handler != NULL; | 425 return singleton_handler != NULL; |
418 } | 426 } |
OLD | NEW |