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

Side by Side Diff: tests/standalone/debugger/debug_lib.dart

Issue 15507004: Let debug target pick the debugger port (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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/main.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 // Library used by debugger wire protocol tests (standalone VM debugging). 5 // Library used by debugger wire protocol tests (standalone VM debugging).
6 6
7 library DartDebugger; 7 library DartDebugger;
8 8
9 import "dart:async"; 9 import "dart:async";
10 import "dart:io"; 10 import "dart:io";
11 import "dart:math"; 11 import "dart:math";
12 import "dart:utf"; 12 import "dart:utf";
13 import "dart:json" as JSON; 13 import "dart:json" as JSON;
14 14
15 // Whether or not to print the debugger wire messages on the console. 15 // Whether or not to print the debugger wire messages on the console.
16 var verboseWire = false; 16 var verboseWire = false;
17 17
18 // The number of attempts made to find an unused debugger port.
19 var retries = 0;
20
21 // Class to buffer wire protocol data from debug target and 18 // Class to buffer wire protocol data from debug target and
22 // break it down to individual json messages. 19 // break it down to individual json messages.
23 class JsonBuffer { 20 class JsonBuffer {
24 String buffer = null; 21 String buffer = null;
25 22
26 append(String s) { 23 append(String s) {
27 if (buffer == null || buffer.length == 0) { 24 if (buffer == null || buffer.length == 0) {
28 buffer = s; 25 buffer = s;
29 } else { 26 } else {
30 buffer += s; 27 buffer += s;
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 bool get isEmpty => entries.isEmpty; 287 bool get isEmpty => entries.isEmpty;
291 get currentEntry => entries.last; 288 get currentEntry => entries.last;
292 advance() => entries.removeLast(); 289 advance() => entries.removeLast();
293 add(entry) => entries.add(entry); 290 add(entry) => entries.add(entry);
294 } 291 }
295 292
296 293
297 class Debugger { 294 class Debugger {
298 // Debug target process properties. 295 // Debug target process properties.
299 Process targetProcess; 296 Process targetProcess;
300 int portNumber;
301 Socket socket; 297 Socket socket;
302 JsonBuffer responses = new JsonBuffer(); 298 JsonBuffer responses = new JsonBuffer();
303 299
304 DebugScript script; 300 DebugScript script;
305 int seqNr = 0; // Sequence number of next debugger command message. 301 int seqNr = 0; // Sequence number of next debugger command message.
306 Command lastCommand = null; // Most recent command sent to target. 302 Command lastCommand = null; // Most recent command sent to target.
307 List<String> errors = new List(); 303 List<String> errors = new List();
308 bool cleanupDone = false; 304 bool cleanupDone = false;
309 305
310 // Data collected from debug target. 306 // Data collected from debug target.
311 Map currentMessage = null; // Currently handled message sent by target. 307 Map currentMessage = null; // Currently handled message sent by target.
312 String scriptUrl = null; 308 String scriptUrl = null;
313 bool shutdownEventSeen = false; 309 bool shutdownEventSeen = false;
314 int isolateId = 0; 310 int isolateId = 0;
315 bool isPaused = false; 311 bool isPaused = false;
316 312
317 Debugger(this.targetProcess, this.portNumber, this.script) { 313 Debugger(this.targetProcess, this.script) {
318 stdin.listen((_) {}); 314 stdin.listen((_) {});
Ivan Posva 2013/05/23 02:06:11 Why is this stdin even needed? This is the stdin o
kustermann 2013/05/23 07:22:32 Correct, this should not be necessary. When have h
hausner 2013/05/23 17:41:40 Removed this line. On 2013/05/23 07:22:32, kuster
319 var stdoutStringStream = targetProcess.stdout 315 var stdoutStringStream = targetProcess.stdout
320 .transform(new StringDecoder()) 316 .transform(new StringDecoder())
321 .transform(new LineTransformer()); 317 .transform(new LineTransformer());
322 stdoutStringStream.listen((line) { 318 stdoutStringStream.listen((line) {
323 if (line == "Debugger initialized") { 319 print("TARG: $line");
324 openConnection(); 320 if (line.startsWith("Debugger listening")) {
321 RegExp portExpr = new RegExp(r"\d+");
322 var port = portExpr.stringMatch(line);
323 print("Debug target found listening at port '$port'");
324 openConnection(int.parse(port));
325 } 325 }
326 print("TARG: $line");
327 }); 326 });
328 327
329 var stderrStringStream = targetProcess.stderr 328 var stderrStringStream = targetProcess.stderr
330 .transform(new StringDecoder()) 329 .transform(new StringDecoder())
331 .transform(new LineTransformer()); 330 .transform(new LineTransformer());
332 stderrStringStream.listen((line) { 331 stderrStringStream.listen((line) {
333 print("TARG: $line"); 332 print("TARG: $line");
334 }); 333 });
335 } 334 }
336 335
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 socket.write(jsonMsg); 447 socket.write(jsonMsg);
449 } 448 }
450 449
451 bool get errorsDetected => errors.length > 0; 450 bool get errorsDetected => errors.length > 0;
452 451
453 // Record error message. 452 // Record error message.
454 void error(String s) { 453 void error(String s) {
455 errors.add(s); 454 errors.add(s);
456 } 455 }
457 456
458 void openConnection() { 457 void openConnection(int portNumber) {
459 Socket.connect("127.0.0.1", portNumber).then((s) { 458 Socket.connect("127.0.0.1", portNumber).then((s) {
460 this.socket = s; 459 this.socket = s;
461 var stringStream = socket.transform(new StringDecoder()); 460 var stringStream = socket.transform(new StringDecoder());
462 stringStream.listen((str) { 461 stringStream.listen((str) {
463 try { 462 try {
464 responses.append(str); 463 responses.append(str);
465 handleMessages(); 464 handleMessages();
466 } catch(e, trace) { 465 } catch(e, trace) {
467 print("Unexpected exception:\n$e\n$trace"); 466 print("Unexpected exception:\n$e\n$trace");
468 cleanup(); 467 cleanup();
(...skipping 23 matching lines...) Expand all
492 if (cleanupDone) return; 491 if (cleanupDone) return;
493 if (socket != null) { 492 if (socket != null) {
494 socket.close().catchError((error) { 493 socket.close().catchError((error) {
495 // Print this directly in addition to adding it to the 494 // Print this directly in addition to adding it to the
496 // error message queue, in case the error message queue 495 // error message queue, in case the error message queue
497 // gets printed before this error handler is called. 496 // gets printed before this error handler is called.
498 print("Error occurred while closing socket: $error"); 497 print("Error occurred while closing socket: $error");
499 error("Error while closing socket: $error"); 498 error("Error while closing socket: $error");
500 }); 499 });
501 } 500 }
501 var targetPid = targetProcess.pid;
502 print("Sending kill signal to process $targetPid...");
502 targetProcess.kill(); 503 targetProcess.kill();
503 // If the process was already dead exitCode is already 504 // If the process was already dead exitCode is already
504 // available and we call exit() in the next event loop cycle. 505 // available and we call exit() in the next event loop cycle.
505 // Otherwise this will wait for the process to exit. 506 // Otherwise this will wait for the process to exit.
506 targetProcess.exitCode.then((exitCode) { 507 targetProcess.exitCode.then((exitCode) {
508 print("process $targetPid terminated with exit code $exitCode.");
507 if (errorsDetected) { 509 if (errorsDetected) {
508 print("\n===== Errors detected: ====="); 510 print("\n===== Errors detected: =====");
509 for (int i = 0; i < errors.length; i++) print(errors[i]); 511 for (int i = 0; i < errors.length; i++) print(errors[i]);
510 print("============================\n"); 512 print("============================\n");
511 } 513 }
512 exit(errors.length); 514 exit(errors.length);
513 }); 515 });
514 cleanupDone = true; 516 cleanupDone = true;
515 } 517 }
516 } 518 }
517 519
518 520
519 bool RunScript(List script) { 521 bool RunScript(List script) {
520 var options = new Options(); 522 var options = new Options();
521 if (options.arguments.contains("--debuggee")) { 523 if (options.arguments.contains("--debuggee")) {
522 return false; 524 return false;
523 } 525 }
524 verboseWire = options.arguments.contains("--wire"); 526 verboseWire = options.arguments.contains("--wire");
525 527
526 // Pick a port in the upper half of the port number range. 528 // Port number 0 means debug target picks a free port dynamically.
527 var seed = new DateTime.now().millisecondsSinceEpoch; 529 var targetOpts = [ "--debug:0" ];
528 Random random = new Random(seed); 530 targetOpts.add(options.script);
529 var debugPort = random.nextInt(32000) + 32000; 531 targetOpts.add("--debuggee");
530 print('using debug port $debugPort ...'); 532 print('args: ${targetOpts.join(" ")}');
531 ServerSocket.bind('127.0.0.1', debugPort).then((ServerSocket s) {
532 s.close();
533 var targetOpts = [ "--debug:$debugPort" ];
534 // --verbose_debug is necessary so the test knows when the debuggee
535 // is initialized.
536 targetOpts.add("--verbose_debug");
537 targetOpts.add(options.script);
538 targetOpts.add("--debuggee");
539 print('args: ${targetOpts.join(" ")}');
540 533
541 Process.start(options.executable, targetOpts).then((Process process) { 534 Process.start(options.executable, targetOpts).then((Process process) {
542 print("Debug target process started"); 535 print("Debug target process started, pid ${process.pid}.");
543 process.stdin.close(); 536 process.stdin.close();
544 process.exitCode.then((int exitCode) { 537 var debugger = new Debugger(process, new DebugScript(script));
545 if (exitCode != 0) throw "bad exit code: $exitCode"; 538 });
546 print("Debug target process exited with exit code $exitCode");
547 });
548 var debugger =
549 new Debugger(process, debugPort, new DebugScript(script));
550 });
551 },
552 onError: (e) {
553 if (++retries >= 3) {
554 print('unable to find unused port: $e');
555 var trace = getAttachedStackTrace(e);
556 if (trace != null) print("StackTrace: $trace");
557 return -1;
558 } else {
559 // Retry with another random port.
560 RunScript(script);
561 }
562 });
563 return true; 539 return true;
564 } 540 }
OLDNEW
« no previous file with comments | « runtime/bin/main.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698