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

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

Issue 135843003: Fix several little buglets with stepping (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 11 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
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:convert"; 10 import "dart:convert";
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 void matchResponse(Debugger debugger) { 173 void matchResponse(Debugger debugger) {
174 Map response = debugger.currentMessage; 174 Map response = debugger.currentMessage;
175 var id = template["id"]; 175 var id = template["id"];
176 assert(id != null && id >= 0); 176 assert(id != null && id >= 0);
177 if (response["id"] != id) { 177 if (response["id"] != id) {
178 debugger.error("Error: expected messaged id $id but got ${response["id"]}. "); 178 debugger.error("Error: expected messaged id $id but got ${response["id"]}. ");
179 } 179 }
180 } 180 }
181 } 181 }
182 182
183 class GetLineTableCmd extends Command {
184 GetLineTableCmd() {
185 template = {"id": 0,
186 "command": "getLineNumberTable",
187 "params": {"isolateId": 0, "libraryId": 0, "url": ""}};
188 }
189
190 void send(Debugger debugger) {
191 assert(debugger.scriptUrl != null);
192 template["params"]["url"] = debugger.scriptUrl;
193 template["params"]["libraryId"] = debugger.libraryId;
194 debugger.sendMessage(template);
195 }
196
197 void matchResponse(Debugger debugger) {
198 super.matchResponse(debugger);
199 List<List<int>> table = getJsonValue(debugger.currentMessage, "result:lines" );
200 debugger.tokenToLine = {};
201 for (var line in table) {
202 // Each entry begins with a line number...
203 var lineNumber = line[0];
204 for (var pos = 1; pos < line.length; pos += 2) {
205 // ...and is followed by (token offset, col number) pairs.
206 var tokenOffset = line[pos];
207 debugger.tokenToLine[tokenOffset] = lineNumber;
208 }
209 }
210 }
211 }
212
213
214 class LineMatcher extends Command {
215 int expectedLineNumber;
216
217 LineMatcher(this.expectedLineNumber) {
218 template = {"id": 0, "command": "getStackTrace", "params": {"isolateId": 0}} ;
219 }
220
221 void matchResponse(Debugger debugger) {
222 assert(debugger.tokenToLine != null);
223 super.matchResponse(debugger);
224 var msg = debugger.currentMessage;
225 List frames = getJsonValue(msg, "result:callFrames");
226 assert(frames != null);
227 var tokenOffset = frames[0]["location"]["tokenOffset"];
228 assert(tokenOffset != null);
229 var lineNumber = debugger.tokenToLine[tokenOffset];
230 assert(lineNumber != null);
231 if (expectedLineNumber != lineNumber) {
232 debugger.error("Error: expected pause at line $expectedLineNumber "
233 "but reported line is $lineNumber.");
234 return;
235 }
236 print("Matched line number $lineNumber");
237 }
238 }
239
240 MatchLine(lineNumber) {
241 return new LineMatcher(lineNumber);
242 }
243
183 244
184 class FrameMatcher extends Command { 245 class FrameMatcher extends Command {
185 int frameIndex; 246 int frameIndex;
186 List<String> functionNames; 247 List<String> functionNames;
187 bool exactMatch; 248 bool exactMatch;
188 249
189 FrameMatcher(this.frameIndex, this.functionNames, this.exactMatch) { 250 FrameMatcher(this.frameIndex, this.functionNames, this.exactMatch) {
190 template = {"id": 0, "command": "getStackTrace", "params": {"isolateId": 0}} ; 251 template = {"id": 0, "command": "getStackTrace", "params": {"isolateId": 0}} ;
191 } 252 }
192 253
193 void matchResponse(Debugger debugger) { 254 void matchResponse(Debugger debugger) {
194 super.matchResponse(debugger); 255 super.matchResponse(debugger);
195 var msg = debugger.currentMessage; 256 var msg = debugger.currentMessage;
196 List frames = getJsonValue(msg, "result:callFrames"); 257 List frames = getJsonValue(msg, "result:callFrames");
197 assert(frames != null); 258 assert(frames != null);
198 if (debugger.scriptUrl == null) { 259 if (debugger.scriptUrl == null) {
199 var name = frames[0]["functionName"]; 260 var name = frames[0]["functionName"];
200 if (name == "main") { 261 if (name == "main") {
201 // Extract script url of debugged script. 262 // Extract script url of debugged script.
202 debugger.scriptUrl = frames[0]["location"]["url"]; 263 debugger.scriptUrl = frames[0]["location"]["url"];
203 assert(debugger.scriptUrl != null); 264 assert(debugger.scriptUrl != null);
265 debugger.libraryId = frames[0]["location"]["libraryId"];
266 assert(debugger.libraryId != null);
204 } 267 }
205 } 268 }
206 if (frames.length < functionNames.length) { 269 if (frames.length < functionNames.length) {
207 debugger.error("Error: stack trace not long enough " 270 debugger.error("Error: stack trace not long enough "
208 "to match ${functionNames.length} frames"); 271 "to match ${functionNames.length} frames");
209 return; 272 return;
210 } 273 }
211 for (int i = 0; i < functionNames.length; i++) { 274 for (int i = 0; i < functionNames.length; i++) {
212 var idx = i + frameIndex; 275 var idx = i + frameIndex;
213 var name = frames[idx]["functionName"]; 276 var name = frames[idx]["functionName"];
214 assert(name != null); 277 assert(name != null);
215 bool isMatch = exactMatch ? name == functionNames[i] 278 bool isMatch = exactMatch ? name == functionNames[i]
216 : name.contains(functionNames[i]); 279 : name.contains(functionNames[i]);
217 if (!isMatch) { 280 if (!isMatch) {
218 debugger.error("Error: call frame $idx: " 281 debugger.error("Error: call frame $idx: "
219 "expected function name '${functionNames[i]}' but found '$name'"); 282 "expected function name '${functionNames[i]}' but found '$name'");
220 return; 283 return;
221 } 284 }
222 } 285 }
286 print("Matched frames: $functionNames");
223 } 287 }
224 } 288 }
225 289
226 290
227 MatchFrame(int frameIndex, String functionName, {exactMatch: false}) { 291 MatchFrame(int frameIndex, String functionName, {exactMatch: false}) {
228 return new FrameMatcher(frameIndex, [functionName], exactMatch); 292 return new FrameMatcher(frameIndex, [functionName], exactMatch);
229 } 293 }
230 294
231 MatchFrames(List<String> functionNames, {exactMatch: false}) { 295 MatchFrames(List<String> functionNames, {exactMatch: false}) {
232 return new FrameMatcher(0, functionNames, exactMatch); 296 return new FrameMatcher(0, functionNames, exactMatch);
(...skipping 24 matching lines...) Expand all
257 return; 321 return;
258 } 322 }
259 String expected = locals[key]; 323 String expected = locals[key];
260 String actual = reportedLocals[key]['text']; 324 String actual = reportedLocals[key]['text'];
261 if (expected != actual) { 325 if (expected != actual) {
262 debugger.error("Error in $functionName(): got '$actual' for local " 326 debugger.error("Error in $functionName(): got '$actual' for local "
263 "variable $key, but expected '$expected'"); 327 "variable $key, but expected '$expected'");
264 return; 328 return;
265 } 329 }
266 } 330 }
331 print("Matched locals ${locals.keys}");
267 } 332 }
268 } 333 }
269 334
270 335
271 MatchLocals(Map localValues) { 336 MatchLocals(Map localValues) {
272 return new LocalsMatcher(localValues); 337 return new LocalsMatcher(localValues);
273 } 338 }
274 339
275 340
276 class EventMatcher { 341 class EventMatcher {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 RunCommand.stepInto() { 376 RunCommand.stepInto() {
312 template = {"id": 0, "command": "stepInto", "params": {"isolateId": 0}}; 377 template = {"id": 0, "command": "stepInto", "params": {"isolateId": 0}};
313 } 378 }
314 RunCommand.stepOut() { 379 RunCommand.stepOut() {
315 template = {"id": 0, "command": "stepOut", "params": {"isolateId": 0}}; 380 template = {"id": 0, "command": "stepOut", "params": {"isolateId": 0}};
316 } 381 }
317 void send(Debugger debugger) { 382 void send(Debugger debugger) {
318 debugger.sendMessage(template); 383 debugger.sendMessage(template);
319 debugger.isPaused = false; 384 debugger.isPaused = false;
320 } 385 }
386 void matchResponse(Debugger debugger) {
387 super.matchResponse(debugger);
388 print("Command: ${template['command']}");
389 }
321 } 390 }
322 391
323 392
324 Resume() => new RunCommand.resume(); 393 Resume() => new RunCommand.resume();
325 Step() => new RunCommand.step(); 394 Step() => new RunCommand.step();
326 StepInto() => new RunCommand.stepInto(); 395 StepInto() => new RunCommand.stepInto();
327 StepOut() => new RunCommand.stepOut(); 396 StepOut() => new RunCommand.stepOut();
328 397
329 class SetBreakpointCommand extends Command { 398 class SetBreakpointCommand extends Command {
330 int line; 399 int line;
331 SetBreakpointCommand(int this.line) { 400 SetBreakpointCommand(int this.line) {
332 template = {"id": 0, 401 template = {"id": 0,
333 "command": "setBreakpoint", 402 "command": "setBreakpoint",
334 "params": { "isolateId": 0, 403 "params": { "isolateId": 0,
335 "url": null, 404 "url": null,
336 "line": null }}; 405 "line": null }};
337 } 406 }
338 407
339 void send(Debugger debugger) { 408 void send(Debugger debugger) {
340 assert(debugger.scriptUrl != null); 409 assert(debugger.scriptUrl != null);
341 template["params"]["url"] = debugger.scriptUrl; 410 template["params"]["url"] = debugger.scriptUrl;
342 template["params"]["line"] = line; 411 template["params"]["line"] = line;
343 debugger.sendMessage(template); 412 debugger.sendMessage(template);
344 } 413 }
414
415 void matchResponse(Debugger debugger) {
416 super.matchResponse(debugger);
417 print("Set breakpoint at line $line");
418 }
345 } 419 }
346 420
347 SetBreakpoint(int line) => new SetBreakpointCommand(line); 421 SetBreakpoint(int line) => new SetBreakpointCommand(line);
348 422
349 class Event { 423 class Event {
350 String name; 424 String name;
351 Map params; 425 Map params;
352 426
353 Event(Map json) { 427 Event(Map json) {
354 name = json['event']; 428 name = json['event'];
355 params = json['params']; 429 params = json['params'];
356 } 430 }
357 } 431 }
358 432
359 433
360 // A debug script is a list of Command objects. 434 // A debug script is a list of Command objects.
361 class DebugScript { 435 class DebugScript {
362 List entries; 436 List entries;
363 DebugScript(List scriptEntries) { 437 DebugScript(List scriptEntries) {
364 entries = new List.from(scriptEntries.reversed); 438 entries = new List.from(scriptEntries.reversed);
439 entries.add(new GetLineTableCmd());
365 entries.add(MatchFrame(0, "main")); 440 entries.add(MatchFrame(0, "main"));
366 } 441 }
367 bool get isEmpty => entries.isEmpty; 442 bool get isEmpty => entries.isEmpty;
368 bool get isNextEventMatcher => !isEmpty && currentEntry is EventMatcher; 443 bool get isNextEventMatcher => !isEmpty && currentEntry is EventMatcher;
369 get currentEntry => entries.last; 444 get currentEntry => entries.last;
370 advance() => entries.removeLast(); 445 advance() => entries.removeLast();
371 add(entry) => entries.add(entry); 446 add(entry) => entries.add(entry);
372 } 447 }
373 448
374 449
375 class Debugger { 450 class Debugger {
376 // Debug target process properties. 451 // Debug target process properties.
377 Process targetProcess; 452 Process targetProcess;
378 Socket socket; 453 Socket socket;
379 JsonBuffer responses = new JsonBuffer(); 454 JsonBuffer responses = new JsonBuffer();
380 455
381 DebugScript script; 456 DebugScript script;
382 int seqNr = 0; // Sequence number of next debugger command message. 457 int seqNr = 0; // Sequence number of next debugger command message.
383 Command lastCommand = null; // Most recent command sent to target. 458 Command lastCommand = null; // Most recent command sent to target.
384 List<String> errors = new List(); 459 List<String> errors = new List();
385 List<Event> events = new List(); 460 List<Event> events = new List();
386 bool cleanupDone = false; 461 bool cleanupDone = false;
387 462
388 // Data collected from debug target. 463 // Data collected from debug target.
389 Map currentMessage = null; // Currently handled message sent by target. 464 Map currentMessage = null; // Currently handled message sent by target.
390 String scriptUrl = null; 465 String scriptUrl = null;
466 int libraryId = null;
467 Map<int,int> tokenToLine = null;
391 bool shutdownEventSeen = false; 468 bool shutdownEventSeen = false;
392 int isolateId = 0; 469 int isolateId = 0;
393 bool isPaused = false; 470 bool isPaused = false;
394 471
395 Debugger(this.targetProcess, this.script) { 472 Debugger(this.targetProcess, this.script) {
396 var stdoutStringStream = targetProcess.stdout 473 var stdoutStringStream = targetProcess.stdout
397 .transform(UTF8.decoder) 474 .transform(UTF8.decoder)
398 .transform(new LineSplitter()); 475 .transform(new LineSplitter());
399 stdoutStringStream.listen((line) { 476 stdoutStringStream.listen((line) {
400 print("TARG: $line"); 477 print("TARG: $line");
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 targetOpts.add("--debuggee"); 694 targetOpts.add("--debuggee");
618 print('args: ${targetOpts.join(" ")}'); 695 print('args: ${targetOpts.join(" ")}');
619 696
620 Process.start(Platform.executable, targetOpts).then((Process process) { 697 Process.start(Platform.executable, targetOpts).then((Process process) {
621 print("Debug target process started, pid ${process.pid}."); 698 print("Debug target process started, pid ${process.pid}.");
622 process.stdin.close(); 699 process.stdin.close();
623 var debugger = new Debugger(process, new DebugScript(script)); 700 var debugger = new Debugger(process, new DebugScript(script));
624 }); 701 });
625 return true; 702 return true;
626 } 703 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698