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. 30 Debug = 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 41 function g() { // line 40 42 var x = 5; 43 var y = 6; 44 var z = 7; 45 }; 46 47 var 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. 51 listenerComplete = false; 52 exception = false; 53 54 var breakpoint1 = -1; 55 var base_request = '"seq":0,"type":"request","command":"listbreakpoints"' 56 57 function safeEval(code) { 58 try { 59 return eval('(' + code + ')'); 60 } catch (e) { 61 assertEquals(void 0, e); 62 return undefined; 63 } 64 } 65 66 67 function 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 75 function 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 83 function 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 116 function 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. 202 Debug.setListener(listener); 203 204 // Set a break point and call to invoke the debug event listener. 205 breakpoint1 = Debug.setBreakPoint(g, 0, 0); 206 g(); 207 208 // Make sure that the debug event listener vas invoked. 209 assertFalse(exception, "exception in listener") 210 assertTrue(listenerComplete, "listener did not run to completion"); 211