mirror of https://github.com/lukechilds/node.git
Browse Source
This change allows reentering the message dispatch loop when the Node is paused. This is necessary when the pause happened as a result of the message sent by a debug frontend, such as evaluating a function with a breakpoint inside. Fixes: https://github.com/nodejs/node/issues/13320 PR-URL: https://github.com/nodejs/node/pull/13350 Reviewed-By: James M Snell <jasnell@gmail.com>v6
Eugene Ostroukhov
8 years ago
7 changed files with 181 additions and 24 deletions
@ -0,0 +1,13 @@ |
|||
'use strict'; // eslint-disable-line required-modules
|
|||
let invocations = 0; |
|||
const interval = setInterval(() => {}, 1000); |
|||
|
|||
global.sum = function() { |
|||
const a = 1; |
|||
const b = 2; |
|||
const c = a + b; |
|||
clearInterval(interval); |
|||
console.log(invocations++, c); |
|||
}; |
|||
|
|||
console.log('Ready!'); |
@ -0,0 +1,128 @@ |
|||
'use strict'; |
|||
const common = require('../common'); |
|||
common.skipIfInspectorDisabled(); |
|||
const assert = require('assert'); |
|||
const helper = require('./inspector-helper.js'); |
|||
const path = require('path'); |
|||
|
|||
const script = path.join(path.dirname(module.filename), 'global-function.js'); |
|||
|
|||
|
|||
function setupExpectBreakOnLine(line, url, session) { |
|||
return function(message) { |
|||
if ('Debugger.paused' === message['method']) { |
|||
const callFrame = message['params']['callFrames'][0]; |
|||
const location = callFrame['location']; |
|||
assert.strictEqual(url, session.scriptUrlForId(location['scriptId'])); |
|||
assert.strictEqual(line, location['lineNumber']); |
|||
return true; |
|||
} |
|||
}; |
|||
} |
|||
|
|||
function setupExpectConsoleOutputAndBreak(type, values) { |
|||
if (!(values instanceof Array)) |
|||
values = [ values ]; |
|||
let consoleLog = false; |
|||
function matchConsoleLog(message) { |
|||
if ('Runtime.consoleAPICalled' === message['method']) { |
|||
const params = message['params']; |
|||
if (params['type'] === type) { |
|||
let i = 0; |
|||
for (const value of params['args']) { |
|||
if (value['value'] !== values[i++]) |
|||
return false; |
|||
} |
|||
return i === values.length; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return function(message) { |
|||
if (consoleLog) |
|||
return message['method'] === 'Debugger.paused'; |
|||
consoleLog = matchConsoleLog(message); |
|||
return false; |
|||
}; |
|||
} |
|||
|
|||
function setupExpectContextDestroyed(id) { |
|||
return function(message) { |
|||
if ('Runtime.executionContextDestroyed' === message['method']) |
|||
return message['params']['executionContextId'] === id; |
|||
}; |
|||
} |
|||
|
|||
function setupDebugger(session) { |
|||
console.log('[test]', 'Setting up a debugger'); |
|||
const commands = [ |
|||
{ 'method': 'Runtime.enable' }, |
|||
{ 'method': 'Debugger.enable' }, |
|||
{ 'method': 'Debugger.setAsyncCallStackDepth', |
|||
'params': {'maxDepth': 0} }, |
|||
{ 'method': 'Runtime.runIfWaitingForDebugger' }, |
|||
]; |
|||
|
|||
session |
|||
.sendInspectorCommands(commands) |
|||
.expectMessages((message) => 'Runtime.consoleAPICalled' === message.method); |
|||
} |
|||
|
|||
function breakOnLine(session) { |
|||
console.log('[test]', 'Breaking in the code'); |
|||
const commands = [ |
|||
{ 'method': 'Debugger.setBreakpointByUrl', |
|||
'params': { 'lineNumber': 9, |
|||
'url': script, |
|||
'columnNumber': 0, |
|||
'condition': '' |
|||
} |
|||
}, |
|||
{ 'method': 'Runtime.evaluate', |
|||
'params': { 'expression': 'sum()', |
|||
'objectGroup': 'console', |
|||
'includeCommandLineAPI': true, |
|||
'silent': false, |
|||
'contextId': 1, |
|||
'returnByValue': false, |
|||
'generatePreview': true, |
|||
'userGesture': true, |
|||
'awaitPromise': false |
|||
} |
|||
} |
|||
]; |
|||
helper.markMessageNoResponse(commands[1]); |
|||
session |
|||
.sendInspectorCommands(commands) |
|||
.expectMessages(setupExpectBreakOnLine(9, script, session)); |
|||
} |
|||
|
|||
function stepOverConsoleStatement(session) { |
|||
console.log('[test]', 'Step over console statement and test output'); |
|||
session |
|||
.sendInspectorCommands({ 'method': 'Debugger.stepOver' }) |
|||
.expectMessages(setupExpectConsoleOutputAndBreak('log', [0, 3])); |
|||
} |
|||
|
|||
function testWaitsForFrontendDisconnect(session, harness) { |
|||
console.log('[test]', 'Verify node waits for the frontend to disconnect'); |
|||
session.sendInspectorCommands({ 'method': 'Debugger.resume'}) |
|||
.expectMessages(setupExpectContextDestroyed(1)) |
|||
.expectStderrOutput('Waiting for the debugger to disconnect...') |
|||
.disconnect(true); |
|||
} |
|||
|
|||
function runTests(harness) { |
|||
harness |
|||
.runFrontendSession([ |
|||
setupDebugger, |
|||
breakOnLine, |
|||
stepOverConsoleStatement, |
|||
testWaitsForFrontendDisconnect |
|||
]).expectShutDown(0); |
|||
} |
|||
|
|||
helper.startNodeForInspectorTest(runTests, |
|||
['--inspect'], |
|||
undefined, |
|||
script); |
Loading…
Reference in new issue