debug-handle.js 8.37 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
// Copyright 2009 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

listenerComplete = false;
exception = false;

function safeEval(code) {
  try {
    return eval('(' + code + ')');
  } catch (e) {
    assertEquals(void 0, e);
    return undefined;
  }
}


// Send an evaluation request and return the handle of the result.
46 47 48 49
function evaluateRequest(exec_state, arguments) {
  // Get the debug command processor.
  var dcp = exec_state.debugCommandProcessor("unspecified_running_state");

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
  // The base part of all evaluate requests.
  var base_request = '"seq":0,"type":"request","command":"evaluate"'

  // Generate request with the supplied arguments.
  var request;
  if (arguments) {
    request = '{' + base_request + ',"arguments":' + arguments + '}';
  } else {
    request = '{' + base_request + '}'
  }

  var response = safeEval(dcp.processDebugJSONRequest(request));
  assertTrue(response.success, request + ' -> ' + response.message);

  return response.body.handle;
}


// Send a lookup request and return the evaluated JSON response.
69 70 71 72
function lookupRequest(exec_state, arguments, success) {
  // Get the debug command processor.
  var dcp = exec_state.debugCommandProcessor("unspecified_running_state");

73 74
  // The base part of all lookup requests.
  var base_request = '"seq":0,"type":"request","command":"lookup"'
75

76 77 78 79 80 81 82 83 84 85 86 87 88 89
  // Generate request with the supplied arguments.
  var request;
  if (arguments) {
    request = '{' + base_request + ',"arguments":' + arguments + '}';
  } else {
    request = '{' + base_request + '}'
  }

  var response = safeEval(dcp.processDebugJSONRequest(request));
  if (success) {
    assertTrue(response.success, request + ' -> ' + response.message);
  } else {
    assertFalse(response.success, request + ' -> ' + response.message);
  }
90
  assertEquals(response.running, dcp.isRunning(), request + ' -> expected not running');
91 92 93 94 95 96 97 98 99

  return response;
}


function listener(event, exec_state, event_data, data) {
  try {
  if (event == Debug.DebugEvent.Break) {
    // Test some illegal lookup requests.
100 101 102
    lookupRequest(exec_state, void 0, false);
    lookupRequest(exec_state, '{"handles":["a"]}', false);
    lookupRequest(exec_state, '{"handles":[-1]}', false);
103 104

    // Evaluate and get some handles.
105 106 107 108
    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}');
109 110 111 112 113 114
    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;
115
    response = lookupRequest(exec_state, '{"handles":[' + handle_o + ']}', true);
116 117 118
    var obj = response.body[handle_o];
    assertTrue(!!obj, 'Object not found: ' + handle_o);
    assertEquals(handle_o, obj.handle);
119
    count = 0;
120 121
    for (i in obj.properties) {
      switch (obj.properties[i].name) {
122
        case 'o':
123
          obj.properties[i].ref = handle_o;
124 125 126
          count++;
          break;
        case 'p':
127
          obj.properties[i].ref = handle_p;
128 129 130 131 132
          count++;
          break;
      }
    }
    assertEquals(2, count, 'Either "o" or "p" not found');
133
    response = lookupRequest(exec_state, '{"handles":[' + handle_p + ']}', true);
134 135 136
    obj = response.body[handle_p];
    assertTrue(!!obj, 'Object not found: ' + handle_p);
    assertEquals(handle_p, obj.handle);
137 138

    // Check handles for functions on the stack.
139 140 141
    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"}');
142 143 144 145

    assertFalse(handle_f == handle_g, "f and g have he same handle");
    assertEquals(handle_g, handle_caller, "caller for f should be g");

146
    response = lookupRequest(exec_state, '{"handles":[' + handle_f + ']}', true);
147 148 149
    obj = response.body[handle_f];
    assertEquals(handle_f, obj.handle);

150
    count = 0;
151 152 153 154
    for (i in obj.properties) {
      var ref = obj.properties[i].ref;
      var arguments = '{"handles":[' + ref + ']}';
      switch (obj.properties[i].name) {
155 156
        case 'name':
          var response_name;
157
          response_name = lookupRequest(exec_state, arguments, true);
158 159
          assertEquals('string', response_name.body[ref].type);
          assertEquals("f", response_name.body[ref].value);
160 161 162 163
          count++;
          break;
        case 'length':
          var response_length;
164
          response_length = lookupRequest(exec_state, arguments, true);
165 166
          assertEquals('number', response_length.body[ref].type);
          assertEquals(1, response_length.body[ref].value);
167 168 169
          count++;
          break;
        case 'caller':
170
          assertEquals(handle_g, obj.properties[i].ref);
171 172 173 174 175 176 177
          count++;
          break;
      }
    }
    assertEquals(3, count, 'Either "name", "length" or "caller" not found');


178 179 180 181 182 183 184
    // Resolve all at once.
    var refs = [];
    for (i in obj.properties) {
      refs.push(obj.properties[i].ref);
    }

    var arguments = '{"handles":[' + refs.join(',') + ']}';
185
    response = lookupRequest(exec_state, arguments, true);
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
    count = 0;
    for (i in obj.properties) {
      var ref = obj.properties[i].ref;
      var val = response.body[ref];
      assertTrue(!!val, 'Failed to lookup "' + obj.properties[i].name + '"');
      switch (obj.properties[i].name) {
        case 'name':
          assertEquals('string', val.type);
          assertEquals("f", val.value);
          count++;
          break;
        case 'length':
          assertEquals('number', val.type);
          assertEquals(1, val.value);
          count++;
          break;
        case 'caller':
          assertEquals('function', val.type);
          assertEquals(handle_g, ref);
          count++;
          break;
      }
    }
    assertEquals(3, count, 'Either "name", "length" or "caller" not found');

    count = 0;
    for (var handle in response.body) {
      assertTrue(refs.indexOf(parseInt(handle)) != -1,
                 'Handle not in the request: ' + handle);
      count++;
    }
217
    assertEquals(count, obj.properties.length,
218 219 220
                 'Unexpected number of resolved objects');


221 222 223 224 225 226 227 228 229
    // Indicate that all was processed.
    listenerComplete = true;
  }
  } catch (e) {
    exception = e
  };
};

// Add the debug event listener.
230
Debug.setListener(listener);
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249

function f(a) {
  debugger;
};

function g(b) {
  f(b);
};

// Set a break point at return in f and invoke g to hit the breakpoint.
Debug.setBreakPoint(f, 2, 0);
o = {};
p = {}
o.o = o;
o.p = p;
p.o = o;
p.p = p;
g(o);

250
assertFalse(exception, "exception in listener")
251
// Make sure that the debug event listener vas invoked.
252
assertTrue(listenerComplete, "listener did not run to completion: " + exception);