From f991f75e78cfaef4faa7d910c8de98565542ed20 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 18 Apr 2017 22:10:35 +0200 Subject: [PATCH 1/2] lib,src,test: update --debug/debug-brk comments Overlooked in commit 47f8f74 ("src: remove support for --debug") from earlier this month. --- lib/module.js | 2 +- src/node.cc | 2 +- test/inspector/test-inspector.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/module.js b/lib/module.js index fe83cd0ecb8a26..d818dd6f2b1b42 100644 --- a/lib/module.js +++ b/lib/module.js @@ -528,7 +528,7 @@ Module.prototype.require = function(path) { // Resolved path to process.argv[1] will be lazily placed here -// (needed for setting breakpoint when called with --debug-brk) +// (needed for setting breakpoint when called with --inspect-brk) var resolvedArgv; diff --git a/src/node.cc b/src/node.cc index a24dcdb734e79b..0243fafa7cfcb3 100644 --- a/src/node.cc +++ b/src/node.cc @@ -3337,7 +3337,7 @@ void SetupProcessObject(Environment* env, READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate())); } - // --debug-brk + // --inspect-brk if (debug_options.wait_for_connect()) { READONLY_PROPERTY(process, "_debugWaitConnect", True(env->isolate())); } diff --git a/test/inspector/test-inspector.js b/test/inspector/test-inspector.js index 5e41864755b08e..458c668953a360 100644 --- a/test/inspector/test-inspector.js +++ b/test/inspector/test-inspector.js @@ -89,7 +89,7 @@ function setupExpectValue(value) { function testBreakpointOnStart(session) { console.log('[test]', - 'Verifying debugger stops on start (--debug-brk option)'); + 'Verifying debugger stops on start (--inspect-brk option)'); const commands = [ { 'method': 'Runtime.enable' }, { 'method': 'Debugger.enable' }, From 857dd1a6b1f06813a9bb4e534000f059b63fc4a2 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 18 Apr 2017 22:46:49 +0200 Subject: [PATCH 2/2] lib: remove _debugger.js The file no longer works after the removal of the --debug/--debug-brk switches in commit 47f8f74 ("src: remove support for --debug".) This commit also removes several tests that still referenced the old debugger but were either unit-testing its internals or passing for the wrong reason (like expecting an operation to fail, which it did because the debugger is gone.) --- lib/_debugger.js | 1791 ----------------- lib/internal/bootstrap_node.js | 33 +- node.gyp | 1 - test/debugger/test-debug-break-on-uncaught.js | 134 -- test/debugger/test-debugger-client.js | 237 --- test/debugger/test-debugger-remote.js | 61 - test/fixtures/debug-uncaught-async.js | 18 - test/fixtures/debug-uncaught.js | 16 - .../test-cluster-disconnect-handles.js | 99 - test/message/core_line_numbers.out | 4 +- test/message/error_exit.out | 3 +- test/message/eval_messages.out | 8 - test/message/nexttick_throw.out | 3 +- .../unhandled_promise_trace_warnings.out | 2 - test/message/vm_display_runtime_error.out | 2 +- test/message/vm_display_syntax_error.out | 8 +- .../message/vm_dont_display_runtime_error.out | 2 +- test/message/vm_dont_display_syntax_error.out | 4 +- test/parallel/test-debug-protocol-execute.js | 20 - .../test-debug-uncaught-exception-async.js | 22 - .../parallel/test-debug-uncaught-exception.js | 17 - .../test-debugger-client-addhandle.js | 44 - 22 files changed, 14 insertions(+), 2515 deletions(-) delete mode 100644 lib/_debugger.js delete mode 100644 test/debugger/test-debug-break-on-uncaught.js delete mode 100644 test/debugger/test-debugger-client.js delete mode 100644 test/debugger/test-debugger-remote.js delete mode 100644 test/fixtures/debug-uncaught-async.js delete mode 100644 test/fixtures/debug-uncaught.js delete mode 100644 test/known_issues/test-cluster-disconnect-handles.js delete mode 100644 test/parallel/test-debug-protocol-execute.js delete mode 100644 test/parallel/test-debug-uncaught-exception-async.js delete mode 100644 test/parallel/test-debug-uncaught-exception.js delete mode 100644 test/parallel/test-debugger-client-addhandle.js diff --git a/lib/_debugger.js b/lib/_debugger.js deleted file mode 100644 index 289ee0f09e4670..00000000000000 --- a/lib/_debugger.js +++ /dev/null @@ -1,1791 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; - -const util = require('util'); -const path = require('path'); -const net = require('net'); -const vm = require('vm'); -const Module = require('module'); -const repl = require('repl'); -const inherits = util.inherits; -const assert = require('assert'); -const spawn = require('child_process').spawn; -const Buffer = require('buffer').Buffer; -const prefix = `(${process.release.name}:${process.pid}) `; - -function error(msg) { - console.error(`${prefix}${msg}`); -} - -exports.start = function(argv, stdin, stdout) { - argv || (argv = process.argv.slice(2)); - - if (argv.length < 1) { - console.error('Usage: node debug script.js'); - console.error(' node debug :'); - console.error(' node debug -p '); - process.exit(1); - } - - // Setup input/output streams - stdin = stdin || process.stdin; - stdout = stdout || process.stdout; - - const args = [`--debug-brk=${exports.port}`].concat(argv); - const interface_ = new Interface(stdin, stdout, args); - - stdin.resume(); - - process.on('uncaughtException', function(e) { - error('There was an internal error in Node\'s debugger. ' + - 'Please report this bug.'); - console.error(e.message); - console.error(e.stack); - if (interface_.child) interface_.child.kill(); - process.exit(1); - }); -}; - -exports.port = process.debugPort; - - -// -// Parser/Serializer for V8 debugger protocol -// https://github.com/v8/v8/wiki/Debugging-Protocol -// -// Usage: -// p = new Protocol(); -// -// p.onResponse = function(res) { -// // do stuff with response from V8 -// }; -// -// socket.setEncoding('utf8'); -// socket.on('data', function(s) { -// // Pass strings into the protocol -// p.execute(s); -// }); -// -// -function Protocol() { - this._newRes(); -} -exports.Protocol = Protocol; - - -Protocol.prototype._newRes = function(raw) { - this.res = { raw: raw || '', headers: {} }; - this.state = 'headers'; - this.reqSeq = 1; - this.execute(''); -}; - - -Protocol.prototype.execute = function(d) { - var res = this.res; - res.raw += d; - - switch (this.state) { - case 'headers': - var endHeaderIndex = res.raw.indexOf('\r\n\r\n'); - - if (endHeaderIndex < 0) break; - - var rawHeader = res.raw.slice(0, endHeaderIndex); - var endHeaderByteIndex = Buffer.byteLength(rawHeader, 'utf8'); - var lines = rawHeader.split('\r\n'); - for (var i = 0; i < lines.length; i++) { - var kv = lines[i].split(/: +/); - res.headers[kv[0]] = kv[1]; - } - - this.contentLength = +res.headers['Content-Length']; - this.bodyStartByteIndex = endHeaderByteIndex + 4; - - this.state = 'body'; - - var len = Buffer.byteLength(res.raw, 'utf8'); - if (len - this.bodyStartByteIndex < this.contentLength) { - break; - } - // falls through - case 'body': - var resRawByteLength = Buffer.byteLength(res.raw, 'utf8'); - - if (resRawByteLength - this.bodyStartByteIndex >= this.contentLength) { - var buf = Buffer.allocUnsafe(resRawByteLength); - buf.write(res.raw, 0, resRawByteLength, 'utf8'); - res.body = - buf.slice(this.bodyStartByteIndex, - this.bodyStartByteIndex + - this.contentLength).toString('utf8'); - // JSON parse body? - res.body = res.body.length ? JSON.parse(res.body) : {}; - - // Done! - this.onResponse(res); - - this._newRes(buf.slice(this.bodyStartByteIndex + - this.contentLength).toString('utf8')); - } - break; - - default: - throw new Error('Unknown state'); - } -}; - - -Protocol.prototype.serialize = function(req) { - req.type = 'request'; - req.seq = this.reqSeq++; - var json = JSON.stringify(req); - return 'Content-Length: ' + Buffer.byteLength(json, 'utf8') + - '\r\n\r\n' + json; -}; - - -const NO_FRAME = -1; - -function Client() { - net.Socket.call(this); - var protocol = this.protocol = new Protocol(this); - this._reqCallbacks = []; - var socket = this; - - this.currentFrame = NO_FRAME; - this.currentSourceLine = -1; - this.handles = {}; - this.scripts = {}; - this.breakpoints = []; - - // Note that 'Protocol' requires strings instead of Buffers. - socket.setEncoding('utf8'); - socket.on('data', function(d) { - protocol.execute(d); - }); - - protocol.onResponse = (res) => this._onResponse(res); -} -inherits(Client, net.Socket); -exports.Client = Client; - - -Client.prototype._addHandle = function(desc) { - if (desc === null || typeof desc !== 'object' || - typeof desc.handle !== 'number') { - return; - } - - this.handles[desc.handle] = desc; - - if (desc.type === 'script') { - this._addScript(desc); - } -}; - - -const natives = process.binding('natives'); - - -Client.prototype._addScript = function(desc) { - this.scripts[desc.id] = desc; - if (desc.name) { - desc.isNative = (desc.name.replace('.js', '') in natives) || - desc.name === 'node.js'; - } -}; - - -Client.prototype._removeScript = function(desc) { - this.scripts[desc.id] = undefined; -}; - - -Client.prototype._onResponse = function(res) { - var cb; - var index = -1; - - this._reqCallbacks.some(function(fn, i) { - if (fn.request_seq === res.body.request_seq) { - cb = fn; - index = i; - return true; - } - }); - - var self = this; - var handled = false; - - if (res.headers.Type === 'connect') { - // Request a list of scripts for our own storage. - self.reqScripts(); - self.emit('ready'); - handled = true; - - } else if (res.body && res.body.event === 'break') { - this.emit('break', res.body); - handled = true; - - } else if (res.body && res.body.event === 'exception') { - this.emit('exception', res.body); - handled = true; - - } else if (res.body && res.body.event === 'afterCompile') { - this._addHandle(res.body.body.script); - handled = true; - - } else if (res.body && res.body.event === 'scriptCollected') { - // ??? - this._removeScript(res.body.body.script); - handled = true; - - } else if (res.body && res.body.event === 'compileError') { - // This event is not used anywhere right now, perhaps somewhere in the - // future? - handled = true; - } - - if (cb) { - this._reqCallbacks.splice(index, 1); - handled = true; - - var err = res.success === false && (res.message || true) || - res.body.success === false && (res.body.message || true); - cb(err, res.body && res.body.body || res.body, res); - } - - if (!handled) this.emit('unhandledResponse', res.body); -}; - - -Client.prototype.req = function(req, cb) { - this.write(this.protocol.serialize(req)); - cb.request_seq = req.seq; - this._reqCallbacks.push(cb); -}; - - -Client.prototype.reqVersion = function(cb) { - cb = cb || function() {}; - this.req({ command: 'version' }, function(err, body, res) { - if (err) return cb(err); - cb(null, res.body.body.V8Version, res.body.running); - }); -}; - - -Client.prototype.reqLookup = function(refs, cb) { - var self = this; - - // TODO: We have a cache of handle's we've already seen in this.handles - // This can be used if we're careful. - var req = { - command: 'lookup', - arguments: { - handles: refs - } - }; - - cb = cb || function() {}; - this.req(req, function(err, res) { - if (err) return cb(err); - for (var ref in res) { - if (res[ref] !== null && typeof res[ref] === 'object') { - self._addHandle(res[ref]); - } - } - - cb(null, res); - }); -}; - -Client.prototype.reqScopes = function(cb) { - const self = this; - const req = { - command: 'scopes', - arguments: {} - }; - - cb = cb || function() {}; - this.req(req, function(err, res) { - if (err) return cb(err); - var refs = res.scopes.map(function(scope) { - return scope.object.ref; - }); - - self.reqLookup(refs, function(err, res) { - if (err) return cb(err); - - var globals = Object.keys(res).map(function(key) { - return res[key].properties.map(function(prop) { - return prop.name; - }); - }); - - cb(null, globals.reverse()); - }); - }); -}; - -// This is like reqEval, except it will look up the expression in each of the -// scopes associated with the current frame. -Client.prototype.reqEval = function(expression, cb) { - var self = this; - - if (this.currentFrame === NO_FRAME) { - // Only need to eval in global scope. - this.reqFrameEval(expression, NO_FRAME, cb); - return; - } - - cb = cb || function() {}; - // Otherwise we need to get the current frame to see which scopes it has. - this.reqBacktrace(function(err, bt) { - if (err || !bt.frames) { - // ?? - return cb(null, {}); - } - - var frame = bt.frames[self.currentFrame]; - - var evalFrames = frame.scopes.map(function(s) { - if (!s) return; - var x = bt.frames[s.index]; - if (!x) return; - return x.index; - }); - - self._reqFramesEval(expression, evalFrames, cb); - }); -}; - - -// Finds the first scope in the array in which the expression evals. -Client.prototype._reqFramesEval = function(expression, evalFrames, cb) { - if (evalFrames.length === 0) { - // Just eval in global scope. - this.reqFrameEval(expression, NO_FRAME, cb); - return; - } - - var self = this; - var i = evalFrames.shift(); - - cb = cb || function() {}; - this.reqFrameEval(expression, i, function(err, res) { - if (!err) return cb(null, res); - self._reqFramesEval(expression, evalFrames, cb); - }); -}; - - -Client.prototype.reqFrameEval = function(expression, frame, cb) { - var self = this; - var req = { - command: 'evaluate', - arguments: { expression: expression } - }; - - if (frame === NO_FRAME) { - req.arguments.global = true; - } else { - req.arguments.frame = frame; - } - - cb = cb || function() {}; - this.req(req, function(err, res) { - if (!err) self._addHandle(res); - cb(err, res); - }); -}; - - -// reqBacktrace(cb) -// TODO: from, to, bottom -Client.prototype.reqBacktrace = function(cb) { - this.req({ command: 'backtrace', arguments: { inlineRefs: true } }, cb); -}; - - -// reqSetExceptionBreak(type, cb) -// TODO: from, to, bottom -Client.prototype.reqSetExceptionBreak = function(type, cb) { - this.req({ - command: 'setexceptionbreak', - arguments: { type: type, enabled: true } - }, cb); -}; - - -// Returns an array of objects like this: -// -// { handle: 11, -// type: 'script', -// name: 'node.js', -// id: 14, -// lineOffset: 0, -// columnOffset: 0, -// lineCount: 562, -// sourceStart: '(function(process) {\n\n ', -// sourceLength: 15939, -// scriptType: 2, -// compilationType: 0, -// context: { ref: 10 }, -// text: 'node.js (lines: 562)' } -// -Client.prototype.reqScripts = function(cb) { - var self = this; - cb = cb || function() {}; - - this.req({ command: 'scripts' }, function(err, res) { - if (err) return cb(err); - - for (var i = 0; i < res.length; i++) { - self._addHandle(res[i]); - } - cb(null); - }); -}; - - -Client.prototype.reqContinue = function(cb) { - this.currentFrame = NO_FRAME; - this.req({ command: 'continue' }, cb); -}; - -Client.prototype.listbreakpoints = function(cb) { - this.req({ command: 'listbreakpoints' }, cb); -}; - -Client.prototype.setBreakpoint = function(req, cb) { - req = { - command: 'setbreakpoint', - arguments: req - }; - - this.req(req, cb); -}; - -Client.prototype.clearBreakpoint = function(req, cb) { - req = { - command: 'clearbreakpoint', - arguments: req - }; - - this.req(req, cb); -}; - -Client.prototype.reqSource = function(from, to, cb) { - var req = { - command: 'source', - fromLine: from, - toLine: to - }; - - this.req(req, cb); -}; - - -// client.next(1, cb); -Client.prototype.step = function(action, count, cb) { - var req = { - command: 'continue', - arguments: { stepaction: action, stepcount: count } - }; - - this.currentFrame = NO_FRAME; - this.req(req, cb); -}; - - -Client.prototype.mirrorObject = function(handle, depth, cb) { - var self = this; - - var val; - - if (handle.type === 'object') { - // The handle looks something like this: - // { handle: 8, - // type: 'object', - // className: 'Object', - // constructorFunction: { ref: 9 }, - // protoObject: { ref: 4 }, - // prototypeObject: { ref: 2 }, - // properties: [ { name: 'hello', propertyType: 1, ref: 10 } ], - // text: '#' } - - // For now ignore the className and constructor and prototype. - // TJ's method of object inspection would probably be good for this: - // https://groups.google.com/forum/?pli=1#!topic/nodejs-dev/4gkWBOimiOg - - var propertyRefs = handle.properties.map(function(p) { - return p.ref; - }); - - cb = cb || function() {}; - this.reqLookup(propertyRefs, function(err, res) { - if (err) { - error('problem with reqLookup'); - cb(null, handle); - return; - } - - var mirror; - var waiting = 1; - - if (handle.className === 'Array') { - mirror = []; - } else if (handle.className === 'Date') { - mirror = new Date(handle.value); - } else { - mirror = {}; - } - - - var keyValues = []; - handle.properties.forEach(function(prop, i) { - var value = res[prop.ref]; - var mirrorValue; - if (value) { - mirrorValue = value.value ? value.value : value.text; - } else { - mirrorValue = '[?]'; - } - - // Skip the 'length' property. - if (Array.isArray(mirror) && prop.name === 'length') { - return; - } - - keyValues[i] = { - name: prop.name, - value: mirrorValue - }; - if (value && value.handle && depth > 0) { - waiting++; - self.mirrorObject(value, depth - 1, function(err, result) { - if (!err) keyValues[i].value = result; - waitForOthers(); - }); - } - }); - - waitForOthers(); - function waitForOthers() { - if (--waiting === 0) { - keyValues.forEach(function(kv) { - mirror[kv.name] = kv.value; - }); - cb(null, mirror); - } - } - }); - return; - } else if (handle.type === 'function') { - val = function() {}; - } else if (handle.type === 'null') { - val = null; - } else if (handle.value !== undefined) { - val = handle.value; - } else if (handle.type === 'undefined') { - val = undefined; - } else { - val = handle; - } - process.nextTick(cb, null, val); -}; - - -Client.prototype.fullTrace = function(cb) { - var self = this; - - cb = cb || function() {}; - this.reqBacktrace(function(err, trace) { - if (err) return cb(err); - if (trace.totalFrames <= 0) return cb(Error('No frames')); - - var refs = []; - - for (var i = 0; i < trace.frames.length; i++) { - var frame = trace.frames[i]; - // looks like this: - // { type: 'frame', - // index: 0, - // receiver: { ref: 1 }, - // func: { ref: 0 }, - // script: { ref: 7 }, - // constructCall: false, - // atReturn: false, - // debuggerFrame: false, - // arguments: [], - // locals: [], - // position: 160, - // line: 7, - // column: 2, - // sourceLineText: ' debugger;', - // scopes: [ { type: 1, index: 0 }, { type: 0, index: 1 } ], - // text: '#00 blah() /home/ryan/projects/node/test-debug.js l...' } - refs.push(frame.script.ref); - refs.push(frame.func.ref); - refs.push(frame.receiver.ref); - } - - self.reqLookup(refs, function(err, res) { - if (err) return cb(err); - - for (var i = 0; i < trace.frames.length; i++) { - var frame = trace.frames[i]; - frame.script = res[frame.script.ref]; - frame.func = res[frame.func.ref]; - frame.receiver = res[frame.receiver.ref]; - } - - cb(null, trace); - }); - }); -}; - - -const commands = [ - [ - 'run (r)', - 'cont (c)', - 'next (n)', - 'step (s)', - 'out (o)', - 'backtrace (bt)', - 'setBreakpoint (sb)', - 'clearBreakpoint (cb)' - ], - [ - 'watch', - 'unwatch', - 'watchers', - 'repl', - 'exec', - 'restart', - 'kill', - 'list', - 'scripts', - 'breakOnException', - 'breakpoints', - 'version' - ] -]; - - -var helpMessage = 'Commands: ' + commands.map(function(group) { - return group.join(', '); -}).join(',\n'); - -// Previous command received. Initialize to empty command. -var lastCommand = '\n'; - - -function SourceUnderline(sourceText, position, repl) { - if (!sourceText) return ''; - - const head = sourceText.slice(0, position); - var tail = sourceText.slice(position); - - // Colourize char if stdout supports colours - if (repl.useColors) { - tail = tail.replace(/(.+?)([^\w]|$)/, '\u001b[32m$1\u001b[39m$2'); - } - - // Return source line with coloured char at `position` - return [ - head, - tail - ].join(''); -} - - -function SourceInfo(body) { - var result = body.exception ? 'exception in ' : 'break in '; - - if (body.script) { - if (body.script.name) { - var name = body.script.name; - const dir = path.resolve() + '/'; - - // Change path to relative, if possible - if (name.indexOf(dir) === 0) { - name = name.slice(dir.length); - } - - result += name; - } else { - result += '[unnamed]'; - } - } - result += ':'; - result += body.sourceLine + 1; - - if (body.exception) result += '\n' + body.exception.text; - - return result; -} - -// This class is the repl-enabled debugger interface which is invoked on -// "node debug" -function Interface(stdin, stdout, args) { - var self = this; - - this.stdin = stdin; - this.stdout = stdout; - this.args = args; - - // Two eval modes are available: controlEval and debugEval - // But controlEval is used by default - var opts = { - prompt: 'debug> ', - input: this.stdin, - output: this.stdout, - eval: (code, ctx, file, cb) => this.controlEval(code, ctx, file, cb), - useGlobal: false, - ignoreUndefined: true - }; - if (parseInt(process.env['NODE_NO_READLINE'], 10)) { - opts.terminal = false; - } else if (parseInt(process.env['NODE_FORCE_READLINE'], 10)) { - opts.terminal = true; - - // Emulate Ctrl+C if we're emulating terminal - if (!this.stdout.isTTY) { - process.on('SIGINT', function() { - self.repl.rli.emit('SIGINT'); - }); - } - } - if (parseInt(process.env['NODE_DISABLE_COLORS'], 10)) { - opts.useColors = false; - } - - this.repl = repl.start(opts); - - // Do not print useless warning - repl._builtinLibs.splice(repl._builtinLibs.indexOf('repl'), 1); - - // Kill child process when main process dies - this.repl.on('exit', function() { - process.exit(0); - }); - - // Handle all possible exits - process.on('exit', () => this.killChild()); - process.once('SIGTERM', process.exit.bind(process, 0)); - process.once('SIGHUP', process.exit.bind(process, 0)); - - var proto = Interface.prototype; - const ignored = [ - 'pause', - 'resume', - 'exitRepl', - 'handleBreak', - 'requireConnection', - 'killChild', - 'trySpawn', - 'controlEval', - 'debugEval', - 'print', - 'childPrint', - 'clearline' - ]; - const shortcut = { - 'run': 'r', - 'cont': 'c', - 'next': 'n', - 'step': 's', - 'out': 'o', - 'backtrace': 'bt', - 'setBreakpoint': 'sb', - 'clearBreakpoint': 'cb', - 'pause_': 'pause' - }; - - function defineProperty(key, protoKey) { - // Check arity - var fn = proto[protoKey].bind(self); - - if (proto[protoKey].length === 0) { - Object.defineProperty(self.repl.context, key, { - get: fn, - enumerable: true, - configurable: false - }); - } else { - self.repl.context[key] = fn; - } - } - - // Copy all prototype methods in repl context - // Setup them as getters if possible - for (var i in proto) { - if (Object.prototype.hasOwnProperty.call(proto, i) && - ignored.indexOf(i) === -1) { - defineProperty(i, i); - if (shortcut[i]) defineProperty(shortcut[i], i); - } - } - - this.killed = false; - this.waiting = null; - this.paused = 0; - this.context = this.repl.context; - this.history = { - debug: [], - control: [] - }; - this.breakpoints = []; - this._watchers = []; - - // Run script automatically - this.pause(); - - setImmediate(() => { this.run(() => this.resume()); }); -} - - -// Stream control - - -Interface.prototype.pause = function() { - if (this.killed || this.paused++ > 0) return this; - this.repl.rli.pause(); - this.stdin.pause(); - return this; -}; - -Interface.prototype.resume = function(silent) { - if (this.killed || this.paused === 0 || --this.paused !== 0) return this; - this.repl.rli.resume(); - if (silent !== true) { - this.repl.displayPrompt(); - } - this.stdin.resume(); - - if (this.waiting) { - this.waiting(); - this.waiting = null; - } - return this; -}; - - -// Clear current line -Interface.prototype.clearline = function() { - if (this.stdout.isTTY) { - this.stdout.cursorTo(0); - this.stdout.clearLine(1); - } else { - this.stdout.write('\b'); - } -}; - -// Print text to output stream -Interface.prototype.print = function(text, oneline) { - if (this.killed) return; - this.clearline(); - - this.stdout.write(typeof text === 'string' ? text : util.inspect(text)); - - if (oneline !== true) { - this.stdout.write('\n'); - } -}; - -// Format and print text from child process -Interface.prototype.childPrint = function(text) { - this.print(text.toString().split(/\r\n|\r|\n/g).filter(function(chunk) { - return chunk; - }).map(function(chunk) { - return '< ' + chunk; - }).join('\n')); - this.repl.displayPrompt(true); -}; - -// Errors formatting -Interface.prototype.error = function(text) { - this.print(text); - this.resume(); -}; - - -// Debugger's `break` event handler -Interface.prototype.handleBreak = function(r) { - var self = this; - - this.pause(); - - // Save execution context's data - this.client.currentSourceLine = r.sourceLine; - this.client.currentSourceLineText = r.sourceLineText; - this.client.currentSourceColumn = r.sourceColumn; - this.client.currentFrame = 0; - this.client.currentScript = r.script && r.script.name; - - // Print break data - this.print(SourceInfo(r)); - - // Show watchers' values - this.watchers(true, function(err) { - if (err) return self.error(err); - - // And list source - self.list(2); - - self.resume(true); - }); -}; - - -// Internal method for checking connection state -Interface.prototype.requireConnection = function() { - if (!this.client) { - this.error('App isn\'t running... Try `run` instead'); - return false; - } - return true; -}; - - -// Evals - -// Used for debugger's commands evaluation and execution -Interface.prototype.controlEval = function(code, context, filename, callback) { - try { - // Repeat last command if empty line are going to be evaluated - if (code === '\n') { - code = lastCommand; - } else { - lastCommand = code; - } - - // exec process.title => exec("process.title"); - var match = code.match(/^\s*exec\s+([^\n]*)/); - if (match) { - code = 'exec(' + JSON.stringify(match[1]) + ')'; - } - - var result = vm.runInContext(code, context, filename); - - // Repl should not ask for next command - // if current one was asynchronous. - if (this.paused === 0) return callback(null, result); - - // Add a callback for asynchronous command - // (it will be automatically invoked by .resume() method - this.waiting = function() { - callback(null, result); - }; - } catch (e) { - callback(e); - } -}; - -// Used for debugger's remote evaluation (`repl`) commands -Interface.prototype.debugEval = function(code, context, filename, callback) { - if (!this.requireConnection()) return; - - const self = this; - const client = this.client; - - // Repl asked for scope variables - if (code === '.scope') { - client.reqScopes(callback); - return; - } - - var frame = client.currentFrame === NO_FRAME ? frame : undefined; - - self.pause(); - - // Request remote evaluation globally or in current frame - client.reqFrameEval(code, frame, function(err, res) { - if (err) { - callback(err); - self.resume(true); - return; - } - - // Request object by handles (and it's sub-properties) - client.mirrorObject(res, 3, function(err, mirror) { - callback(null, mirror); - self.resume(true); - }); - }); -}; - - -// Utils - -// Adds spaces and prefix to number -// maxN is a maximum number we should have space for -function leftPad(n, prefix, maxN) { - const s = n.toString(); - const nchars = Math.max(2, String(maxN).length) + 1; - const nspaces = nchars - s.length - 1; - - return prefix + ' '.repeat(nspaces) + s; -} - - -// Commands - - -// Print help message -Interface.prototype.help = function() { - this.print(helpMessage); -}; - - -// Run script -Interface.prototype.run = function() { - var callback = arguments[0]; - - if (this.child) { - this.error('App is already running... Try `restart` instead'); - callback && callback(true); - } else { - this.trySpawn(callback); - } -}; - - -// Restart script -Interface.prototype.restart = function() { - if (!this.requireConnection()) return; - - var self = this; - - self.pause(); - self.killChild(); - - // XXX need to wait a little bit for the restart to work? - setTimeout(function() { - self.trySpawn(); - self.resume(); - }, 1000); -}; - - -// Print version -Interface.prototype.version = function() { - if (!this.requireConnection()) return; - - var self = this; - - this.pause(); - this.client.reqVersion(function(err, v) { - if (err) { - self.error(err); - } else { - self.print(v); - } - self.resume(); - }); -}; - -// List source code -Interface.prototype.list = function(delta) { - if (!this.requireConnection()) return; - - delta || (delta = 5); - - const self = this; - const client = this.client; - const from = client.currentSourceLine - delta + 1; - const to = client.currentSourceLine + delta + 1; - - self.pause(); - client.reqSource(from, to, function(err, res) { - if (err || !res) { - self.error('You can\'t list source code right now'); - self.resume(); - return; - } - - var lines = res.source.split('\n'); - for (var i = 0; i < lines.length; i++) { - var lineno = res.fromLine + i + 1; - if (lineno < from || lineno > to) continue; - - const current = lineno === 1 + client.currentSourceLine; - const breakpoint = client.breakpoints.some(function(bp) { - return (bp.scriptReq === client.currentScript || - bp.script === client.currentScript) && - bp.line === lineno; - }); - - if (lineno === 1) { - // The first line needs to have the module wrapper filtered out of - // it. - var wrapper = Module.wrapper[0]; - lines[i] = lines[i].slice(wrapper.length); - - client.currentSourceColumn -= wrapper.length; - } - - // Highlight executing statement - var line; - if (current) { - line = SourceUnderline(lines[i], - client.currentSourceColumn, - self.repl); - } else { - line = lines[i]; - } - - var prefixChar = ' '; - if (current) { - prefixChar = '>'; - } else if (breakpoint) { - prefixChar = '*'; - } - - self.print(leftPad(lineno, prefixChar, to) + ' ' + line); - } - self.resume(); - }); -}; - -// Print backtrace -Interface.prototype.backtrace = function() { - if (!this.requireConnection()) return; - - const self = this; - const client = this.client; - - self.pause(); - client.fullTrace(function(err, bt) { - if (err) { - self.error('Can\'t request backtrace now'); - self.resume(); - return; - } - - if (bt.totalFrames === 0) { - self.print('(empty stack)'); - } else { - const trace = []; - const firstFrameNative = bt.frames[0].script.isNative; - - for (var i = 0; i < bt.frames.length; i++) { - var frame = bt.frames[i]; - if (!firstFrameNative && frame.script.isNative) break; - - var text = '#' + i + ' '; - if (frame.func.inferredName && frame.func.inferredName.length > 0) { - text += frame.func.inferredName + ' '; - } - text += path.basename(frame.script.name) + ':'; - text += (frame.line + 1) + ':' + (frame.column + 1); - - trace.push(text); - } - - self.print(trace.join('\n')); - } - - self.resume(); - }); -}; - - -// First argument tells if it should display internal node scripts or not -// (available only for internal debugger's functions) -Interface.prototype.scripts = function() { - if (!this.requireConnection()) return; - - const client = this.client; - const displayNatives = arguments[0] || false; - const scripts = []; - - this.pause(); - for (var id in client.scripts) { - var script = client.scripts[id]; - if (script !== null && typeof script === 'object' && script.name) { - if (displayNatives || - script.name === client.currentScript || - !script.isNative) { - scripts.push( - (script.name === client.currentScript ? '* ' : ' ') + - id + ': ' + - path.basename(script.name) - ); - } - } - } - this.print(scripts.join('\n')); - this.resume(); -}; - - -// Continue execution of script -Interface.prototype.cont = function() { - if (!this.requireConnection()) return; - this.pause(); - - var self = this; - this.client.reqContinue(function(err) { - if (err) self.error(err); - self.resume(); - }); -}; - - -// Step commands generator -Interface.stepGenerator = function(type, count) { - return function() { - if (!this.requireConnection()) return; - - var self = this; - - self.pause(); - self.client.step(type, count, function(err, res) { - if (err) self.error(err); - self.resume(); - }); - }; -}; - - -// Jump to next command -Interface.prototype.next = Interface.stepGenerator('next', 1); - - -// Step in -Interface.prototype.step = Interface.stepGenerator('in', 1); - - -// Step out -Interface.prototype.out = Interface.stepGenerator('out', 1); - - -// Watch -Interface.prototype.watch = function(expr) { - this._watchers.push(expr); -}; - -// Unwatch -Interface.prototype.unwatch = function(expr) { - var index = this._watchers.indexOf(expr); - - // Unwatch by expression - // or - // Unwatch by watcher number - this._watchers.splice(index !== -1 ? index : +expr, 1); -}; - -// List watchers -Interface.prototype.watchers = function() { - var self = this; - var verbose = arguments[0] || false; - var callback = arguments[1] || function() {}; - var waiting = this._watchers.length; - var values = []; - - this.pause(); - - if (!waiting) { - this.resume(); - - return callback(); - } - - this._watchers.forEach(function(watcher, i) { - self.debugEval(watcher, null, null, function(err, value) { - values[i] = err ? '' : value; - wait(); - }); - }); - - function wait() { - if (--waiting === 0) { - if (verbose) self.print('Watchers:'); - - self._watchers.forEach(function(watcher, i) { - self.print(leftPad(i, ' ', self._watchers.length - 1) + - ': ' + watcher + ' = ' + - JSON.stringify(values[i])); - }); - - if (verbose) self.print(''); - - self.resume(); - - callback(null); - } - } -}; - -// Break on exception -Interface.prototype.breakOnException = function breakOnException() { - if (!this.requireConnection()) return; - - var self = this; - - // Break on exceptions - this.pause(); - this.client.reqSetExceptionBreak('all', function(err, res) { - self.resume(); - }); -}; - -// Add breakpoint -Interface.prototype.setBreakpoint = function(script, line, - condition, silent) { - if (!this.requireConnection()) return; - - const self = this; - var scriptId; - var ambiguous; - - // setBreakpoint() should insert breakpoint on current line - if (script === undefined) { - script = this.client.currentScript; - line = this.client.currentSourceLine + 1; - } - - // setBreakpoint(line-number) should insert breakpoint in current script - if (line === undefined && typeof script === 'number') { - line = script; - script = this.client.currentScript; - } - - if (script === undefined) { - this.print('Cannot determine the current script, ' + - 'make sure the debugged process is paused.'); - return; - } - - let req; - if (script.endsWith('()')) { - // setBreakpoint('functionname()'); - req = { - type: 'function', - target: script.replace(/\(\)$/, ''), - condition: condition - }; - } else { - // setBreakpoint('scriptname') - // eslint-disable-next-line eqeqeq - if (script != +script && !this.client.scripts[script]) { - var scripts = this.client.scripts; - for (var id in scripts) { - if (scripts[id] && - scripts[id].name && - scripts[id].name.indexOf(script) !== -1) { - if (scriptId) { - ambiguous = true; - } - scriptId = id; - } - } - } else { - scriptId = script; - } - - if (ambiguous) return this.error('Script name is ambiguous'); - if (line <= 0) return this.error('Line should be a positive value'); - - if (scriptId) { - req = { - type: 'scriptId', - target: scriptId, - line: line - 1, - condition: condition - }; - } else { - this.print('Warning: script \'' + script + '\' was not loaded yet.'); - var escapedPath = script.replace(/([/\\.?*()^${}|[\]])/g, '\\$1'); - var scriptPathRegex = '^(.*[\\/\\\\])?' + escapedPath + '$'; - req = { - type: 'scriptRegExp', - target: scriptPathRegex, - line: line - 1, - condition: condition - }; - } - } - - self.pause(); - self.client.setBreakpoint(req, function(err, res) { - if (err) { - if (!silent) { - self.error(err); - } - } else { - if (!silent) { - self.list(5); - } - - // Try load scriptId and line from response - if (!scriptId) { - scriptId = res.script_id; - line = res.line + 1; - } - - // Remember this breakpoint even if scriptId is not resolved yet - self.client.breakpoints.push({ - id: res.breakpoint, - scriptId: scriptId, - script: (self.client.scripts[scriptId] || {}).name, - line: line, - condition: condition, - scriptReq: script - }); - } - self.resume(); - }); -}; - -// Clear breakpoint -Interface.prototype.clearBreakpoint = function(script, line) { - if (!this.requireConnection()) return; - - var ambiguous; - var breakpoint; - var scriptId; - var index; - - this.client.breakpoints.some(function(bp, i) { - if (bp.scriptId === script || - bp.scriptReq === script || - (bp.script && bp.script.indexOf(script) !== -1)) { - if (index !== undefined) { - ambiguous = true; - } - scriptId = script; - if (bp.line === line) { - index = i; - breakpoint = bp.id; - return true; - } - } - }); - - if (!scriptId && !this.client.scripts[script]) { - var scripts = this.client.scripts; - for (var id in scripts) { - if (scripts[id] && - scripts[id].name && - scripts[id].name.indexOf(script) !== -1) { - if (scriptId) { - ambiguous = true; - } - scriptId = id; - } - } - } - - if (ambiguous) return this.error('Script name is ambiguous'); - - if (scriptId === undefined) { - return this.error('Script ' + script + ' not found'); - } - - if (breakpoint === undefined) { - return this.error('Breakpoint not found on line ' + line); - } - - var self = this; - const req = {breakpoint}; - - self.pause(); - self.client.clearBreakpoint(req, function(err, res) { - if (err) { - self.error(err); - } else { - self.client.breakpoints.splice(index, 1); - self.list(5); - } - self.resume(); - }); -}; - - -// Show breakpoints -Interface.prototype.breakpoints = function() { - if (!this.requireConnection()) return; - - this.pause(); - var self = this; - this.client.listbreakpoints(function(err, res) { - if (err) { - self.error(err); - } else { - self.print(res); - self.resume(); - } - }); -}; - - -// Pause child process -Interface.prototype.pause_ = function() { - if (!this.requireConnection()) return; - - const self = this; - const cmd = 'process._debugPause();'; - - this.pause(); - this.client.reqFrameEval(cmd, NO_FRAME, function(err, res) { - if (err) { - self.error(err); - } else { - self.resume(); - } - }); -}; - - -// execute expression -Interface.prototype.exec = function(code) { - this.debugEval(code, null, null, (err, result) => { - if (err) { - this.error(err); - } else { - this.print(util.inspect(result, {colors: true})); - } - }); -}; - - -// Kill child process -Interface.prototype.kill = function() { - if (!this.child) return; - this.killChild(); -}; - - -// Activate debug repl -Interface.prototype.repl = function() { - if (!this.requireConnection()) return; - - var self = this; - - self.print('Press Ctrl + C to leave debug repl'); - - // Don't display any default messages - var listeners = this.repl.rli.listeners('SIGINT').slice(0); - this.repl.rli.removeAllListeners('SIGINT'); - - function exitDebugRepl() { - // Restore all listeners - process.nextTick(function() { - listeners.forEach(function(listener) { - self.repl.rli.on('SIGINT', listener); - }); - }); - - // Exit debug repl - self.exitRepl(); - - self.repl.rli.removeListener('SIGINT', exitDebugRepl); - self.repl.removeListener('exit', exitDebugRepl); - } - - // Exit debug repl on SIGINT - this.repl.rli.on('SIGINT', exitDebugRepl); - - // Exit debug repl on repl exit - this.repl.on('exit', exitDebugRepl); - - // Set new - this.repl.eval = (code, ctx, file, cb) => - this.debugEval(code, ctx, file, cb); - this.repl.context = {}; - - // Swap history - this.history.control = this.repl.rli.history; - this.repl.rli.history = this.history.debug; - - this.repl.rli.setPrompt('> '); - this.repl.displayPrompt(); -}; - - -// Exit debug repl -Interface.prototype.exitRepl = function() { - // Restore eval - this.repl.eval = (code, ctx, file, cb) => - this.controlEval(code, ctx, file, cb); - - // Swap history - this.history.debug = this.repl.rli.history; - this.repl.rli.history = this.history.control; - - this.repl.context = this.context; - this.repl.rli.setPrompt('debug> '); - this.repl.displayPrompt(); -}; - - -// Quit -Interface.prototype.quit = function() { - this.killChild(); - process.exit(0); -}; - - -// Kills child process -Interface.prototype.killChild = function() { - if (this.child) { - this.child.kill(); - this.child = null; - } - - if (this.client) { - // Save breakpoints - this.breakpoints = this.client.breakpoints; - - this.client.destroy(); - this.client = null; - } -}; - - -// Spawns child process (and restores breakpoints) -Interface.prototype.trySpawn = function(cb) { - const self = this; - const breakpoints = this.breakpoints || []; - var port = exports.port; - var host = '127.0.0.1'; - var childArgs = this.args; - - this.killChild(); - assert(!this.child); - - var isRemote = false; - if (this.args.length === 2) { - const match = this.args[1].match(/^([^:]+):(\d+)$/); - - if (match) { - // Connecting to remote debugger - // `node debug localhost:5858` - host = match[1]; - port = parseInt(match[2], 10); - isRemote = true; - } - } else if (this.args.length === 3) { - // `node debug -p pid` - if (this.args[1] === '-p' && /^\d+$/.test(this.args[2])) { - const pid = parseInt(this.args[2], 10); - try { - process._debugProcess(pid); - } catch (e) { - if (e.code === 'ESRCH') { - error(`Target process: ${pid} doesn't exist.`); - process.exit(1); - } - throw e; - } - isRemote = true; - } else { - const match = this.args[1].match(/^--port=(\d+)$/); - if (match) { - // Start debugger on custom port - // `node debug --port=5858 app.js` - port = parseInt(match[1], 10); - childArgs = ['--debug-brk=' + port].concat(this.args.slice(2)); - } - } - } - - if (!isRemote) { - // pipe stream into debugger - this.child = spawn(process.execPath, childArgs); - - this.child.stdout.on('data', (text) => this.childPrint(text)); - this.child.stderr.on('data', (text) => this.childPrint(text)); - } - - this.pause(); - - const client = self.client = new Client(); - var connectionAttempts = 0; - - client.once('ready', function() { - self.stdout.write(' ok\n'); - - // Restore breakpoints - breakpoints.forEach(function(bp) { - self.print('Restoring breakpoint ' + bp.scriptReq + ':' + bp.line); - self.setBreakpoint(bp.scriptReq, bp.line, bp.condition, true); - }); - - client.on('close', function() { - self.pause(); - self.print('program terminated'); - self.resume(); - self.client = null; - self.killChild(); - }); - - if (cb) cb(); - self.resume(); - }); - - client.on('unhandledResponse', function(res) { - self.pause(); - self.print('\nunhandled res:' + JSON.stringify(res)); - self.resume(); - }); - - client.on('break', function(res) { - self.handleBreak(res.body); - }); - - client.on('exception', function(res) { - self.handleBreak(res.body); - }); - - client.on('error', connectError); - function connectError() { - // If it's failed to connect 10 times then print failed message - if (connectionAttempts >= 10) { - error(' failed to connect, please retry'); - process.exit(1); - } - setTimeout(attemptConnect, 500); - } - - function attemptConnect() { - ++connectionAttempts; - self.stdout.write('.'); - client.connect(port, host); - } - - if (isRemote) { - self.print('connecting to ' + host + ':' + port + ' ..', true); - attemptConnect(); - } else { - this.child.stderr.once('data', function() { - self.print('connecting to ' + host + ':' + port + ' ..', true); - setImmediate(attemptConnect); - }); - } -}; diff --git a/lib/internal/bootstrap_node.js b/lib/internal/bootstrap_node.js index 6380506b72ee1b..2c338113de77ea 100644 --- a/lib/internal/bootstrap_node.js +++ b/lib/internal/bootstrap_node.js @@ -122,9 +122,7 @@ const internalModule = NativeModule.require('internal/module'); internalModule.addBuiltinLibsToObject(global); - run(() => { - evalScript('[eval]'); - }); + evalScript('[eval]'); } else if (process.argv[1]) { // make process.argv[1] into a full path const path = NativeModule.require('path'); @@ -143,7 +141,7 @@ } preloadModules(); - run(Module.runMain); + Module.runMain(); } else { preloadModules(); // If -i or --interactive were passed, or stdin is a TTY. @@ -417,33 +415,6 @@ } } - function isDebugBreak() { - return process.execArgv.some((arg) => /^--debug-brk(=[0-9]+)?$/.test(arg)); - } - - function run(entryFunction) { - if (process._debugWaitConnect && isDebugBreak()) { - - // XXX Fix this terrible hack! - // - // Give the client program a few ticks to connect. - // Otherwise, there's a race condition where `node debug foo.js` - // will not be able to connect in time to catch the first - // breakpoint message on line 1. - // - // A better fix would be to somehow get a message from the - // V8 debug object about a connection, and runMain when - // that occurs. --isaacs - - const debugTimeout = +process.env.NODE_DEBUG_TIMEOUT || 50; - setTimeout(entryFunction, debugTimeout); - - } else { - // Main entry point into most programs: - entryFunction(); - } - } - function checkScriptSyntax(source, filename) { const Module = NativeModule.require('module'); const vm = NativeModule.require('vm'); diff --git a/node.gyp b/node.gyp index db0531c0694d5a..8b1bb0c71fef1d 100644 --- a/node.gyp +++ b/node.gyp @@ -23,7 +23,6 @@ 'library_files': [ 'lib/internal/bootstrap_node.js', 'lib/_debug_agent.js', - 'lib/_debugger.js', 'lib/assert.js', 'lib/buffer.js', 'lib/child_process.js', diff --git a/test/debugger/test-debug-break-on-uncaught.js b/test/debugger/test-debug-break-on-uncaught.js deleted file mode 100644 index 4c8fb5b3fc27c5..00000000000000 --- a/test/debugger/test-debug-break-on-uncaught.js +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; -const common = require('../common'); -const path = require('path'); -const assert = require('assert'); -const spawn = require('child_process').spawn; -const debug = require('_debugger'); - -const scenarios = []; - -addScenario('global.js', 2); -addScenario('timeout.js', 2); - -run(); - -/***************** IMPLEMENTATION *****************/ - -function addScenario(scriptName, throwsOnLine) { - scenarios.push( - runScenario.bind(null, scriptName, throwsOnLine, run) - ); -} - -function run() { - const next = scenarios.shift(); - if (next) next(); -} - -function runScenario(scriptName, throwsOnLine, next) { - let asserted = false; - const port = common.PORT; - - const testScript = path.join( - common.fixturesDir, - 'uncaught-exceptions', - scriptName - ); - - const child = spawn(process.execPath, [ '--debug-brk=' + port, testScript ]); - child.on('close', function() { - assert(asserted, 'debugger did not pause on exception'); - if (next) next(); - }); - - const exceptions = []; - - let stderr = ''; - - function stderrListener(data) { - stderr += data; - if (stderr.includes('Debugger listening on ')) { - setTimeout(setupClient.bind(null, runTest), 200); - child.stderr.removeListener('data', stderrListener); - } - } - - child.stderr.setEncoding('utf8'); - child.stderr.on('data', stderrListener); - - function setupClient(callback) { - const client = new debug.Client(); - - client.once('ready', callback.bind(null, client)); - - client.on('unhandledResponse', function(body) { - console.error('unhandled response: %j', body); - }); - - client.on('error', function(err) { - if (asserted) return; - assert.ifError(err); - }); - - client.connect(port); - } - - let interval; - function runTest(client) { - client.req( - { - command: 'setexceptionbreak', - arguments: { - type: 'uncaught', - enabled: true - } - }, - function(error) { - assert.ifError(error); - - client.on('exception', function(event) { - exceptions.push(event.body); - }); - - client.reqContinue(function(error) { - assert.ifError(error); - interval = setInterval(assertHasPaused.bind(null, client), 10); - }); - } - ); - } - - function assertHasPaused(client) { - if (!exceptions.length) return; - - assert.strictEqual(exceptions.length, 1, - 'debugger did not pause on exception'); - assert.strictEqual(exceptions[0].uncaught, true); - assert.strictEqual(exceptions[0].script.name, testScript); - assert.strictEqual(exceptions[0].sourceLine + 1, throwsOnLine); - asserted = true; - client.reqContinue(assert.ifError); - clearInterval(interval); - } -} diff --git a/test/debugger/test-debugger-client.js b/test/debugger/test-debugger-client.js deleted file mode 100644 index fe28d353c13790..00000000000000 --- a/test/debugger/test-debugger-client.js +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; -const common = require('../common'); -const assert = require('assert'); -const debug = require('_debugger'); - -process.env.NODE_DEBUGGER_TIMEOUT = 2000; -const debugPort = common.PORT; -debug.port = debugPort; -const spawn = require('child_process').spawn; - -setTimeout(function() { - if (nodeProcess) nodeProcess.kill('SIGTERM'); - throw new Error('timeout'); -}, 10000).unref(); - - -let resCount = 0; -const p = new debug.Protocol(); -p.onResponse = function() { - resCount++; -}; - -p.execute('Type: connect\r\n' + - 'V8-Version: 3.0.4.1\r\n' + - 'Protocol-Version: 1\r\n' + - 'Embedding-Host: node v0.3.3-pre\r\n' + - 'Content-Length: 0\r\n\r\n'); -assert.strictEqual(resCount, 1); - -// Make sure split messages go in. - -const parts = []; -parts.push('Content-Length: 336\r\n'); -assert.strictEqual(parts[0].length, 21); -parts.push('\r\n'); -assert.strictEqual(parts[1].length, 2); -let bodyLength = 0; - -parts.push('{"seq":12,"type":"event","event":"break","body":' + - '{"invocationText":"#'); -assert.strictEqual(parts[2].length, 78); -bodyLength += parts[2].length; - -parts.push('.[anonymous](req=#, ' + - 'res=#)","sourceLine"'); -assert.strictEqual(parts[3].length, 78); -bodyLength += parts[3].length; - -parts.push(':45,"sourceColumn":4,"sourceLineText":" debugger;",' + - '"script":{"id":24,"name":"/home/ryan/projects/node/' + - 'benchmark/http_simple.js","lineOffset":0,"columnOffset":0,' + - '"lineCount":98}}}'); -assert.strictEqual(parts[4].length, 180); -bodyLength += parts[4].length; - -assert.strictEqual(bodyLength, 336); - -for (let i = 0; i < parts.length; i++) { - p.execute(parts[i]); -} -assert.strictEqual(resCount, 2); - - -// Make sure that if we get backed up, we still manage to get all the -// messages -const d = 'Content-Length: 466\r\n\r\n' + - '{"seq":10,"type":"event","event":"afterCompile","success":true,' + - '"body":{"script":{"handle":1,"type":"script","name":"dns.js",' + - '"id":34,"lineOffset":0,"columnOffset":0,"lineCount":241,' + - '"sourceStart":"(function(module, exports, require) {' + - 'var dns = process.binding(\'cares\')' + - ';\\nvar ne","sourceLength":6137,"scriptType":2,"compilationType"' + - ':0,"context":{"ref":0},"text":"dns.js (lines: 241)"}},"refs":' + - '[{"handle":0' + - ',"type":"context","text":"#"}],"running":true}' + - '\r\n\r\nContent-Length: 119\r\n\r\n' + - '{"seq":11,"type":"event","event":"scriptCollected","success":true' + - ',"body":{"script":{"id":26}},"refs":[],"running":true}'; -p.execute(d); -assert.strictEqual(resCount, 4); - -let expectedConnections = 0; -const tests = []; -function addTest(cb) { - expectedConnections++; - tests.push(cb); -} - -addTest(function(client, done) { - console.error('requesting version'); - client.reqVersion(function(err, v) { - assert.ifError(err); - console.log('version: %s', v); - assert.strictEqual(process.versions.v8, v); - done(); - }); -}); - -addTest(function(client, done) { - console.error('requesting scripts'); - client.reqScripts(function(err) { - assert.ifError(err); - console.error('got %d scripts', Object.keys(client.scripts).length); - - let foundMainScript = false; - for (const k in client.scripts) { - const script = client.scripts[k]; - if (script && script.name === 'bootstrap_node.js') { - foundMainScript = true; - break; - } - } - assert.ok(foundMainScript); - done(); - }); -}); - -addTest(function(client, done) { - console.error('eval 2+2'); - client.reqEval('2+2', function(err, res) { - console.error(res); - assert.ifError(err); - assert.strictEqual(res.text, '4'); - assert.strictEqual(res.value, 4); - done(); - }); -}); - - -let connectCount = 0; -const script = 'setTimeout(function() { console.log("blah"); });' + - 'setInterval(common.noop, 1000000);'; - -let nodeProcess; - -function doTest(cb, done) { - const args = ['--debug=' + debugPort, '-e', script]; - nodeProcess = spawn(process.execPath, args); - - nodeProcess.stdout.once('data', function() { - console.log('>>> new node process: %d', nodeProcess.pid); - let failed = true; - try { - process._debugProcess(nodeProcess.pid); - failed = false; - } finally { - // At least TRY not to leave zombie procs if this fails. - if (failed) - nodeProcess.kill('SIGTERM'); - } - console.log('>>> starting debugger session'); - }); - - let didTryConnect = false; - nodeProcess.stderr.setEncoding('utf8'); - let b = ''; - nodeProcess.stderr.on('data', function(data) { - console.error('got stderr data %j', data); - nodeProcess.stderr.resume(); - b += data; - if (didTryConnect === false && b.match(/Debugger listening on /)) { - didTryConnect = true; - - // The timeout is here to expose a race in the bootstrap process. - // Without the early SIGUSR1 debug handler, it effectively results - // in an infinite ECONNREFUSED loop. - setTimeout(tryConnect, 100); - - function tryConnect() { - // Wait for some data before trying to connect - const c = new debug.Client(); - console.error('>>> connecting...'); - c.connect(debug.port); - c.on('break', function() { - c.reqContinue(common.noop); - }); - c.on('ready', function() { - connectCount++; - console.log('ready!'); - cb(c, function() { - c.end(); - c.on('end', function() { - console.error( - '>>> killing node process %d\n\n', - nodeProcess.pid); - nodeProcess.kill(); - done(); - }); - }); - }); - c.on('error', function(err) { - if (err.code !== 'ECONNREFUSED') throw err; - setTimeout(tryConnect, 10); - }); - } - } - }); -} - - -function run() { - const t = tests[0]; - if (!t) return; - - doTest(t, function() { - tests.shift(); - run(); - }); -} - -run(); - -process.on('exit', function(code) { - if (!code) - assert.strictEqual(connectCount, expectedConnections); -}); diff --git a/test/debugger/test-debugger-remote.js b/test/debugger/test-debugger-remote.js deleted file mode 100644 index a1a95edd6e941a..00000000000000 --- a/test/debugger/test-debugger-remote.js +++ /dev/null @@ -1,61 +0,0 @@ -'use strict'; -const common = require('../common'); -const assert = require('assert'); -const spawn = require('child_process').spawn; -const path = require('path'); - -const PORT = common.PORT; -const scriptToDebug = path.join(common.fixturesDir, 'empty.js'); - -// running with debug agent -const child = spawn(process.execPath, [`--debug-brk=${PORT}`, scriptToDebug]); - -// connect to debug agent -const interfacer = spawn(process.execPath, ['debug', `localhost:${PORT}`]); -interfacer.stdout.setEncoding('utf-8'); - -// fail the test if either of the processes exit normally -const debugBreakExit = common.mustNotCall('child should not exit normally'); -const debugExit = common.mustNotCall('interfacer should not exit normally'); -child.on('exit', debugBreakExit); -interfacer.on('exit', debugExit); - -let buffer = ''; -const expected = [ - `\bconnecting to localhost:${PORT} ... ok`, - '\bbreak in test/fixtures/empty.js:2' -]; -const actual = []; -interfacer.stdout.on('data', function(data) { - data = (buffer + data).split('\n'); - buffer = data.pop(); - data.forEach(function(line) { - interfacer.emit('line', line); - }); -}); - -interfacer.on('line', function(line) { - line = line.replace(/^(debug> *)+/, ''); - if (expected.includes(line)) { - actual.push(line); - } -}); - -// allow time to start up the debugger -setTimeout(function() { - // remove the exit handlers before killing the processes - child.removeListener('exit', debugBreakExit); - interfacer.removeListener('exit', debugExit); - - child.kill(); - interfacer.kill(); -}, common.platformTimeout(2000)); - -process.on('exit', function() { - // additional checks to ensure that both the processes were actually killed - assert(child.killed); - assert(interfacer.killed); - assert.deepStrictEqual(actual, expected); -}); - -interfacer.stderr.pipe(process.stderr); diff --git a/test/fixtures/debug-uncaught-async.js b/test/fixtures/debug-uncaught-async.js deleted file mode 100644 index 275f89525b8ab7..00000000000000 --- a/test/fixtures/debug-uncaught-async.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -require('../common'); -const assert = require('assert'); -const debug = require('_debugger'); - -function emit() { - const error = new Error('fhqwhgads'); - process.emit('uncaughtException', error); -} - -assert.doesNotThrow(emit); - -// Send debug.start() an argv array of length 1 to avoid code that exits -// if argv is empty. -debug.start(['sterrance']); - -setImmediate(emit); diff --git a/test/fixtures/debug-uncaught.js b/test/fixtures/debug-uncaught.js deleted file mode 100644 index f09d62f3580f32..00000000000000 --- a/test/fixtures/debug-uncaught.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -require('../common'); -const assert = require('assert'); -const debug = require('_debugger'); - -function emit() { - const error = new Error('sterrance'); - process.emit('uncaughtException', error); -} - -assert.doesNotThrow(emit); - -debug.start(['fhqwhgads']); - -emit(); diff --git a/test/known_issues/test-cluster-disconnect-handles.js b/test/known_issues/test-cluster-disconnect-handles.js deleted file mode 100644 index 4b481f0a7b1751..00000000000000 --- a/test/known_issues/test-cluster-disconnect-handles.js +++ /dev/null @@ -1,99 +0,0 @@ -/* eslint-disable no-debugger */ -// Flags: --expose_internals -'use strict'; - -const common = require('../common'); -const assert = require('assert'); -const cluster = require('cluster'); -const net = require('net'); - -const Protocol = require('_debugger').Protocol; - -if (common.isWindows) { - common.skip('SCHED_RR not reliable on Windows'); - return; -} - -cluster.schedulingPolicy = cluster.SCHED_RR; - -// Worker sends back a "I'm here" message, then immediately suspends -// inside the debugger. The master connects to the debug agent first, -// connects to the TCP server second, then disconnects the worker and -// unsuspends it again. The ultimate goal of this tortured exercise -// is to make sure the connection is still sitting in the master's -// pending handle queue. -if (cluster.isMaster) { - let isKilling = false; - const handles = require('internal/cluster/utils').handles; - const address = common.hasIPv6 ? '[::1]' : common.localhostIPv4; - cluster.setupMaster({ execArgv: [`--debug=${address}:${common.PORT}`] }); - const worker = cluster.fork(); - worker.once('exit', common.mustCall((code, signal) => { - assert.strictEqual(code, 0, 'worker did not exit normally'); - assert.strictEqual(signal, null, 'worker did not exit normally'); - })); - worker.on('message', common.mustCall((message) => { - assert.strictEqual(Array.isArray(message), true); - assert.strictEqual(message[0], 'listening'); - let continueRecv = false; - const address = message[1]; - const host = address.address; - const debugClient = net.connect({ host, port: common.PORT }); - const protocol = new Protocol(); - debugClient.setEncoding('utf8'); - debugClient.on('data', (data) => protocol.execute(data)); - debugClient.once('connect', common.mustCall(() => { - protocol.onResponse = common.mustCall((res) => { - protocol.onResponse = (res) => { - // It can happen that the first continue was sent before the break - // event was received. If that's the case, send also a continue from - // here so the worker exits - if (res.body.command === 'continue') { - continueRecv = true; - } else if (res.body.event === 'break' && continueRecv) { - const req = protocol.serialize({ command: 'continue' }); - debugClient.write(req); - } - }; - const conn = net.connect({ host, port: address.port }); - conn.once('connect', common.mustCall(() => { - conn.destroy(); - assert.notDeepStrictEqual(handles, {}); - worker.disconnect(); - assert.deepStrictEqual(handles, {}); - // Always send the continue, as the break event might have already - // been received. - const req = protocol.serialize({ command: 'continue' }); - debugClient.write(req); - })); - }); - })); - })); - process.on('exit', () => assert.deepStrictEqual(handles, {})); - process.on('uncaughtException', function(ex) { - // Make sure we clean up so as not to leave a stray worker process running - // if we encounter a connection or other error - if (!worker.isDead()) { - if (!isKilling) { - isKilling = true; - worker.once('exit', function() { - throw ex; - }); - worker.process.kill(); - } - return; - } - throw ex; - }); -} else { - const server = net.createServer((socket) => socket.pipe(socket)); - const cb = () => { - process.send(['listening', server.address()]); - debugger; - }; - if (common.hasIPv6) - server.listen(0, '::1', cb); - else - server.listen(0, common.localhostIPv4, cb); - process.on('disconnect', process.exit); -} diff --git a/test/message/core_line_numbers.out b/test/message/core_line_numbers.out index 0dd38a3996d8e9..1049fdc3e935df 100644 --- a/test/message/core_line_numbers.out +++ b/test/message/core_line_numbers.out @@ -11,5 +11,5 @@ RangeError: Invalid input at Module.load (module.js:*:*) at tryModuleLoad (module.js:*:*) at Function.Module._load (module.js:*:*) - at Module.runMain (module.js:*:*) - at run (bootstrap_node.js:*:*) + at Function.Module.runMain (module.js:*:*) + at startup (bootstrap_node.js:*:*) diff --git a/test/message/error_exit.out b/test/message/error_exit.out index e2a29ab42dbbd2..c1b778d6e90101 100644 --- a/test/message/error_exit.out +++ b/test/message/error_exit.out @@ -10,7 +10,6 @@ AssertionError: 1 === 2 at Module.load (module.js:*:*) at tryModuleLoad (module.js:*:*) at Function.Module._load (module.js:*:*) - at Module.runMain (module.js:*:*) - at run (bootstrap_node.js:*:*) + at Function.Module.runMain (module.js:*:*) at startup (bootstrap_node.js:*:*) at bootstrap_node.js:*:* diff --git a/test/message/eval_messages.out b/test/message/eval_messages.out index 340e760dc696b7..aa7e51dc5d1584 100644 --- a/test/message/eval_messages.out +++ b/test/message/eval_messages.out @@ -8,8 +8,6 @@ SyntaxError: Strict mode code may not include a with statement at Object. ([eval]-wrapper:*:*) at Module._compile (module.js:*:*) at evalScript (bootstrap_node.js:*:*) - at run (bootstrap_node.js:*:*) - at run (bootstrap_node.js:*:*) at startup (bootstrap_node.js:*:*) at bootstrap_node.js:*:* 42 @@ -25,8 +23,6 @@ Error: hello at Object. ([eval]-wrapper:*:*) at Module._compile (module.js:*:*) at evalScript (bootstrap_node.js:*:*) - at run (bootstrap_node.js:*:*) - at run (bootstrap_node.js:*:*) at startup (bootstrap_node.js:*:*) at bootstrap_node.js:*:* @@ -41,8 +37,6 @@ Error: hello at Object. ([eval]-wrapper:*:*) at Module._compile (module.js:*:*) at evalScript (bootstrap_node.js:*:*) - at run (bootstrap_node.js:*:*) - at run (bootstrap_node.js:*:*) at startup (bootstrap_node.js:*:*) at bootstrap_node.js:*:* 100 @@ -57,8 +51,6 @@ ReferenceError: y is not defined at Object. ([eval]-wrapper:*:*) at Module._compile (module.js:*:*) at evalScript (bootstrap_node.js:*:*) - at run (bootstrap_node.js:*:*) - at run (bootstrap_node.js:*:*) at startup (bootstrap_node.js:*:*) at bootstrap_node.js:*:* diff --git a/test/message/nexttick_throw.out b/test/message/nexttick_throw.out index 9f32dcb6367ffd..1b72ea2d3cfb69 100644 --- a/test/message/nexttick_throw.out +++ b/test/message/nexttick_throw.out @@ -6,7 +6,6 @@ ReferenceError: undefined_reference_error_maker is not defined at *test*message*nexttick_throw.js:*:* at _combinedTickCallback (internal/process/next_tick.js:*:*) at process._tickCallback (internal/process/next_tick.js:*:*) - at Module.runMain (module.js:*:*) - at run (bootstrap_node.js:*:*) + at Function.Module.runMain (module.js:*:*) at startup (bootstrap_node.js:*:*) at bootstrap_node.js:*:* diff --git a/test/message/unhandled_promise_trace_warnings.out b/test/message/unhandled_promise_trace_warnings.out index 603333e64a946f..4372efdeedb1ae 100644 --- a/test/message/unhandled_promise_trace_warnings.out +++ b/test/message/unhandled_promise_trace_warnings.out @@ -8,7 +8,6 @@ at * at * at * - at * (node:*) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. at * at * @@ -18,7 +17,6 @@ at * at * at * - at * (node:*) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1) at getAsynchronousRejectionWarningObject (internal/process/promises.js:*) at rejectionHandled (internal/process/promises.js:*) diff --git a/test/message/vm_display_runtime_error.out b/test/message/vm_display_runtime_error.out index d5cf1d3ee50dbb..9035c1783c389a 100644 --- a/test/message/vm_display_runtime_error.out +++ b/test/message/vm_display_runtime_error.out @@ -13,4 +13,4 @@ Error: boo! at Module.load (module.js:*) at tryModuleLoad (module.js:*:*) at Function.Module._load (module.js:*) - at Module.runMain (module.js:*) + at Function.Module.runMain (module.js:*) diff --git a/test/message/vm_display_syntax_error.out b/test/message/vm_display_syntax_error.out index 9ec62eacb895f0..c64f508c74db1b 100644 --- a/test/message/vm_display_syntax_error.out +++ b/test/message/vm_display_syntax_error.out @@ -11,8 +11,8 @@ SyntaxError: Unexpected number at Module.load (module.js:*) at tryModuleLoad (module.js:*:*) at Function.Module._load (module.js:*) - at Module.runMain (module.js:*) - at run (bootstrap_node.js:*) + at Function.Module.runMain (module.js:*) + at startup (bootstrap_node.js:*:*) test.vm:1 var 5; ^ @@ -25,5 +25,5 @@ SyntaxError: Unexpected number at Module.load (module.js:*) at tryModuleLoad (module.js:*:*) at Function.Module._load (module.js:*) - at Module.runMain (module.js:*) - at run (bootstrap_node.js:*) + at Function.Module.runMain (module.js:*) + at startup (bootstrap_node.js:*:*) diff --git a/test/message/vm_dont_display_runtime_error.out b/test/message/vm_dont_display_runtime_error.out index a60bde2a8c29ea..af634c6dcc4ab1 100644 --- a/test/message/vm_dont_display_runtime_error.out +++ b/test/message/vm_dont_display_runtime_error.out @@ -14,4 +14,4 @@ Error: boo! at Module.load (module.js:*) at tryModuleLoad (module.js:*:*) at Function.Module._load (module.js:*) - at Module.runMain (module.js:*) + at Function.Module.runMain (module.js:*) diff --git a/test/message/vm_dont_display_syntax_error.out b/test/message/vm_dont_display_syntax_error.out index bc5b180dc1fa2a..eced3a3f626804 100644 --- a/test/message/vm_dont_display_syntax_error.out +++ b/test/message/vm_dont_display_syntax_error.out @@ -13,5 +13,5 @@ SyntaxError: Unexpected number at Module.load (module.js:*) at tryModuleLoad (module.js:*:*) at Function.Module._load (module.js:*) - at Module.runMain (module.js:*) - at run (bootstrap_node.js:*) + at Function.Module.runMain (module.js:*) + at startup (bootstrap_node.js:*:*) diff --git a/test/parallel/test-debug-protocol-execute.js b/test/parallel/test-debug-protocol-execute.js deleted file mode 100644 index 2283a3c54e9034..00000000000000 --- a/test/parallel/test-debug-protocol-execute.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -require('../common'); -const assert = require('assert'); -const debug = require('_debugger'); - -const protocol = new debug.Protocol(); - -assert.strictEqual(protocol.state, 'headers'); - -protocol.execute('Content-Length: 10\r\n\r\nfhqwhgads'); - -assert.strictEqual(protocol.state, 'body'); -assert.strictEqual(protocol.res.body, undefined); - -protocol.state = 'sterrance'; -assert.throws( - () => { protocol.execute('grumblecakes'); }, - /^Error: Unknown state$/ -); diff --git a/test/parallel/test-debug-uncaught-exception-async.js b/test/parallel/test-debug-uncaught-exception-async.js deleted file mode 100644 index 8d0d7957c22e12..00000000000000 --- a/test/parallel/test-debug-uncaught-exception-async.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; -const common = require('../common'); -const assert = require('assert'); -const path = require('path'); -const spawn = require('child_process').spawn; - -const emitUncaught = path.join(common.fixturesDir, 'debug-uncaught-async.js'); -const result = spawn(process.execPath, [emitUncaught], {encoding: 'utf8'}); - -let stderr = ''; -result.stderr.on('data', (data) => { - stderr += data; -}); - -result.on('close', (code) => { - const expectedMessage = - "There was an internal error in Node's debugger. Please report this bug."; - - assert.strictEqual(code, 1); - assert(stderr.includes(expectedMessage)); - assert(stderr.includes('Error: fhqwhgads')); -}); diff --git a/test/parallel/test-debug-uncaught-exception.js b/test/parallel/test-debug-uncaught-exception.js deleted file mode 100644 index 64c98469942dab..00000000000000 --- a/test/parallel/test-debug-uncaught-exception.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict'; -const common = require('../common'); -const assert = require('assert'); -const path = require('path'); -const spawnSync = require('child_process').spawnSync; - -const emitUncaught = path.join(common.fixturesDir, 'debug-uncaught.js'); -const result = spawnSync(process.execPath, [emitUncaught], {encoding: 'utf8'}); - -const expectedMessage = - "There was an internal error in Node's debugger. Please report this bug."; - -assert.strictEqual(result.status, 1); -assert(result.stderr.includes(expectedMessage)); -assert(result.stderr.includes('Error: sterrance')); - -console.log(result.stdout); diff --git a/test/parallel/test-debugger-client-addhandle.js b/test/parallel/test-debugger-client-addhandle.js deleted file mode 100644 index bb953561b945a9..00000000000000 --- a/test/parallel/test-debugger-client-addhandle.js +++ /dev/null @@ -1,44 +0,0 @@ -'use strict'; - -require('../common'); -const assert = require('assert'); -const Client = require('_debugger').Client; - -{ - const client = new Client(); - assert.deepStrictEqual(client.handles, {}); -} - -{ - const client = new Client(); - client._addHandle(null); - assert.deepStrictEqual(client.handles, {}); -} - -{ - const client = new Client(); - client._addHandle('not an object'); - assert.deepStrictEqual(client.handles, {}); -} - -{ - const client = new Client(); - client._addHandle({ handle: 'not a number' }); - assert.deepStrictEqual(client.handles, {}); -} - -{ - const client = new Client(); - const validNoScript = { handle: 6, id: 'foo', type: 'not a script' }; - client._addHandle(validNoScript); - assert.deepStrictEqual(client.handles, { 6: validNoScript }); - assert.deepStrictEqual(client.scripts, {}); -} - -{ - const client = new Client(); - const validWithScript = { handle: 5, id: 'bar', type: 'script' }; - client._addHandle(validWithScript); - assert.deepStrictEqual(client.handles, { 5: validWithScript }); - assert.deepStrictEqual(client.scripts, { bar: validWithScript }); -}