debug-handle.js revision a7e24c173cf37484693b9abb38e494fa7bd7baeb
1// Copyright 2009 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// Get the Debug object exposed from the debug context global object. 30Debug = debug.Debug 31 32listenerComplete = false; 33exception = false; 34 35function safeEval(code) { 36 try { 37 return eval('(' + code + ')'); 38 } catch (e) { 39 assertEquals(void 0, e); 40 return undefined; 41 } 42} 43 44 45// Send an evaluation request and return the handle of the result. 46function evaluateRequest(dcp, arguments) { 47 // The base part of all evaluate requests. 48 var base_request = '"seq":0,"type":"request","command":"evaluate"' 49 50 // Generate request with the supplied arguments. 51 var request; 52 if (arguments) { 53 request = '{' + base_request + ',"arguments":' + arguments + '}'; 54 } else { 55 request = '{' + base_request + '}' 56 } 57 58 var response = safeEval(dcp.processDebugJSONRequest(request)); 59 assertTrue(response.success, request + ' -> ' + response.message); 60 61 return response.body.handle; 62} 63 64 65// Send a lookup request and return the evaluated JSON response. 66function lookupRequest(dcp, arguments, success) { 67 // The base part of all lookup requests. 68 var base_request = '"seq":0,"type":"request","command":"lookup"' 69 70 // Generate request with the supplied arguments. 71 var request; 72 if (arguments) { 73 request = '{' + base_request + ',"arguments":' + arguments + '}'; 74 } else { 75 request = '{' + base_request + '}' 76 } 77 78 var response = safeEval(dcp.processDebugJSONRequest(request)); 79 if (success) { 80 assertTrue(response.success, request + ' -> ' + response.message); 81 } else { 82 assertFalse(response.success, request + ' -> ' + response.message); 83 } 84 assertFalse(response.running, request + ' -> expected not running'); 85 86 return response; 87} 88 89 90function listener(event, exec_state, event_data, data) { 91 try { 92 if (event == Debug.DebugEvent.Break) { 93 // Get the debug command processor. 94 var dcp = exec_state.debugCommandProcessor(); 95 96 // Test some illegal lookup requests. 97 lookupRequest(dcp, void 0, false); 98 lookupRequest(dcp, '{"handles":["a"]}', false); 99 lookupRequest(dcp, '{"handles":[-1]}', false); 100 101 // Evaluate and get some handles. 102 var handle_o = evaluateRequest(dcp, '{"expression":"o"}'); 103 var handle_p = evaluateRequest(dcp, '{"expression":"p"}'); 104 var handle_b = evaluateRequest(dcp, '{"expression":"a"}'); 105 var handle_a = evaluateRequest(dcp, '{"expression":"b","frame":1}'); 106 assertEquals(handle_o, handle_a); 107 assertEquals(handle_a, handle_b); 108 assertFalse(handle_o == handle_p, "o and p have he same handle"); 109 110 var response; 111 var count; 112 response = lookupRequest(dcp, '{"handles":[' + handle_o + ']}', true); 113 var obj = response.body[handle_o]; 114 assertTrue(!!obj, 'Object not found: ' + handle_o); 115 assertEquals(handle_o, obj.handle); 116 count = 0; 117 for (i in obj.properties) { 118 switch (obj.properties[i].name) { 119 case 'o': 120 obj.properties[i].ref = handle_o; 121 count++; 122 break; 123 case 'p': 124 obj.properties[i].ref = handle_p; 125 count++; 126 break; 127 } 128 } 129 assertEquals(2, count, 'Either "o" or "p" not found'); 130 response = lookupRequest(dcp, '{"handles":[' + handle_p + ']}', true); 131 obj = response.body[handle_p]; 132 assertTrue(!!obj, 'Object not found: ' + handle_p); 133 assertEquals(handle_p, obj.handle); 134 135 // Check handles for functions on the stack. 136 var handle_f = evaluateRequest(dcp, '{"expression":"f"}'); 137 var handle_g = evaluateRequest(dcp, '{"expression":"g"}'); 138 var handle_caller = evaluateRequest(dcp, '{"expression":"f.caller"}'); 139 140 assertFalse(handle_f == handle_g, "f and g have he same handle"); 141 assertEquals(handle_g, handle_caller, "caller for f should be g"); 142 143 response = lookupRequest(dcp, '{"handles":[' + handle_f + ']}', true); 144 obj = response.body[handle_f]; 145 assertEquals(handle_f, obj.handle); 146 147 count = 0; 148 for (i in obj.properties) { 149 var ref = obj.properties[i].ref; 150 var arguments = '{"handles":[' + ref + ']}'; 151 switch (obj.properties[i].name) { 152 case 'name': 153 var response_name; 154 response_name = lookupRequest(dcp, arguments, true); 155 assertEquals('string', response_name.body[ref].type); 156 assertEquals("f", response_name.body[ref].value); 157 count++; 158 break; 159 case 'length': 160 var response_length; 161 response_length = lookupRequest(dcp, arguments, true); 162 assertEquals('number', response_length.body[ref].type); 163 assertEquals(1, response_length.body[ref].value); 164 count++; 165 break; 166 case 'caller': 167 assertEquals(handle_g, obj.properties[i].ref); 168 count++; 169 break; 170 } 171 } 172 assertEquals(3, count, 'Either "name", "length" or "caller" not found'); 173 174 175 // Resolve all at once. 176 var refs = []; 177 for (i in obj.properties) { 178 refs.push(obj.properties[i].ref); 179 } 180 181 var arguments = '{"handles":[' + refs.join(',') + ']}'; 182 response = lookupRequest(dcp, arguments, true); 183 count = 0; 184 for (i in obj.properties) { 185 var ref = obj.properties[i].ref; 186 var val = response.body[ref]; 187 assertTrue(!!val, 'Failed to lookup "' + obj.properties[i].name + '"'); 188 switch (obj.properties[i].name) { 189 case 'name': 190 assertEquals('string', val.type); 191 assertEquals("f", val.value); 192 count++; 193 break; 194 case 'length': 195 assertEquals('number', val.type); 196 assertEquals(1, val.value); 197 count++; 198 break; 199 case 'caller': 200 assertEquals('function', val.type); 201 assertEquals(handle_g, ref); 202 count++; 203 break; 204 } 205 } 206 assertEquals(3, count, 'Either "name", "length" or "caller" not found'); 207 208 count = 0; 209 for (var handle in response.body) { 210 assertTrue(refs.indexOf(parseInt(handle)) != -1, 211 'Handle not in the request: ' + handle); 212 count++; 213 } 214 assertEquals(count, obj.properties.length, 215 'Unexpected number of resolved objects'); 216 217 218 // Indicate that all was processed. 219 listenerComplete = true; 220 } 221 } catch (e) { 222 exception = e 223 }; 224}; 225 226// Add the debug event listener. 227Debug.setListener(listener); 228 229function f(a) { 230 debugger; 231}; 232 233function g(b) { 234 f(b); 235}; 236 237// Set a break point at return in f and invoke g to hit the breakpoint. 238Debug.setBreakPoint(f, 2, 0); 239o = {}; 240p = {} 241o.o = o; 242o.p = p; 243p.o = o; 244p.p = p; 245g(o); 246 247// Make sure that the debug event listener vas invoked. 248assertTrue(listenerComplete, "listener did not run to completion: " + exception); 249assertFalse(exception, "exception in listener") 250