debugger-stepping-and-breakpoints.js 8.43 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
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

InspectorTest.log('Tests how multiple sessions interact while pausing, stepping, setting breakpoints and blackboxing.');

var contextGroup = new InspectorTest.ContextGroup();

contextGroup.addScript(`
function foo() {
  return 1;
}
function baz() {
  return 2;
}
function stepping() {
  debugger;
  var a = 1;
  var b = 1;
}
//# sourceURL=test.js`, 9, 25);

contextGroup.addScript(`
function bar() {
  debugger;
}
//# sourceURL=test2.js`, 23, 25);

(async function test() {
30
  InspectorTest.log('Connecting session 1');
31 32
  var session1 = contextGroup.connect();
  await session1.Protocol.Debugger.enable();
33 34 35 36
  InspectorTest.log('Pausing in 1');
  session1.Protocol.Runtime.evaluate({expression: 'debugger;'});
  await waitForPaused(session1, 1);
  InspectorTest.log('Connecting session 2');
37
  var session2 = contextGroup.connect();
38 39 40 41 42 43
  var enabledPromise = session2.Protocol.Debugger.enable();
  await waitForPaused(session2, 2);
  await enabledPromise;
  InspectorTest.log('Resuming in 2');
  session2.Protocol.Debugger.resume();
  await waitForBothResumed();
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154

  InspectorTest.log('Setting breakpoints in 1');
  await session1.Protocol.Debugger.setBreakpointByUrl({url: 'test.js', lineNumber: 11});
  await session1.Protocol.Debugger.setBreakpointByUrl({url: 'test.js', lineNumber: 14});
  InspectorTest.log('Setting breakpoints in 2');
  await session2.Protocol.Debugger.setBreakpointByUrl({url: 'test.js', lineNumber: 11});

  InspectorTest.log('Evaluating common breakpoint in 1');
  session1.Protocol.Runtime.evaluate({expression: 'foo();'});
  await waitForBothPaused();
  InspectorTest.log('Resuming in 1');
  session1.Protocol.Debugger.resume();
  await waitForBothResumed();

  InspectorTest.log('Evaluating debugger in 1');
  session1.Protocol.Runtime.evaluate({expression: 'bar();'});
  await waitForBothPaused();
  InspectorTest.log('Resuming in 2');
  session2.Protocol.Debugger.resume();
  await waitForBothResumed();

  InspectorTest.log('Evaluating exclusive breakpoint in 1');
  session1.Protocol.Runtime.evaluate({expression: 'baz();'});
  await waitForBothPaused();
  InspectorTest.log('Resuming in 1');
  session1.Protocol.Debugger.resume();
  await waitForBothResumed();

  InspectorTest.log('Evaluating common breakpoint in 2');
  session2.Protocol.Runtime.evaluate({expression: 'foo();'});
  await waitForBothPaused();
  InspectorTest.log('Resuming in 2');
  session2.Protocol.Debugger.resume();
  await waitForBothResumed();

  InspectorTest.log('Evaluating debugger in 2');
  session2.Protocol.Runtime.evaluate({expression: 'bar();'});
  await waitForBothPaused();
  InspectorTest.log('Resuming in 2');
  session2.Protocol.Debugger.resume();
  await waitForBothResumed();

  InspectorTest.log('Evaluating exclusive breakpoint in 2');
  session2.Protocol.Runtime.evaluate({expression: 'baz();'});
  await waitForBothPaused();
  InspectorTest.log('Resuming in 1');
  session1.Protocol.Debugger.resume();
  await waitForBothResumed();

  InspectorTest.log('Evaluating stepping in 1');
  session1.Protocol.Runtime.evaluate({expression: 'stepping();'});
  await waitForBothPaused();
  InspectorTest.log('Stepping into in 2');
  session2.Protocol.Debugger.stepInto();
  await waitForBothResumed();
  await waitForBothPaused();
  InspectorTest.log('Stepping over in 1');
  session1.Protocol.Debugger.stepOver();
  await waitForBothResumed();
  await waitForBothPaused();
  InspectorTest.log('Stepping out in 2');
  session2.Protocol.Debugger.stepOut();
  await waitForBothResumed();
  await waitForBothPaused();
  InspectorTest.log('Resuming in 1');
  session1.Protocol.Debugger.resume();
  await waitForBothResumed();

  InspectorTest.log('Pausing in next statement');
  contextGroup.schedulePauseOnNextStatement('some-reason', JSON.stringify({a: 42}));
  session2.Protocol.Runtime.evaluate({expression: 'var a = 1;'});
  await waitForBothPaused();
  InspectorTest.log('Resuming in 1');
  session1.Protocol.Debugger.resume();
  await waitForBothResumed();

  InspectorTest.log('Pausing in next statement');
  contextGroup.schedulePauseOnNextStatement('some-reason', JSON.stringify({a: 42}));
  session2.Protocol.Runtime.evaluate({expression: 'var a = 1;'});
  await waitForBothPaused();
  InspectorTest.log('Resuming in 2');
  session2.Protocol.Debugger.resume();
  await waitForBothResumed();

  InspectorTest.log('Blackboxing bar() in 2');
  await session2.Protocol.Debugger.setBlackboxPatterns({patterns: ['test2.js']});
  InspectorTest.log('Evaluating bar() in 2');
  session2.Protocol.Runtime.evaluate({expression: 'bar();'});
  await waitForPaused(session1, 1);
  InspectorTest.log('Resuming in 1');
  session1.Protocol.Debugger.resume();
  await waitForResumed(session1, 1);

  InspectorTest.log('Blackboxing bar() in 1');
  await session1.Protocol.Debugger.setBlackboxPatterns({patterns: ['test2.js']});
  InspectorTest.log('Evaluating bar() in 2');
  await session2.Protocol.Runtime.evaluate({expression: 'bar();'});

  InspectorTest.log('Skipping pauses in 1');
  await session1.Protocol.Debugger.setSkipAllPauses({skip: true});
  InspectorTest.log('Evaluating common breakpoint in 1');
  session1.Protocol.Runtime.evaluate({expression: 'foo();'});
  await waitForPaused(session2, 2);
  InspectorTest.log('Resuming in 2');
  session2.Protocol.Debugger.resume();
  await waitForResumed(session2, 2);

  InspectorTest.log('Skipping pauses in 2');
  await session2.Protocol.Debugger.setSkipAllPauses({skip: true});
  InspectorTest.log('Evaluating common breakpoint in 1');
  await session1.Protocol.Runtime.evaluate({expression: 'foo();'});
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173

  InspectorTest.log('Unskipping pauses in 1');
  await session1.Protocol.Debugger.setSkipAllPauses({skip: false});
  InspectorTest.log('Unskipping pauses in 2');
  await session2.Protocol.Debugger.setSkipAllPauses({skip: false});

  InspectorTest.log('Deactivating breakpoints in 1');
  await session1.Protocol.Debugger.setBreakpointsActive({active: false});
  InspectorTest.log('Evaluating common breakpoint in 1');
  session1.Protocol.Runtime.evaluate({expression: 'foo();'});
  await waitForPaused(session2, 2);
  InspectorTest.log('Resuming in 2');
  session2.Protocol.Debugger.resume();
  await waitForResumed(session2, 2);

  InspectorTest.log('Deactivating breakpoints in 2');
  await session2.Protocol.Debugger.setBreakpointsActive({active: false});
  InspectorTest.log('Evaluating common breakpoint in 1');
  await session1.Protocol.Runtime.evaluate({expression: 'foo();'});
174

175 176 177 178 179 180 181 182 183 184
  InspectorTest.log('Activating breakpoints in 1');
  await session1.Protocol.Debugger.setBreakpointsActive({active: true});
  InspectorTest.log('Activating breakpoints in 2');
  await session2.Protocol.Debugger.setBreakpointsActive({active: true});
  InspectorTest.log('Disabling debugger agent in 1');
  await session1.Protocol.Debugger.disable();
  InspectorTest.log('Evaluating breakpoint in 1 (should not be triggered)');
  session2.Protocol.Runtime.evaluate({expression: 'baz();\ndebugger;'});
  await waitForPaused(session2, 2);

185 186 187 188 189 190 191 192 193
  session1.Protocol.Debugger.onResumed(() => InspectorTest.log('session1 is resumed'));
  session2.Protocol.Debugger.onResumed(() => InspectorTest.log('session2 is resumed'));
  InspectorTest.log('Activating debugger agent in 1');
  await session1.Protocol.Debugger.enable();
  InspectorTest.log('Disabling debugger agent in 2');
  await session2.Protocol.Debugger.disable();
  InspectorTest.log('Disabling debugger agent in 1');
  await session1.Protocol.Debugger.disable();

194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
  InspectorTest.completeTest();

  function waitForBothPaused() {
    return Promise.all([waitForPaused(session1, 1), waitForPaused(session2, 2)]);
  }

  function waitForBothResumed() {
    return Promise.all([waitForResumed(session1, 1), waitForResumed(session2, 2)]);
  }
})();

function waitForPaused(session, num) {
  return session.Protocol.Debugger.oncePaused().then(message => {
    InspectorTest.log(`Paused in ${num}:`);
    InspectorTest.log(`  reason: ${message.params.reason}`);
    InspectorTest.log(`  hit breakpoints: ${(message.params.hitBreakpoints || []).join(';')}`);
    var callFrame = message.params.callFrames[0];
    InspectorTest.log(`  location: ${callFrame.functionName || '<anonymous>'}@${callFrame.location.lineNumber}`);
    InspectorTest.log(`  data: ${JSON.stringify(message.params.data || null)}`);
  });
}

function waitForResumed(session, num) {
  return session.Protocol.Debugger.onceResumed().then(message => {
    InspectorTest.log(`Resumed in ${num}`);
  });
}