Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: runtime/bin/dbg_connection_macos.cc

Issue 10357003: Beginnings of a debugger wire protocol (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/bin/dbg_connection_macos.h ('k') | runtime/bin/dbg_connection_win.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #include <errno.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/event.h>
10 #include <unistd.h>
11
12 #include "bin/dartutils.h"
13 #include "bin/dbg_connection.h"
14 #include "bin/fdutils.h"
15 #include "bin/socket.h"
16 #include "platform/thread.h"
17 #include "platform/utils.h"
18
19
20 #define INVALID_FD -1
21
22 int DebuggerConnectionImpl::kqueue_fd_ = INVALID_FD;
23 int DebuggerConnectionImpl::wakeup_fds_[2] = {INVALID_FD, INVALID_FD};
24
25
26 // Used by VM threads to send a message to the debugger connetion
27 // handler thread.
28 void DebuggerConnectionImpl::SendMessage(MessageType id) {
29 ASSERT(wakeup_fds_[1] != INVALID_FD);
30 struct Message msg;
31 msg.msg_id = id;
32 int result = FDUtils::WriteToBlocking(wakeup_fds_[1], &msg, sizeof(msg));
33 if (result != sizeof(msg)) {
34 if (result == -1) {
35 perror("Wakeup message failure: ");
36 }
37 FATAL1("Wakeup message failure. Wrote %d bytes.", result);
38 }
39 }
40
41
42 // Used by the debugger connection handler to read the messages sent
43 // by the VM.
44 bool DebuggerConnectionImpl::ReceiveMessage(Message* msg) {
45 int total_read = 0;
46 int bytes_read = 0;
47 int remaining = sizeof(Message);
48 uint8_t* buf = reinterpret_cast<uint8_t*>(msg);
49 while (remaining > 0) {
50 bytes_read =
51 TEMP_FAILURE_RETRY(read(wakeup_fds_[0], buf + total_read, remaining));
52 if ((bytes_read < 0) && (total_read == 0)) {
53 return false;
54 }
55 if (bytes_read > 0) {
56 total_read += bytes_read;
57 remaining -= bytes_read;
58 }
59 }
60 ASSERT(remaining >= 0);
61 return remaining == 0;
62 }
63
64
65 void DebuggerConnectionImpl::HandleEvent(struct kevent* event) {
66 int ident = event->ident;
67 if (ident == DebuggerConnectionHandler::listener_fd_) {
68 if (DebuggerConnectionHandler::IsConnected()) {
69 FATAL("Cannot connect to more than one debugger.\n");
70 }
71 int fd = ServerSocket::Accept(ident);
72 if (fd < 0) {
73 FATAL("Accepting new debugger connection failed.\n");
74 }
75 FDUtils::SetBlocking(fd);
76 DebuggerConnectionHandler::AcceptDbgConnection(fd);
77
78 /* For now, don't poll the debugger connection.
79 struct kevent ev_add;
80 EV_SET(&ev_add, fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
81 int status =
82 TEMP_FAILURE_RETRY(kevent(kqueue_fd_, &ev_add, 1, NULL, 0, NULL));
83 if (status == -1) {
84 FATAL1("Failed adding debugger socket to kqueue: %s\n", strerror(errno));
85 }
86 */
87 } else if (ident == DebuggerConnectionHandler::debugger_fd_) {
88 printf("unexpected: receiving debugger connection event.\n");
89 UNIMPLEMENTED();
90 } else {
91 Message msg;
92 if (ReceiveMessage(&msg)) {
93 printf("Received sync message id %d.\n", msg.msg_id);
94 }
95 }
96 }
97
98
99 void DebuggerConnectionImpl::Handler(uword args) {
100 static const intptr_t kMaxEvents = 4;
101 struct kevent events[kMaxEvents];
102
103 while (1) {
104 // Wait indefinitely for an event.
105 int result = TEMP_FAILURE_RETRY(
106 kevent(kqueue_fd_, NULL, 0, events, kMaxEvents, NULL));
107 if (result == -1) {
108 FATAL1("kevent failed %s\n", strerror(errno));
109 } else {
110 ASSERT(result <= kMaxEvents);
111 for (int i = 0; i < result; i++) {
112 HandleEvent(&events[i]);
113 }
114 }
115 }
116 printf("shutting down debugger thread\n");
117 }
118
119
120 void DebuggerConnectionImpl::SetupPollQueue() {
121 int result;
122 result = TEMP_FAILURE_RETRY(pipe(wakeup_fds_));
123 if (result != 0) {
124 FATAL1("Pipe creation failed with error %d\n", result);
125 }
126 FDUtils::SetNonBlocking(wakeup_fds_[0]);
127
128 kqueue_fd_ = TEMP_FAILURE_RETRY(kqueue());
129 if (kqueue_fd_ == -1) {
130 FATAL("Failed creating kqueue\n");
131 }
132 // Register the wakeup_fd_ with the kqueue.
133 struct kevent event;
134 EV_SET(&event, wakeup_fds_[0], EVFILT_READ, EV_ADD, 0, 0, NULL);
135 int status = TEMP_FAILURE_RETRY(kevent(kqueue_fd_, &event, 1, NULL, 0, NULL));
136 if (status == -1) {
137 FATAL1("Failed adding wakeup pipe fd to kqueue: %s\n", strerror(errno));
138 }
139
140 // Register the listening socket.
141 EV_SET(&event, DebuggerConnectionHandler::listener_fd_,
142 EVFILT_READ, EV_ADD, 0, 0, NULL);
143 status = TEMP_FAILURE_RETRY(kevent(kqueue_fd_, &event, 1, NULL, 0, NULL));
144 if (status == -1) {
145 FATAL1("Failed adding listener socket to kqueue: %s\n", strerror(errno));
146 }
147 }
148
149
150 void DebuggerConnectionImpl::StartHandler(int port_number) {
151 ASSERT(DebuggerConnectionHandler::listener_fd_ != -1);
152 SetupPollQueue();
153 int result =
154 dart::Thread::Start(&DebuggerConnectionImpl::Handler, 0);
155 if (result != 0) {
156 FATAL1("Failed to start debugger connection handler thread: %d\n", result);
157 }
158 }
OLDNEW
« no previous file with comments | « runtime/bin/dbg_connection_macos.h ('k') | runtime/bin/dbg_connection_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698