Home | History | Annotate | Download | only in mjsunit
      1 // Copyright 2008 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     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.
     27 
     28 // Flags: --expose-debug-as debug
     29 // The functions used for testing backtraces. They are at the top to make the
     30 // testing of source line/column easier.
     31 function f(x, y) {
     32   a=1;
     33 };
     34 
     35 var m = function() {
     36   new f(1);
     37 };
     38 
     39 function g() {
     40   m();
     41 };
     42 
     43 
     44 // Get the Debug object exposed from the debug context global object.
     45 Debug = debug.Debug
     46 
     47 listenerCalled = false;
     48 exception = false;
     49 
     50 
     51 function ParsedResponse(json) {
     52   this.response_ = eval('(' + json + ')');
     53   this.refs_ = [];
     54   if (this.response_.refs) {
     55     for (var i = 0; i < this.response_.refs.length; i++) {
     56       this.refs_[this.response_.refs[i].handle] = this.response_.refs[i];
     57     }
     58   }
     59 }
     60 
     61 
     62 ParsedResponse.prototype.response = function() {
     63   return this.response_;
     64 }
     65 
     66 
     67 ParsedResponse.prototype.body = function() {
     68   return this.response_.body;
     69 }
     70 
     71 
     72 ParsedResponse.prototype.running = function() {
     73   return this.response_.running;
     74 }
     75 
     76 
     77 ParsedResponse.prototype.lookup = function(handle) {
     78   return this.refs_[handle];
     79 }
     80 
     81 
     82 function listener(event, exec_state, event_data, data) {
     83   try {
     84     if (event == Debug.DebugEvent.Break) {
     85       // The expected backtrace is
     86       // 0: f
     87       // 1: m
     88       // 2: g
     89       // 3: [anonymous]
     90 
     91       var response;
     92       var backtrace;
     93       var frame;
     94       var source;
     95 
     96       var dcp;
     97       // New copy of debug command processor paused state.
     98       dcp = exec_state.debugCommandProcessor(false);
     99 
    100       // Get the backtrace.
    101       var json;
    102       json = '{"seq":0,"type":"request","command":"backtrace"}'
    103       var resp = dcp.processDebugJSONRequest(json);
    104       response = new ParsedResponse(resp);
    105       backtrace = response.body();
    106       assertEquals(0, backtrace.fromFrame);
    107       assertEquals(4, backtrace.toFrame);
    108       assertEquals(4, backtrace.totalFrames);
    109       var frames = backtrace.frames;
    110       assertEquals(4, frames.length);
    111       for (var i = 0; i < frames.length; i++) {
    112         assertEquals('frame', frames[i].type);
    113       }
    114       assertEquals(0, frames[0].index);
    115       assertEquals("f", response.lookup(frames[0].func.ref).name);
    116       assertEquals(1, frames[1].index);
    117       assertEquals("", response.lookup(frames[1].func.ref).name);
    118       assertEquals("m", response.lookup(frames[1].func.ref).inferredName);
    119       assertEquals(2, frames[2].index);
    120       assertEquals("g", response.lookup(frames[2].func.ref).name);
    121       assertEquals(3, frames[3].index);
    122       assertEquals("", response.lookup(frames[3].func.ref).name);
    123       assertFalse(response.running(), "expected not running");
    124 
    125       // Get backtrace with two frames.
    126       json = '{"seq":0,"type":"request","command":"backtrace","arguments":{"fromFrame":1,"toFrame":3}}'
    127       response = new ParsedResponse(dcp.processDebugJSONRequest(json));
    128       backtrace = response.body();
    129       assertEquals(1, backtrace.fromFrame);
    130       assertEquals(3, backtrace.toFrame);
    131       assertEquals(4, backtrace.totalFrames);
    132       var frames = backtrace.frames;
    133       assertEquals(2, frames.length);
    134       for (var i = 0; i < frames.length; i++) {
    135         assertEquals('frame', frames[i].type);
    136       }
    137       assertEquals(1, frames[0].index);
    138       assertEquals("", response.lookup(frames[0].func.ref).name);
    139       assertEquals("m", response.lookup(frames[0].func.ref).inferredName);
    140       assertEquals(2, frames[1].index);
    141       assertEquals("g", response.lookup(frames[1].func.ref).name);
    142 
    143       // Get backtrace with bottom two frames.
    144       json = '{"seq":0,"type":"request","command":"backtrace","arguments":{"fromFrame":0,"toFrame":2, "bottom":true}}'
    145       response = new ParsedResponse(dcp.processDebugJSONRequest(json));
    146       backtrace = response.body();
    147       assertEquals(2, backtrace.fromFrame);
    148       assertEquals(4, backtrace.toFrame);
    149       assertEquals(4, backtrace.totalFrames);
    150       var frames = backtrace.frames;
    151       assertEquals(2, frames.length);
    152       for (var i = 0; i < frames.length; i++) {
    153         assertEquals('frame', frames[i].type);
    154       }
    155       assertEquals(2, frames[0].index);
    156       assertEquals("g", response.lookup(frames[0].func.ref).name);
    157       assertEquals(3, frames[1].index);
    158       assertEquals("", response.lookup(frames[1].func.ref).name);
    159 
    160       // Get the individual frames.
    161       json = '{"seq":0,"type":"request","command":"frame"}'
    162       response = new ParsedResponse(dcp.processDebugJSONRequest(json));
    163       frame = response.body();
    164       assertEquals(0, frame.index);
    165       assertEquals("f", response.lookup(frame.func.ref).name);
    166       assertTrue(frame.constructCall);
    167       assertEquals(31, frame.line);
    168       assertEquals(3, frame.column);
    169       assertEquals(2, frame.arguments.length);
    170       assertEquals('x', frame.arguments[0].name);
    171       assertEquals('number', response.lookup(frame.arguments[0].value.ref).type);
    172       assertEquals(1, response.lookup(frame.arguments[0].value.ref).value);
    173       assertEquals('y', frame.arguments[1].name);
    174       assertEquals('undefined', response.lookup(frame.arguments[1].value.ref).type);
    175 
    176       json = '{"seq":0,"type":"request","command":"frame","arguments":{"number":0}}'
    177       response = new ParsedResponse(dcp.processDebugJSONRequest(json));
    178       frame = response.body();
    179       assertEquals(0, frame.index);
    180       assertEquals("f", response.lookup(frame.func.ref).name);
    181       assertEquals(31, frame.line);
    182       assertEquals(3, frame.column);
    183       assertEquals(2, frame.arguments.length);
    184       assertEquals('x', frame.arguments[0].name);
    185       assertEquals('number', response.lookup(frame.arguments[0].value.ref).type);
    186       assertEquals(1, response.lookup(frame.arguments[0].value.ref).value);
    187       assertEquals('y', frame.arguments[1].name);
    188       assertEquals('undefined', response.lookup(frame.arguments[1].value.ref).type);
    189 
    190       json = '{"seq":0,"type":"request","command":"frame","arguments":{"number":1}}'
    191       response = new ParsedResponse(dcp.processDebugJSONRequest(json));
    192       frame = response.body();
    193       assertEquals(1, frame.index);
    194       assertEquals("", response.lookup(frame.func.ref).name);
    195       assertEquals("m", response.lookup(frame.func.ref).inferredName);
    196       assertFalse(frame.constructCall);
    197       assertEquals(35, frame.line);
    198       assertEquals(2, frame.column);
    199       assertEquals(0, frame.arguments.length);
    200 
    201       json = '{"seq":0,"type":"request","command":"frame","arguments":{"number":3}}'
    202       response = new ParsedResponse(dcp.processDebugJSONRequest(json));
    203       frame = response.body();
    204       assertEquals(3, frame.index);
    205       assertEquals("", response.lookup(frame.func.ref).name);
    206 
    207       // Source slices for the individual frames (they all refer to this script).
    208       json = '{"seq":0,"type":"request","command":"source",' +
    209               '"arguments":{"frame":0,"fromLine":30,"toLine":32}}'
    210       response = new ParsedResponse(dcp.processDebugJSONRequest(json));
    211       source = response.body();
    212       assertEquals("function f(x, y) {", source.source.substring(0, 18));
    213       assertEquals(30, source.fromLine);
    214       assertEquals(32, source.toLine);
    215 
    216       json = '{"seq":0,"type":"request","command":"source",' +
    217               '"arguments":{"frame":1,"fromLine":31,"toLine":32}}'
    218       response = new ParsedResponse(dcp.processDebugJSONRequest(json));
    219       source = response.body();
    220       assertEquals("  a=1;", source.source.substring(0, 6));
    221       assertEquals(31, source.fromLine);
    222       assertEquals(32, source.toLine);
    223 
    224       json = '{"seq":0,"type":"request","command":"source",' +
    225               '"arguments":{"frame":2,"fromLine":35,"toLine":36}}'
    226       response = new ParsedResponse(dcp.processDebugJSONRequest(json));
    227       source = response.body();
    228       assertEquals("  new f(1);", source.source.substring(0, 11));
    229       assertEquals(35, source.fromLine);
    230       assertEquals(36, source.toLine);
    231 
    232       // Test line interval way beyond this script will result in an error.
    233       json = '{"seq":0,"type":"request","command":"source",' +
    234               '"arguments":{"frame":0,"fromLine":10000,"toLine":20000}}'
    235       response = new ParsedResponse(dcp.processDebugJSONRequest(json));
    236       assertFalse(response.response().success);
    237 
    238       // Test without arguments.
    239       json = '{"seq":0,"type":"request","command":"source"}'
    240       response = new ParsedResponse(dcp.processDebugJSONRequest(json));
    241       source = response.body();
    242       assertEquals(Debug.findScript(f).source, source.source);
    243 
    244       // New copy of debug command processor in running state.
    245       dcp = exec_state.debugCommandProcessor(true);
    246       // Get the backtrace.
    247       json = '{"seq":0,"type":"request","command":"backtrace"}'
    248       resp = dcp.processDebugJSONRequest(json);
    249       response = new ParsedResponse(resp);
    250       // It might be argueable, but we expect response to have body when
    251       // not suspended
    252       assertTrue(!!response.body(), "response should be null");
    253       assertTrue(response.running(), "expected running");
    254 
    255       listenerCalled = true;
    256     }
    257   } catch (e) {
    258     exception = e
    259   };
    260 };
    261 
    262 // Add the debug event listener.
    263 Debug.setListener(listener);
    264 
    265 // Set a break point and call to invoke the debug event listener.
    266 Debug.setBreakPoint(f, 0, 0);
    267 g();
    268 
    269 // Make sure that the debug event listener vas invoked.
    270 assertFalse(exception, "exception in listener");
    271 assertTrue(listenerCalled);
    272 
    273