Redo "running" field in debug-delay.js and support "suspend" command
authorpeter.rybin@gmail.com <peter.rybin@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 15 Oct 2009 20:06:08 +0000 (20:06 +0000)
committerpeter.rybin@gmail.com <peter.rybin@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 15 Oct 2009 20:06:08 +0000 (20:06 +0000)
It also fixes "backtrace" command so that it didn't give away random stack if we are running

Review URL: http://codereview.chromium.org/242034

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3077 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

17 files changed:
src/debug-delay.js
src/debug.cc
test/mjsunit/debug-backtrace.js
test/mjsunit/debug-changebreakpoint.js
test/mjsunit/debug-clearbreakpoint.js
test/mjsunit/debug-clearbreakpointgroup.js
test/mjsunit/debug-continue.js
test/mjsunit/debug-evaluate-recursive.js
test/mjsunit/debug-evaluate.js
test/mjsunit/debug-handle.js
test/mjsunit/debug-mirror-cache.js
test/mjsunit/debug-references.js
test/mjsunit/debug-scopes.js
test/mjsunit/debug-scripts-request.js
test/mjsunit/debug-setbreakpoint.js
test/mjsunit/debug-suspend.js [new file with mode: 0644]
test/mjsunit/regress/regress-1081309.js

index cb789be..d9447bd 100644 (file)
@@ -795,8 +795,8 @@ ExecutionState.prototype.selectedFrame = function() {
   return this.selected_frame;
 };
 
-ExecutionState.prototype.debugCommandProcessor = function(protocol) {
-  return new DebugCommandProcessor(this, protocol);
+ExecutionState.prototype.debugCommandProcessor = function(opt_is_running) {
+  return new DebugCommandProcessor(this, opt_is_running);
 };
 
 
@@ -1081,9 +1081,9 @@ function MakeScriptObject_(script, include_source) {
 };
 
 
-function DebugCommandProcessor(exec_state) {
+function DebugCommandProcessor(exec_state, opt_is_running) {
   this.exec_state_ = exec_state;
-  this.running_ = false;
+  this.running_ = opt_is_running || false;
 };
 
 
@@ -1107,7 +1107,8 @@ function ProtocolMessage(request) {
     this.type = 'event';
   }
   this.success = true;
-  this.running = false;
+  // Handler may set this field to control debugger state.
+  this.running = undefined;
 }
 
 
@@ -1168,11 +1169,7 @@ ProtocolMessage.prototype.toJSONProtocol = function() {
   if (this.message) {
     json.message = this.message;
   }
-  if (this.running) {
-    json.running = true;
-  } else {
-    json.running = false;
-  }
+  json.running = this.running;
   return JSON.stringify(json);
 }
 
@@ -1244,6 +1241,8 @@ DebugCommandProcessor.prototype.processDebugJSONRequest = function(json_request)
         this.scriptsRequest_(request, response);
       } else if (request.command == 'threads') {
         this.threadsRequest_(request, response);
+      } else if (request.command == 'suspend') {
+        this.suspendRequest_(request, response);
       } else {
         throw new Error('Unknown command "' + request.command + '" in request');
       }
@@ -1258,7 +1257,11 @@ DebugCommandProcessor.prototype.processDebugJSONRequest = function(json_request)
 
     // Return the response as a JSON encoded string.
     try {
-      this.running_ = response.running;  // Store the running state.
+      if (!IS_UNDEFINED(response.running)) {
+        // Response controls running state.
+        this.running_ = response.running;
+      }
+      response.running = this.running_; 
       return response.toJSONProtocol();
     } catch (e) {
       // Failed to generate response - return generic error.
@@ -1907,6 +1910,12 @@ DebugCommandProcessor.prototype.threadsRequest_ = function(request, response) {
 };
 
 
+DebugCommandProcessor.prototype.suspendRequest_ = function(request, response) {
+  // TODO(peter.rybin): probably we need some body field here.
+  response.running = false;
+};
+
+
 // Check whether the previously processed command caused the VM to become
 // running.
 DebugCommandProcessor.prototype.isRunning = function() {
index d4a0012..d3a6b5b 100644 (file)
@@ -2212,21 +2212,31 @@ void Debugger::NotifyMessageHandler(v8::DebugEvent event,
     return;
   }
 
-  // Get the DebugCommandProcessor.
-  v8::Local<v8::Object> api_exec_state =
-      v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state));
-  v8::Local<v8::String> fun_name =
-      v8::String::New("debugCommandProcessor");
-  v8::Local<v8::Function> fun =
-      v8::Function::Cast(*api_exec_state->Get(fun_name));
   v8::TryCatch try_catch;
