1// Copyright 2010 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 32// Note: the following tests only checks the debugger handling of the 33// setexceptionbreak command. It does not test whether the debugger 34// actually breaks on exceptions or not. That functionality is tested 35// in test-debug.cc instead. 36 37// Note: The following function g() is purposedly placed here so that 38// its line numbers will not change should we add more lines of test code 39// below. The test checks for these line numbers. 40 41function g() { // line 40 42 var x = 5; 43 var y = 6; 44 var z = 7; 45}; 46 47var first_lineno = 40; // Must be the line number of g() above. 48 // The first line of the file is line 0. 49 50// Simple function which stores the last debug event. 51listenerComplete = false; 52exception = false; 53 54var breakpoint1 = -1; 55var base_request = '"seq":0,"type":"request","command":"listbreakpoints"' 56 57function safeEval(code) { 58 try { 59 return eval('(' + code + ')'); 60 } catch (e) { 61 assertEquals(void 0, e); 62 return undefined; 63 } 64} 65 66 67function clearBreakpoint(dcp, breakpoint_id) { 68 var base_request = '"seq":0,"type":"request","command":"clearbreakpoint"' 69 var arguments = '{"breakpoint":' + breakpoint_id + '}' 70 var request = '{' + base_request + ',"arguments":' + arguments + '}' 71 var json_response = dcp.processDebugJSONRequest(request); 72} 73 74 75function setBreakOnException(dcp, type, enabled) { 76 var base_request = '"seq":0,"type":"request","command":"setexceptionbreak"' 77 var arguments = '{"type":"' + type + '","enabled":' + enabled + '}' 78 var request = '{' + base_request + ',"arguments":' + arguments + '}' 79 var json_response = dcp.processDebugJSONRequest(request); 80} 81 82 83function testArguments(dcp, success, breakpoint_ids, breakpoint_linenos, 84 break_on_all, break_on_uncaught) { 85 var request = '{' + base_request + '}' 86 var json_response = dcp.processDebugJSONRequest(request); 87 var response = safeEval(json_response); 88 var num_breakpoints = breakpoint_ids.length; 89 90 if (success) { 91 assertTrue(response.success, json_response); 92 assertEquals(response.body.breakpoints.length, num_breakpoints); 93 if (num_breakpoints > 0) { 94 var breakpoints = response.body.breakpoints; 95 for (var i = 0; i < breakpoints.length; i++) { 96 var id = breakpoints[i].number; 97 var found = false; 98 for (var j = 0; j < num_breakpoints; j++) { 99 if (breakpoint_ids[j] == id) { 100 assertEquals(breakpoints[i].line, breakpoint_linenos[j]); 101 found = true; 102 break; 103 } 104 } 105 assertTrue(found, "found unexpected breakpoint " + id); 106 } 107 } 108 assertEquals(response.body.breakOnExceptions, break_on_all); 109 assertEquals(response.body.breakOnUncaughtExceptions, break_on_uncaught); 110 } else { 111 assertFalse(response.success, json_response); 112 } 113} 114 115 116function listener(event, exec_state, event_data, data) { 117 try { 118 if (event == Debug.DebugEvent.Break) { 119 // Get the debug command processor. 120 var dcp = exec_state.debugCommandProcessor("unspecified_running_state"); 121 122 // Test with the 1 breakpoint already set: 123 testArguments(dcp, true, [ breakpoint1 ], [ first_lineno ], false, false); 124 125 setBreakOnException(dcp, "all", true); 126 testArguments(dcp, true, [ breakpoint1 ], [ first_lineno ], true, false); 127 128 setBreakOnException(dcp, "uncaught", true); 129 testArguments(dcp, true, [ breakpoint1 ], [ first_lineno ], true, true); 130 131 setBreakOnException(dcp, "all", false); 132 testArguments(dcp, true, [ breakpoint1 ], [ first_lineno ], false, true); 133 134 setBreakOnException(dcp, "uncaught", false); 135 testArguments(dcp, true, [ breakpoint1 ], [ first_lineno ], false, false); 136 137 // Clear the one breakpoint and retest: 138 clearBreakpoint(dcp, breakpoint1); 139 testArguments(dcp, true, [], [], false, false); 140 141 setBreakOnException(dcp, "all", true); 142 testArguments(dcp, true, [], [], true, false); 143 144 setBreakOnException(dcp, "uncaught", true); 145 testArguments(dcp, true, [], [], true, true); 146 147 setBreakOnException(dcp, "all", false); 148 testArguments(dcp, true, [], [], false, true); 149 150 setBreakOnException(dcp, "uncaught", false); 151 testArguments(dcp, true, [], [], false, false); 152 153 // Set some more breakpoints, and clear them in various orders: 154 var bp2 = Debug.setBreakPoint(g, 1, 0); 155 testArguments(dcp, true, [ bp2 ], 156 [ first_lineno + 1 ], 157 false, false); 158 159 var bp3 = Debug.setBreakPoint(g, 2, 0); 160 testArguments(dcp, true, [ bp2, bp3 ], 161 [ first_lineno + 1, first_lineno + 2 ], 162 false, false); 163 164 var bp4 = Debug.setBreakPoint(g, 3, 0); 165 testArguments(dcp, true, [ bp2, bp3, bp4 ], 166 [ first_lineno + 1, first_lineno + 2, first_lineno + 3 ], 167 false, false); 168 169 clearBreakpoint(dcp, bp3); 170 testArguments(dcp, true, [ bp2, bp4 ], 171 [ first_lineno + 1, first_lineno + 3 ], 172 false, false); 173 174 clearBreakpoint(dcp, bp4); 175 testArguments(dcp, true, [ bp2 ], 176 [ first_lineno + 1 ], 177 false, false); 178 179 var bp5 = Debug.setBreakPoint(g, 3, 0); 180 testArguments(dcp, true, [ bp2, bp5 ], 181 [ first_lineno + 1, first_lineno + 3 ], 182 false, false); 183 184 clearBreakpoint(dcp, bp2); 185 testArguments(dcp, true, [ bp5 ], 186 [ first_lineno + 3 ], 187 false, false); 188 189 clearBreakpoint(dcp, bp5); 190 testArguments(dcp, true, [], [], false, false); 191 192 // Indicate that all was processed. 193 listenerComplete = true; 194 195 } 196 } catch (e) { 197 exception = e 198 }; 199}; 200 201// Add the debug event listener. 202Debug.setListener(listener); 203 204// Set a break point and call to invoke the debug event listener. 205breakpoint1 = Debug.setBreakPoint(g, 0, 0); 206g(); 207 208// Make sure that the debug event listener vas invoked. 209assertFalse(exception, "exception in listener") 210assertTrue(listenerComplete, "listener did not run to completion"); 211