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

Side by Side Diff: src/d8-debug.cc

Issue 40290: Experimental: Merge 1395:1441 from bleeding_edge branch to the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/global/
Patch Set: Created 11 years, 9 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 | « src/d8-debug.h ('k') | src/debug.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2008 the V8 project authors. All rights reserved. 1 // Copyright 2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 10 matching lines...) Expand all
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 28
29 #include "d8.h" 29 #include "d8.h"
30 #include "d8-debug.h" 30 #include "d8-debug.h"
31 #include "platform.h"
32 #include "debug-agent.h"
31 33
32 34
33 namespace v8 { 35 namespace v8 {
34 36
35 37
36 void HandleDebugEvent(DebugEvent event, 38 void HandleDebugEvent(DebugEvent event,
37 Handle<Object> exec_state, 39 Handle<Object> exec_state,
38 Handle<Object> event_data, 40 Handle<Object> event_data,
39 Handle<Value> data) { 41 Handle<Value> data) {
40 HandleScope scope; 42 HandleScope scope;
41 43
42 // Check for handled event. 44 // Check for handled event.
43 if (event != Break && event != Exception && event != AfterCompile) { 45 if (event != Break && event != Exception && event != AfterCompile) {
44 return; 46 return;
45 } 47 }
46 48
47 TryCatch try_catch; 49 TryCatch try_catch;
48 50
49 // Get the toJSONProtocol function on the event and get the JSON format. 51 // Get the toJSONProtocol function on the event and get the JSON format.
50 Local<String> to_json_fun_name = String::New("toJSONProtocol"); 52 Local<String> to_json_fun_name = String::New("toJSONProtocol");
51 Local<Function> to_json_fun = 53 Local<Function> to_json_fun =
52 Function::Cast(*event_data->Get(to_json_fun_name)); 54 Function::Cast(*event_data->Get(to_json_fun_name));
53 Local<Value> event_json = to_json_fun->Call(event_data, 0, NULL); 55 Local<Value> event_json = to_json_fun->Call(event_data, 0, NULL);
54 if (try_catch.HasCaught()) { 56 if (try_catch.HasCaught()) {
55 Shell::ReportException(&try_catch); 57 Shell::ReportException(&try_catch);
56 return; 58 return;
57 } 59 }
58 60
59 // Print the event details. 61 // Print the event details.
60 Handle<String> details = 62 Handle<Object> details =
61 Shell::DebugEventToText(Handle<String>::Cast(event_json)); 63 Shell::DebugMessageDetails(Handle<String>::Cast(event_json));
62 if (details->Length() == 0) { 64 if (try_catch.HasCaught()) {
65 Shell::ReportException(&try_catch);
66 return;
67 }
68 String::Utf8Value str(details->Get(String::New("text")));
69 if (str.length() == 0) {
63 // Empty string is used to signal not to process this event. 70 // Empty string is used to signal not to process this event.
64 return; 71 return;
65 } 72 }
66 String::Utf8Value str(details);
67 printf("%s\n", *str); 73 printf("%s\n", *str);
68 74
69 // Get the debug command processor. 75 // Get the debug command processor.
70 Local<String> fun_name = String::New("debugCommandProcessor"); 76 Local<String> fun_name = String::New("debugCommandProcessor");
71 Local<Function> fun = Function::Cast(*exec_state->Get(fun_name)); 77 Local<Function> fun = Function::Cast(*exec_state->Get(fun_name));
72 Local<Object> cmd_processor = 78 Local<Object> cmd_processor =
73 Object::Cast(*fun->Call(exec_state, 0, NULL)); 79 Object::Cast(*fun->Call(exec_state, 0, NULL));
74 if (try_catch.HasCaught()) { 80 if (try_catch.HasCaught()) {
75 Shell::ReportException(&try_catch); 81 Shell::ReportException(&try_catch);
76 return; 82 return;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 fun = Handle<Function>::Cast(cmd_processor->Get(fun_name)); 122 fun = Handle<Function>::Cast(cmd_processor->Get(fun_name));
117 args[0] = request; 123 args[0] = request;
118 Handle<Value> response_val = fun->Call(cmd_processor, kArgc, args); 124 Handle<Value> response_val = fun->Call(cmd_processor, kArgc, args);
119 if (try_catch.HasCaught()) { 125 if (try_catch.HasCaught()) {
120 Shell::ReportException(&try_catch); 126 Shell::ReportException(&try_catch);
121 continue; 127 continue;
122 } 128 }
123 Handle<String> response = Handle<String>::Cast(response_val); 129 Handle<String> response = Handle<String>::Cast(response_val);
124 130
125 // Convert the debugger response into text details and the running state. 131 // Convert the debugger response into text details and the running state.
126 Handle<Object> response_details = Shell::DebugResponseDetails(response); 132 Handle<Object> response_details = Shell::DebugMessageDetails(response);
127 if (try_catch.HasCaught()) { 133 if (try_catch.HasCaught()) {
128 Shell::ReportException(&try_catch); 134 Shell::ReportException(&try_catch);
129 continue; 135 continue;
130 } 136 }
131 String::Utf8Value text_str(response_details->Get(String::New("text"))); 137 String::Utf8Value text_str(response_details->Get(String::New("text")));
132 if (text_str.length() > 0) { 138 if (text_str.length() > 0) {
133 printf("%s\n", *text_str); 139 printf("%s\n", *text_str);
134 } 140 }
135 running = 141 running =
136 response_details->Get(String::New("running"))->ToBoolean()->Value(); 142 response_details->Get(String::New("running"))->ToBoolean()->Value();
137 } 143 }
138 } 144 }
139 145
140 146
147 void RunRemoteDebugger(int port) {
148 RemoteDebugger debugger(port);
149 debugger.Run();
150 }
151
152
153 void RemoteDebugger::Run() {
154 bool ok;
155
156 // Make sure that socket support is initialized.
157 ok = i::Socket::Setup();
158 if (!ok) {
159 printf("Unable to initialize socket support %d\n", i::Socket::LastError());
160 return;
161 }
162
163 // Connect to the debugger agent.
164 conn_ = i::OS::CreateSocket();
165 static const int kPortStrSize = 6;
166 char port_str[kPortStrSize];
167 i::OS::SNPrintF(i::Vector<char>(port_str, kPortStrSize), "%d", port_);
168 ok = conn_->Connect("localhost", port_str);
169 if (!ok) {
170 printf("Unable to connect to debug agent %d\n", i::Socket::LastError());
171 return;
172 }
173
174 // Start the receiver thread.
175 ReceiverThread receiver(this);
176 receiver.Start();
177
178 // Start the keyboard thread.
179 KeyboardThread keyboard(this);
180 keyboard.Start();
181
182 // Process events received from debugged VM and from the keyboard.
183 bool terminate = false;
184 while (!terminate) {
185 event_available_->Wait();
186 RemoteDebuggerEvent* event = GetEvent();
187 switch (event->type()) {
188 case RemoteDebuggerEvent::kMessage:
189 HandleMessageReceived(event->data());
190 break;
191 case RemoteDebuggerEvent::kKeyboard:
192 HandleKeyboardCommand(event->data());
193 break;
194 case RemoteDebuggerEvent::kDisconnect:
195 terminate = true;
196 break;
197
198 default:
199 UNREACHABLE();
200 }
201 delete event;
202 }
203
204 // Wait for the receiver thread to end.
205 receiver.Join();
206 }
207
208
209 void RemoteDebugger::MessageReceived(i::SmartPointer<char> message) {
210 RemoteDebuggerEvent* event =
211 new RemoteDebuggerEvent(RemoteDebuggerEvent::kMessage, message);
212 AddEvent(event);
213 }
214
215
216 void RemoteDebugger::KeyboardCommand(i::SmartPointer<char> command) {
217 RemoteDebuggerEvent* event =
218 new RemoteDebuggerEvent(RemoteDebuggerEvent::kKeyboard, command);
219 AddEvent(event);
220 }
221
222
223 void RemoteDebugger::ConnectionClosed() {
224 RemoteDebuggerEvent* event =
225 new RemoteDebuggerEvent(RemoteDebuggerEvent::kDisconnect,
226 i::SmartPointer<char>());
227 AddEvent(event);
228 }
229
230
231 void RemoteDebugger::AddEvent(RemoteDebuggerEvent* event) {
232 i::ScopedLock lock(event_access_);
233 if (head_ == NULL) {
234 ASSERT(tail_ == NULL);
235 head_ = event;
236 tail_ = event;
237 } else {
238 ASSERT(tail_ != NULL);
239 tail_->set_next(event);
240 tail_ = event;
241 }
242 event_available_->Signal();
243 }
244
245
246 RemoteDebuggerEvent* RemoteDebugger::GetEvent() {
247 i::ScopedLock lock(event_access_);
248 ASSERT(head_ != NULL);
249 RemoteDebuggerEvent* result = head_;
250 head_ = head_->next();
251 if (head_ == NULL) {
252 ASSERT(tail_ == result);
253 tail_ = NULL;
254 }
255 return result;
256 }
257
258
259 void RemoteDebugger::HandleMessageReceived(char* message) {
260 HandleScope scope;
261
262 // Print the event details.
263 TryCatch try_catch;
264 Handle<Object> details =
265 Shell::DebugMessageDetails(Handle<String>::Cast(String::New(message)));
266 if (try_catch.HasCaught()) {
267 Shell::ReportException(&try_catch);
268 return;
269 }
270 String::Utf8Value str(details->Get(String::New("text")));
271 if (str.length() == 0) {
272 // Empty string is used to signal not to process this event.
273 return;
274 }
275 if (*str != NULL) {
276 printf("%s\n", *str);
277 } else {
278 printf("???\n");
279 }
280 printf("dbg> ");
281 }
282
283
284 void RemoteDebugger::HandleKeyboardCommand(char* command) {
285 HandleScope scope;
286
287 // Convert the debugger command to a JSON debugger request.
288 TryCatch try_catch;
289 Handle<Value> request =
290 Shell::DebugCommandToJSONRequest(String::New(command));
291 if (try_catch.HasCaught()) {
292 Shell::ReportException(&try_catch);
293 return;
294 }
295
296 // If undefined is returned the command was handled internally and there is
297 // no JSON to send.
298 if (request->IsUndefined()) {
299 return;
300 }
301
302 // Send the JSON debugger request.
303 i::DebuggerAgentUtil::SendMessage(conn_, Handle<String>::Cast(request));
304 }
305
306
307 void ReceiverThread::Run() {
308 while (true) {
309 // Receive a message.
310 i::SmartPointer<char> message =
311 i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn());
312 if (*message == NULL) {
313 remote_debugger_->ConnectionClosed();
314 return;
315 }
316
317 // Pass the message to the main thread.
318 remote_debugger_->MessageReceived(message);
319 }
320 }
321
322
323 void KeyboardThread::Run() {
324 static const int kBufferSize = 256;
325 while (true) {
326 // read keyboard input.
327 char command[kBufferSize];
328 char* str = fgets(command, kBufferSize, stdin);
329 if (str == NULL) {
330 break;
331 }
332
333 // Pass the keyboard command to the main thread.
334 remote_debugger_->KeyboardCommand(
335 i::SmartPointer<char>(i::OS::StrDup(command)));
336 }
337 }
338
339
141 } // namespace v8 340 } // namespace v8
OLDNEW
« no previous file with comments | « src/d8-debug.h ('k') | src/debug.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698