-  v8::Local<v8::Object> cmd_processor =
-      v8::Object::Cast(*fun->Call(api_exec_state, 0, NULL));
-  if (try_catch.HasCaught()) {
-    PrintLn(try_catch.Exception());
-    return;
+
+  // DebugCommandProcessor goes here.
+  v8::Local<v8::Object> cmd_processor;
+  {
+    v8::Local<v8::Object> api_exec_state =
+        v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state));
+    v8::Local<v8::String> fun_name =
+        v8::String::New("debugCommandProcessor");
+    v8::Local<v8::Function> fun =
+        v8::Function::Cast(*api_exec_state->Get(fun_name));
+
+    v8::Handle<v8::Boolean> running =
+        auto_continue ? v8::True() : v8::False();
+    static const int kArgc = 1;
+    v8::Handle<Value> argv[kArgc] = { running };
+    cmd_processor = v8::Object::Cast(*fun->Call(api_exec_state, kArgc, argv));
+    if (try_catch.HasCaught()) {
+      PrintLn(try_catch.Exception());
+      return;
+    }
   }
 
+  bool running = auto_continue;
+
   // Process requests from the debugger.
   while (true) {
     // Wait for new command in the queue.
@@ -2267,7 +2277,6 @@ void Debugger::NotifyMessageHandler(v8::DebugEvent event,
 
     // Get the response.
     v8::Local<v8::String> response;
-    bool running = false;
     if (!try_catch.HasCaught()) {
       // Get response string.
       if (!response_val->IsUndefined()) {
@@ -2310,7 +2319,7 @@ void Debugger::NotifyMessageHandler(v8::DebugEvent event,
     // Return from debug event processing if either the VM is put into the
     // runnning state (through a continue command) or auto continue is active
     // and there are no more commands queued.
-    if (running || (auto_continue && !HasCommands())) {
+    if (running && !HasCommands()) {
       return;
     }
   }
index 0c200ae..d15b2d2 100644 (file)
@@ -69,6 +69,11 @@ ParsedResponse.prototype.body = function() {
 }
 
 
+ParsedResponse.prototype.running = function() {
+  return this.response_.running;
+}
+
+
 ParsedResponse.prototype.lookup = function(handle) {
   return this.refs_[handle];
 }
@@ -88,8 +93,9 @@ function listener(event, exec_state, event_data, data) {
       var frame;
       var source;
 
-      // Get the debug command processor.
-      var dcp = exec_state.debugCommandProcessor();
+      var dcp;
+      // New copy of debug command processor paused state.
+      dcp = exec_state.debugCommandProcessor(false);
 
       // Get the backtrace.
       var json;
@@ -114,6 +120,7 @@ function listener(event, exec_state, event_data, data) {
       assertEquals("g", response.lookup(frames[2].func.ref).name);
       assertEquals(3, frames[3].index);
       assertEquals("", response.lookup(frames[3].func.ref).name);
+      assertFalse(response.running(), "expected not running");
 
       // Get backtrace with two frames.
       json = '{"seq":0,"type":"request","command":"backtrace","arguments":{"fromFrame":1,"toFrame":3}}'
@@ -234,6 +241,17 @@ function listener(event, exec_state, event_data, data) {
       source = response.body();
       assertEquals(Debug.findScript(f).source, source.source);
 
+      // New copy of debug command processor in running state.
+      dcp = exec_state.debugCommandProcessor(true);
+      // Get the backtrace.
+      json = '{"seq":0,"type":"request","command":"backtrace"}'
+      resp = dcp.processDebugJSONRequest(json);
+      response = new ParsedResponse(resp);
+      // It might be argueable, but we expect response to have body when
+      // not suspended
+      assertTrue(!!response.body(), "response should be null");
+      assertTrue(response.running(), "expected running");
+
       listenerCalled = true;
     }
   } catch (e) {
index 477c908..936523a 100644 (file)
@@ -59,7 +59,7 @@ function listener(event, exec_state, event_data, data) {
   try {
   if (event == Debug.DebugEvent.Break) {
     // Get the debug command processor.
-    var dcp = exec_state.debugCommandProcessor();
+    var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
 
     // Test some illegal clearbreakpoint requests.
     var request = '{' + base_request + '}'
index 28920c5..59479f2 100644 (file)
@@ -59,7 +59,7 @@ function listener(event, exec_state, event_data, data) {
   try {
   if (event == Debug.DebugEvent.Break) {
     // Get the debug command processor.
-    var dcp = exec_state.debugCommandProcessor();
+    var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
 
     // Test some illegal clearbreakpoint requests.
     var request = '{' + base_request + '}'
index eca9378..aad6c3a 100644 (file)
@@ -60,7 +60,7 @@ function listener(event, exec_state, event_data, data) {
   try {\r
     if (event == Debug.DebugEvent.Break) {\r
       // Get the debug command processor.\r
-      var dcp = exec_state.debugCommandProcessor();\r
+      var dcp = exec_state.debugCommandProcessor("unspecified_running_state");\r
 \r
       // Clear breakpoint group 1.\r
       testArguments(dcp, '{"groupId":1}', true);\r
index 0c11abc..a501aa9 100644 (file)
@@ -44,7 +44,10 @@ function safeEval(code) {
   }
 }
 
-function testArguments(dcp, arguments, success) {
+function testArguments(exec_state, arguments, success) {
+  // Get the debug command processor in paused state.
+  var dcp = exec_state.debugCommandProcessor(false);
+
   // Generate request with the supplied arguments
   var request;
   if (arguments) {
@@ -65,25 +68,23 @@ function testArguments(dcp, arguments, success) {
 function listener(event, exec_state, event_data, data) {
   try {
   if (event == Debug.DebugEvent.Break) {
-    // Get the debug command processor.
-    var dcp = exec_state.debugCommandProcessor();
 
     // Test simple continue request.
-    testArguments(dcp, void 0, true);
+    testArguments(exec_state, void 0, true);
 
     // Test some illegal continue requests.
-    testArguments(dcp, '{"stepaction":"maybe"}', false);
-    testArguments(dcp, '{"stepcount":-1}', false);
+    testArguments(exec_state, '{"stepaction":"maybe"}', false);
+    testArguments(exec_state, '{"stepcount":-1}', false);
 
     // Test some legal continue requests.
-    testArguments(dcp, '{"stepaction":"in"}', true);
-    testArguments(dcp, '{"stepaction":"min"}', true);
-    testArguments(dcp, '{"stepaction":"next"}', true);
-    testArguments(dcp, '{"stepaction":"out"}', true);
-    testArguments(dcp, '{"stepcount":1}', true);
-    testArguments(dcp, '{"stepcount":10}', true);
-    testArguments(dcp, '{"stepcount":"10"}', true);
-    testArguments(dcp, '{"stepaction":"next","stepcount":10}', true);
+    testArguments(exec_state, '{"stepaction":"in"}', true);
+    testArguments(exec_state, '{"stepaction":"min"}', true);
+    testArguments(exec_state, '{"stepaction":"next"}', true);
+    testArguments(exec_state, '{"stepaction":"out"}', true);
+    testArguments(exec_state, '{"stepcount":1}', true);
+    testArguments(exec_state, '{"stepcount":10}', true);
+    testArguments(exec_state, '{"stepcount":"10"}', true);
+    testArguments(exec_state, '{"stepaction":"next","stepcount":10}', true);
 
     // Indicate that all was processed.
     listenerComplete = true;
@@ -108,6 +109,6 @@ function g() {
 Debug.setBreakPoint(g, 0, 0);
 g();
 
+assertFalse(exception, "exception in listener")
 // Make sure that the debug event listener vas invoked.
 assertTrue(listenerComplete, "listener did not run to completion");
-assertFalse(exception, "exception in listener")
index 9f037e5..6ee391b 100644 (file)
@@ -44,7 +44,10 @@ function safeEval(code) {
   }
 }
 
-function testRequest(dcp, arguments, success, result) {
+function testRequest(exec_state, arguments, success, result) {
+  // Get the debug command processor in paused state.
+  var dcp = exec_state.debugCommandProcessor(false);
+
   // Generate request with the supplied arguments.
   var request;
   if (arguments) {
@@ -74,23 +77,20 @@ function listener(event, exec_state, event_data, data) {
       assertEquals(1, exec_state.frame(0).evaluate('f()', true).value());
       assertEquals(2, exec_state.frame(0).evaluate('g()', true).value());
 
-      // Get the debug command processor.
-      var dcp = exec_state.debugCommandProcessor();
-
       // Call functions with break using the JSON protocol. Tests that argument
       // disable_break is default true.
-      testRequest(dcp, '{"expression":"f()"}', true, 1);
-      testRequest(dcp, '{"expression":"f()","frame":0}',  true, 1);
-      testRequest(dcp, '{"expression":"g()"}', true, 2);
-      testRequest(dcp, '{"expression":"g()","frame":0}',  true, 2);
+      testRequest(exec_state, '{"expression":"f()"}', true, 1);
+      testRequest(exec_state, '{"expression":"f()","frame":0}',  true, 1);
+      testRequest(exec_state, '{"expression":"g()"}', true, 2);
+      testRequest(exec_state, '{"expression":"g()","frame":0}',  true, 2);
 
       // Call functions with break using the JSON protocol. Tests passing
       // argument disable_break is default true.
-      testRequest(dcp, '{"expression":"f()","disable_break":true}', true, 1);
-      testRequest(dcp, '{"expression":"f()","frame":0,"disable_break":true}',
+      testRequest(exec_state, '{"expression":"f()","disable_break":true}', true, 1);
+      testRequest(exec_state, '{"expression":"f()","frame":0,"disable_break":true}',
                   true, 1);
-      testRequest(dcp, '{"expression":"g()","disable_break":true}', true, 2);
-      testRequest(dcp, '{"expression":"g()","frame":0,"disable_break":true}',
+      testRequest(exec_state, '{"expression":"g()","disable_break":true}', true, 2);
+      testRequest(exec_state, '{"expression":"g()","frame":0,"disable_break":true}',
                   true, 2);
 
       // Indicate that all was processed.
@@ -146,9 +146,9 @@ Debug.setBreakPoint(f, 2, 0);
 // Cause a debug break event.
 debugger;
 
+assertFalse(exception, "exception in listener")
 // Make sure that the debug event listener vas invoked.
 assertTrue(listenerComplete);
-assertFalse(exception, "exception in listener")
 
 // Remove the debug event listener.
 Debug.setListener(null);
@@ -161,7 +161,7 @@ Debug.setBreakPoint(f, 2, 0);
 
 debugger;
 
+assertFalse(exception, "exception in listener")
 // Make sure that the debug event listener vas invoked.
 assertTrue(listenerComplete);
-assertFalse(exception, "exception in listener")
 assertEquals(2, break_count);
index 5c5734f..c477907 100644 (file)
@@ -59,14 +59,15 @@ function testRequest(dcp, arguments, success, result) {
   } else {
     assertFalse(response.success, request + ' -> ' + response.message);
   }
-  assertFalse(response.running, request + ' -> expected not running');
+  assertEquals(response.running, "unspecified_running_state",
+               request + ' -> expected not running');
 }
 
 function listener(event, exec_state, event_data, data) {
   try {
     if (event == Debug.DebugEvent.Break) {
       // Get the debug command processor.
-      var dcp = exec_state.debugCommandProcessor();
+      var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
 
       // Test some illegal evaluate requests.
       testRequest(dcp, void 0, false);
@@ -112,6 +113,6 @@ a = 1;
 Debug.setBreakPoint(f, 2, 0);
 g();
 
+assertFalse(exception, "exception in listener")
 // Make sure that the debug event listener vas invoked.
 assertTrue(listenerComplete, "listener did not run to completion");
-assertFalse(exception, "exception in listener")
index c7ab76a..98875ce 100644 (file)
@@ -43,7 +43,10 @@ function safeEval(code) {
 
 
 // Send an evaluation request and return the handle of the result.
-function evaluateRequest(dcp, arguments) {
+function evaluateRequest(exec_state, arguments) {
+  // Get the debug command processor.
+  var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
+
   // The base part of all evaluate requests.
   var base_request = '"seq":0,"type":"request","command":"evaluate"'
 
@@ -63,7 +66,10 @@ function evaluateRequest(dcp, arguments) {
 
 
 // Send a lookup request and return the evaluated JSON response.
-function lookupRequest(dcp, arguments, success) {
+function lookupRequest(exec_state, arguments, success) {
+  // Get the debug command processor.
+  var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
+
   // The base part of all lookup requests.
   var base_request = '"seq":0,"type":"request","command":"lookup"'
   
@@ -81,7 +87,7 @@ function lookupRequest(dcp, arguments, success) {
   } else {
     assertFalse(response.success, request + ' -> ' + response.message);
   }
-  assertFalse(response.running, request + ' -> expected not running');
+  assertEquals(response.running, dcp.isRunning(), request + ' -> expected not running');
 
   return response;
 }
@@ -90,26 +96,23 @@ function lookupRequest(dcp, arguments, success) {
 function listener(event, exec_state, event_data, data) {
   try {
   if (event == Debug.DebugEvent.Break) {
-    // Get the debug command processor.
-    var dcp = exec_state.debugCommandProcessor();
-
     // Test some illegal lookup requests.
-    lookupRequest(dcp, void 0, false);
-    lookupRequest(dcp, '{"handles":["a"]}', false);
-    lookupRequest(dcp, '{"handles":[-1]}', false);
+    lookupRequest(exec_state, void 0, false);
+    lookupRequest(exec_state, '{"handles":["a"]}', false);
+    lookupRequest(exec_state, '{"handles":[-1]}', false);
 
     // Evaluate and get some handles.
-    var handle_o = evaluateRequest(dcp, '{"expression":"o"}');
-    var handle_p = evaluateRequest(dcp, '{"expression":"p"}');
-    var handle_b = evaluateRequest(dcp, '{"expression":"a"}');
-    var handle_a = evaluateRequest(dcp, '{"expression":"b","frame":1}');
+    var handle_o = evaluateRequest(exec_state, '{"expression":"o"}');
+    var handle_p = evaluateRequest(exec_state, '{"expression":"p"}');
+    var handle_b = evaluateRequest(exec_state, '{"expression":"a"}');
+    var handle_a = evaluateRequest(exec_state, '{"expression":"b","frame":1}');
     assertEquals(handle_o, handle_a);
     assertEquals(handle_a, handle_b);
     assertFalse(handle_o == handle_p, "o and p have he same handle");
 
     var response;
     var count;
-    response = lookupRequest(dcp, '{"handles":[' + handle_o + ']}', true);
+    response = lookupRequest(exec_state, '{"handles":[' + handle_o + ']}', true);
     var obj = response.body[handle_o];
     assertTrue(!!obj, 'Object not found: ' + handle_o);
     assertEquals(handle_o, obj.handle);
@@ -127,20 +130,20 @@ function listener(event, exec_state, event_data, data) {
       }
     }
     assertEquals(2, count, 'Either "o" or "p" not found');
-    response = lookupRequest(dcp, '{"handles":[' + handle_p + ']}', true);
+    response = lookupRequest(exec_state, '{"handles":[' + handle_p + ']}', true);
     obj = response.body[handle_p];
     assertTrue(!!obj, 'Object not found: ' + handle_p);
     assertEquals(handle_p, obj.handle);
 
     // Check handles for functions on the stack.
-    var handle_f = evaluateRequest(dcp, '{"expression":"f"}');
-    var handle_g = evaluateRequest(dcp, '{"expression":"g"}');
-    var handle_caller = evaluateRequest(dcp, '{"expression":"f.caller"}');
+    var handle_f = evaluateRequest(exec_state, '{"expression":"f"}');
+    var handle_g = evaluateRequest(exec_state, '{"expression":"g"}');
+    var handle_caller = evaluateRequest(exec_state, '{"expression":"f.caller"}');
 
     assertFalse(handle_f == handle_g, "f and g have he same handle");
     assertEquals(handle_g, handle_caller, "caller for f should be g");
 
-    response = lookupRequest(dcp, '{"handles":[' + handle_f + ']}', true);
+    response = lookupRequest(exec_state, '{"handles":[' + handle_f + ']}', true);
     obj = response.body[handle_f];
     assertEquals(handle_f, obj.handle);
 
@@ -151,14 +154,14 @@ function listener(event, exec_state, event_data, data) {
       switch (obj.properties[i].name) {
         case 'name':
           var response_name;
-          response_name = lookupRequest(dcp, arguments, true);
+          response_name = lookupRequest(exec_state, arguments, true);
           assertEquals('string', response_name.body[ref].type);
           assertEquals("f", response_name.body[ref].value);
           count++;
           break;
         case 'length':
           var response_length;
-          response_length = lookupRequest(dcp, arguments, true);
+          response_length = lookupRequest(exec_state, arguments, true);
           assertEquals('number', response_length.body[ref].type);
           assertEquals(1, response_length.body[ref].value);
           count++;
@@ -179,7 +182,7 @@ function listener(event, exec_state, event_data, data) {
     }
 
     var arguments = '{"handles":[' + refs.join(',') + ']}';
-    response = lookupRequest(dcp, arguments, true);
+    response = lookupRequest(exec_state, arguments, true);
     count = 0;
     for (i in obj.properties) {
       var ref = obj.properties[i].ref;
@@ -244,6 +247,6 @@ p.o = o;
 p.p = p;
 g(o);
 
+assertFalse(exception, "exception in listener")
 // Make sure that the debug event listener vas invoked.
 assertTrue(listenerComplete, "listener did not run to completion: " + exception);
-assertFalse(exception, "exception in listener")
index d15146f..5b85306 100644 (file)
@@ -41,7 +41,7 @@ function g() {
 Debug = debug.Debug
 
 listenerCallCount = 0;
-listenerExceptionCount = 0;
+listenerExceptions = [];
 
 
 function listener(event, exec_state, event_data, data) {
@@ -54,8 +54,8 @@ function listener(event, exec_state, event_data, data) {
     assertEquals(0, debug.next_handle_, "Mirror cache not cleared");
     assertEquals(0, debug.mirror_cache_.length, "Mirror cache not cleared");
 
-    // Get the debug command processor.
-    var dcp = exec_state.debugCommandProcessor();
+    // Get the debug command processor in paused state.
+    var dcp = exec_state.debugCommandProcessor(false);
 
     // Make a backtrace request to create some mirrors.
     var json;
@@ -68,7 +68,7 @@ function listener(event, exec_state, event_data, data) {
   }
   } catch (e) {
     print(e);
-    listenerExceptionCount++;
+    listenerExceptions.push(e);
   };
 };
 
@@ -79,7 +79,7 @@ Debug.setListener(listener);
 debugger;
 debugger;
 
+assertEquals([], listenerExceptions, "Exception in listener");
 // Make sure that the debug event listener vas invoked.
 assertEquals(2, listenerCallCount, "Listener not called");
-assertEquals(0, listenerExceptionCount, "Exception in listener");
 
index 1fde1ac..452761c 100644 (file)
@@ -66,14 +66,14 @@ function testRequest(dcp, arguments, success, count) {
   } else {\r
     assertFalse(response.success, request + ' -> ' + response.message);\r
   }\r
-  assertFalse(response.running, request + ' -> expected not running');\r
+  assertEquals(response.running, dcp.isRunning(), request + ' -> expected not running');\r
 }\r
 \r
 function listener(event, exec_state, event_data, data) {\r
   try {\r
   if (event == Debug.DebugEvent.Break) {\r
     // Get the debug command processor.\r
-    var dcp = exec_state.debugCommandProcessor();\r
+    var dcp = exec_state.debugCommandProcessor("unspecified_running_state");\r
 \r
     // Test some illegal references requests.\r
     testRequest(dcp, void 0, false);\r
index e87cbb7..af29df9 100644 (file)
@@ -92,7 +92,7 @@ function CheckScopeChain(scopes, exec_state) {
   }
   
   // Get the debug command processor.
-  var dcp = exec_state.debugCommandProcessor();
+  var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
   
   // Send a scopes request and check the result.
   var json;
@@ -155,7 +155,7 @@ function CheckScopeContent(content, number, exec_state) {
   assertEquals(count, scope_size);
 
   // Get the debug command processor.
-  var dcp = exec_state.debugCommandProcessor();
+  var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
   
   // Send a scope request for information on a single scope and check the
   // result.
index 80b3bce..41bff0e 100644 (file)
@@ -60,7 +60,7 @@ function listener(event, exec_state, event_data, data) {
   try {
   if (event == Debug.DebugEvent.Break) {
     // Get the debug command processor.
-    var dcp = exec_state.debugCommandProcessor();
+    var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
 
     // Test illegal scripts requests.
     testArguments(dcp, '{"types":"xx"}', false);
index f8d9b15..08492b4 100644 (file)
@@ -69,7 +69,7 @@ function listener(event, exec_state, event_data, data) {
   try {
   if (event == Debug.DebugEvent.Break) {
     // Get the debug command processor.
-    var dcp = exec_state.debugCommandProcessor();
+    var dcp = exec_state.debugCommandProcessor("unspecified_running_state");
 
     // Test some illegal setbreakpoint requests.
     var request = '{' + base_request + '}'
diff --git a/test/mjsunit/debug-suspend.js b/test/mjsunit/debug-suspend.js
new file mode 100644 (file)
index 0000000..73a2e8c
--- /dev/null
@@ -0,0 +1,96 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+// Simple function which stores the last debug event.
+listenerComplete = false;
+exception = false;
+
+var base_backtrace_request = '"seq":0,"type":"request","command":"backtrace"'
+var base_suspend_request = '"seq":0,"type":"request","command":"suspend"'
+
+function safeEval(code) {
+  try {
+    return eval('(' + code + ')');
+  } catch (e) {
+    assertEquals(void 0, e);
+    return undefined;
+  }
+}
+
+function testArguments(exec_state) {
+  // Get the debug command processor in running state.
+  var dcp = exec_state.debugCommandProcessor(true);
+
+  assertTrue(dcp.isRunning());
+
+  var backtrace_request = '{' + base_backtrace_request + '}'
+  var backtrace_response = safeEval(dcp.processDebugJSONRequest(backtrace_request));
+
+  assertTrue(backtrace_response.success);
+
+  assertTrue(backtrace_response.running, backtrace_request + ' -> expected running');
+
+  assertTrue(dcp.isRunning());
+
+  var suspend_request = '{' + base_suspend_request + '}'
+  var suspend_response = safeEval(dcp.processDebugJSONRequest(suspend_request));
+
+  assertTrue(suspend_response.success);
+
+  assertFalse(suspend_response.running, suspend_request + ' -> expected not running');
+
+  assertFalse(dcp.isRunning());
+}
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+
+      // Test simple suspend request.
+      testArguments(exec_state);
+
+      // Indicate that all was processed.
+      listenerComplete = true;
+    }
+  } catch (e) {
+    exception = e
+  };
+};
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+// Stop debugger and check that suspend command changes running flag.
+debugger;
+
+assertFalse(exception, "exception in listener")
+// Make sure that the debug event listener vas invoked.
+assertTrue(listenerComplete, "listener did not run to completion");
index a771ac0..009ede1 100644 (file)
@@ -69,7 +69,7 @@ function listener(event, exec_state, event_data, data) {
     // 0: [anonymous]
     
     // Get the debug command processor.
-    var dcp = exec_state.debugCommandProcessor();
+    var dcp = exec_state.debugCommandProcessor(false);
 
     // Get the backtrace.
     var json;
@@ -105,6 +105,6 @@ try {
   // Ignore the exception "Cannot call method 'x' of undefined"
 }
 
+assertFalse(exception, "exception in listener", exception)
 // Make sure that the debug event listener vas invoked.
 assertTrue(listenerCalled, "listener not called");
-assertFalse(exception, "exception in listener", exception)