lib,src: remove vm.runInDebugContext()
The V8 API it is based on is deprecated and scheduled for removal later this year. Remove it. PR-URL: https://github.com/nodejs/node/pull/13295 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Robert Jefe Lindstaedt <robert.lindstaedt@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Timothy Gu <timothygu99@gmail.com>
This commit is contained in:
parent
05948d8e4e
commit
6f724e1563
@ -600,10 +600,9 @@ a V8-inspector based CLI debugger available through `node inspect`.
|
|||||||
<a id="DEP0069"></a>
|
<a id="DEP0069"></a>
|
||||||
### DEP0069: vm.runInDebugContext(string)
|
### DEP0069: vm.runInDebugContext(string)
|
||||||
|
|
||||||
Type: Runtime
|
Type: End-of-Life
|
||||||
|
|
||||||
The DebugContext will be removed in V8 soon and will not be available in Node
|
DebugContext has been removed in V8 and is not available in Node 10+.
|
||||||
10+.
|
|
||||||
|
|
||||||
*Note*: DebugContext was an experimental API.
|
*Note*: DebugContext was an experimental API.
|
||||||
|
|
||||||
|
@ -334,36 +334,6 @@ console.log(util.inspect(sandbox));
|
|||||||
// { globalVar: 1024 }
|
// { globalVar: 1024 }
|
||||||
```
|
```
|
||||||
|
|
||||||
## vm.runInDebugContext(code)
|
|
||||||
<!-- YAML
|
|
||||||
added: v0.11.14
|
|
||||||
deprecated: v8.0.0
|
|
||||||
changes:
|
|
||||||
- version: v9.0.0
|
|
||||||
pr-url: https://github.com/nodejs/node/pull/12815
|
|
||||||
description: Calling this function now emits a deprecation warning.
|
|
||||||
-->
|
|
||||||
|
|
||||||
> Stability: 0 - Deprecated. An alternative is in development.
|
|
||||||
|
|
||||||
* `code` {string} The JavaScript code to compile and run.
|
|
||||||
|
|
||||||
The `vm.runInDebugContext()` method compiles and executes `code` inside the V8
|
|
||||||
debug context. The primary use case is to gain access to the V8 `Debug` object:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const vm = require('vm');
|
|
||||||
const Debug = vm.runInDebugContext('Debug');
|
|
||||||
console.log(Debug.findScript(process.emit).name); // 'events.js'
|
|
||||||
console.log(Debug.findScript(process.exit).name); // 'internal/process.js'
|
|
||||||
```
|
|
||||||
|
|
||||||
*Note*: The debug context and object are intrinsically tied to V8's debugger
|
|
||||||
implementation and may change (or even be removed) without prior warning.
|
|
||||||
|
|
||||||
The `Debug` object can also be made available using the V8-specific
|
|
||||||
`--expose_debug_as=` [command line option][].
|
|
||||||
|
|
||||||
## vm.runInNewContext(code[, sandbox][, options])
|
## vm.runInNewContext(code[, sandbox][, options])
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v0.3.1
|
added: v0.3.1
|
||||||
@ -517,7 +487,6 @@ associating it with the `sandbox` object is what this document refers to as
|
|||||||
[`vm.runInContext()`]: #vm_vm_runincontext_code_contextifiedsandbox_options
|
[`vm.runInContext()`]: #vm_vm_runincontext_code_contextifiedsandbox_options
|
||||||
[`vm.runInThisContext()`]: #vm_vm_runinthiscontext_code_options
|
[`vm.runInThisContext()`]: #vm_vm_runinthiscontext_code_options
|
||||||
[V8 Embedder's Guide]: https://github.com/v8/v8/wiki/Embedder's%20Guide#contexts
|
[V8 Embedder's Guide]: https://github.com/v8/v8/wiki/Embedder's%20Guide#contexts
|
||||||
[command line option]: cli.html
|
|
||||||
[contextified]: #vm_what_does_it_mean_to_contextify_an_object
|
[contextified]: #vm_what_does_it_mean_to_contextify_an_object
|
||||||
[global object]: https://es5.github.io/#x15.1
|
[global object]: https://es5.github.io/#x15.1
|
||||||
[indirect `eval()` call]: https://es5.github.io/#x10.4.2
|
[indirect `eval()` call]: https://es5.github.io/#x10.4.2
|
||||||
|
@ -629,10 +629,6 @@ Module.prototype._compile = function(content, filename) {
|
|||||||
if (filename === resolvedArgv) {
|
if (filename === resolvedArgv) {
|
||||||
delete process._breakFirstLine;
|
delete process._breakFirstLine;
|
||||||
inspectorWrapper = process.binding('inspector').callAndPauseOnStart;
|
inspectorWrapper = process.binding('inspector').callAndPauseOnStart;
|
||||||
if (!inspectorWrapper) {
|
|
||||||
const Debug = vm.runInDebugContext('Debug');
|
|
||||||
Debug.setBreakPoint(compiledWrapper, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var dirname = path.dirname(filename);
|
var dirname = path.dirname(filename);
|
||||||
|
15
lib/vm.js
15
lib/vm.js
@ -27,7 +27,6 @@ const {
|
|||||||
|
|
||||||
makeContext,
|
makeContext,
|
||||||
isContext,
|
isContext,
|
||||||
runInDebugContext: runInDebugContext_
|
|
||||||
} = process.binding('contextify');
|
} = process.binding('contextify');
|
||||||
|
|
||||||
// The binding provides a few useful primitives:
|
// The binding provides a few useful primitives:
|
||||||
@ -105,19 +104,6 @@ function sigintHandlersWrap(fn, thisArg, argsArray) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let runInDebugContextWarned = false;
|
|
||||||
function runInDebugContext(code) {
|
|
||||||
if (runInDebugContextWarned === false) {
|
|
||||||
runInDebugContextWarned = true;
|
|
||||||
process.emitWarning(
|
|
||||||
'DebugContext has been deprecated and will be removed in a ' +
|
|
||||||
'future version.',
|
|
||||||
'DeprecationWarning',
|
|
||||||
'DEP0069');
|
|
||||||
}
|
|
||||||
return runInDebugContext_(code);
|
|
||||||
}
|
|
||||||
|
|
||||||
function runInContext(code, contextifiedSandbox, options) {
|
function runInContext(code, contextifiedSandbox, options) {
|
||||||
if (typeof options === 'string') {
|
if (typeof options === 'string') {
|
||||||
options = {
|
options = {
|
||||||
@ -156,7 +142,6 @@ module.exports = {
|
|||||||
Script,
|
Script,
|
||||||
createContext,
|
createContext,
|
||||||
createScript,
|
createScript,
|
||||||
runInDebugContext,
|
|
||||||
runInContext,
|
runInContext,
|
||||||
runInNewContext,
|
runInNewContext,
|
||||||
runInThisContext,
|
runInThisContext,
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#include "node_internals.h"
|
#include "node_internals.h"
|
||||||
#include "node_watchdog.h"
|
#include "node_watchdog.h"
|
||||||
#include "base_object-inl.h"
|
#include "base_object-inl.h"
|
||||||
#include "v8-debug.h"
|
|
||||||
|
|
||||||
namespace node {
|
namespace node {
|
||||||
|
|
||||||
@ -30,7 +29,6 @@ using v8::Array;
|
|||||||
using v8::ArrayBuffer;
|
using v8::ArrayBuffer;
|
||||||
using v8::Boolean;
|
using v8::Boolean;
|
||||||
using v8::Context;
|
using v8::Context;
|
||||||
using v8::Debug;
|
|
||||||
using v8::EscapableHandleScope;
|
using v8::EscapableHandleScope;
|
||||||
using v8::External;
|
using v8::External;
|
||||||
using v8::Function;
|
using v8::Function;
|
||||||
@ -218,42 +216,11 @@ class ContextifyContext {
|
|||||||
function_template->InstanceTemplate()->SetInternalFieldCount(1);
|
function_template->InstanceTemplate()->SetInternalFieldCount(1);
|
||||||
env->set_script_data_constructor_function(function_template->GetFunction());
|
env->set_script_data_constructor_function(function_template->GetFunction());
|
||||||
|
|
||||||
env->SetMethod(target, "runInDebugContext", RunInDebugContext);
|
|
||||||
env->SetMethod(target, "makeContext", MakeContext);
|
env->SetMethod(target, "makeContext", MakeContext);
|
||||||
env->SetMethod(target, "isContext", IsContext);
|
env->SetMethod(target, "isContext", IsContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void RunInDebugContext(const FunctionCallbackInfo<Value>& args) {
|
|
||||||
Local<String> script_source(args[0]->ToString(args.GetIsolate()));
|
|
||||||
if (script_source.IsEmpty())
|
|
||||||
return; // Exception pending.
|
|
||||||
Local<Context> debug_context = Debug::GetDebugContext(args.GetIsolate());
|
|
||||||
Environment* env = Environment::GetCurrent(args);
|
|
||||||
if (debug_context.IsEmpty()) {
|
|
||||||
// Force-load the debug context.
|
|
||||||
auto dummy_event_listener = [] (const Debug::EventDetails&) {};
|
|
||||||
Debug::SetDebugEventListener(args.GetIsolate(), dummy_event_listener);
|
|
||||||
debug_context = Debug::GetDebugContext(args.GetIsolate());
|
|
||||||
CHECK(!debug_context.IsEmpty());
|
|
||||||
// Ensure that the debug context has an Environment assigned in case
|
|
||||||
// a fatal error is raised. The fatal exception handler in node.cc
|
|
||||||
// is not equipped to deal with contexts that don't have one and
|
|
||||||
// can't easily be taught that due to a deficiency in the V8 API:
|
|
||||||
// there is no way for the embedder to tell if the data index is
|
|
||||||
// in use.
|
|
||||||
const int index = Environment::kContextEmbedderDataIndex;
|
|
||||||
debug_context->SetAlignedPointerInEmbedderData(index, env);
|
|
||||||
}
|
|
||||||
|
|
||||||
Context::Scope context_scope(debug_context);
|
|
||||||
MaybeLocal<Script> script = Script::Compile(debug_context, script_source);
|
|
||||||
if (script.IsEmpty())
|
|
||||||
return; // Exception pending.
|
|
||||||
args.GetReturnValue().Set(script.ToLocalChecked()->Run());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void MakeContext(const FunctionCallbackInfo<Value>& args) {
|
static void MakeContext(const FunctionCallbackInfo<Value>& args) {
|
||||||
Environment* env = Environment::GetCurrent(args);
|
Environment* env = Environment::GetCurrent(args);
|
||||||
|
|
||||||
|
4
test/fixtures/vm-run-in-debug-context.js
vendored
4
test/fixtures/vm-run-in-debug-context.js
vendored
@ -1,4 +0,0 @@
|
|||||||
if (process.argv[2] === 'handle-fatal-exception')
|
|
||||||
process._fatalException = process.exit.bind(null, 42);
|
|
||||||
|
|
||||||
require('vm').runInDebugContext('*');
|
|
@ -19,12 +19,14 @@
|
|||||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
// Flags: --expose_internals
|
||||||
'use strict';
|
'use strict';
|
||||||
const common = require('../common');
|
const common = require('../common');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const JSStream = process.binding('js_stream').JSStream;
|
const JSStream = process.binding('js_stream').JSStream;
|
||||||
const util = require('util');
|
const util = require('util');
|
||||||
const vm = require('vm');
|
const vm = require('vm');
|
||||||
|
const { previewMapIterator } = require('internal/v8');
|
||||||
|
|
||||||
assert.strictEqual(util.inspect(1), '1');
|
assert.strictEqual(util.inspect(1), '1');
|
||||||
assert.strictEqual(util.inspect(false), 'false');
|
assert.strictEqual(util.inspect(false), 'false');
|
||||||
@ -442,11 +444,9 @@ assert.strictEqual(util.inspect(-0), '-0');
|
|||||||
|
|
||||||
// test for Array constructor in different context
|
// test for Array constructor in different context
|
||||||
{
|
{
|
||||||
const Debug = vm.runInDebugContext('Debug');
|
|
||||||
const map = new Map();
|
const map = new Map();
|
||||||
map.set(1, 2);
|
map.set(1, 2);
|
||||||
const mirror = Debug.MakeMirror(map.entries(), true);
|
const vals = previewMapIterator(map.entries(), 100);
|
||||||
const vals = mirror.preview();
|
|
||||||
const valsOutput = [];
|
const valsOutput = [];
|
||||||
for (const o of vals) {
|
for (const o of vals) {
|
||||||
valsOutput.push(o);
|
valsOutput.push(o);
|
||||||
|
@ -1,123 +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.
|
|
||||||
|
|
||||||
/* eslint-disable no-debugger */
|
|
||||||
'use strict';
|
|
||||||
const common = require('../common');
|
|
||||||
const assert = require('assert');
|
|
||||||
const vm = require('vm');
|
|
||||||
const { spawn } = require('child_process');
|
|
||||||
const fixtures = require('../common/fixtures');
|
|
||||||
|
|
||||||
const msg = 'DebugContext has been deprecated and will be removed in ' +
|
|
||||||
'a future version.';
|
|
||||||
common.expectWarning('DeprecationWarning', msg);
|
|
||||||
vm.runInDebugContext();
|
|
||||||
|
|
||||||
assert.throws(function() {
|
|
||||||
vm.runInDebugContext('*');
|
|
||||||
}, /SyntaxError/);
|
|
||||||
|
|
||||||
assert.throws(function() {
|
|
||||||
vm.runInDebugContext({ toString: assert.fail });
|
|
||||||
}, /AssertionError/);
|
|
||||||
|
|
||||||
assert.throws(function() {
|
|
||||||
vm.runInDebugContext('throw URIError("BAM")');
|
|
||||||
}, /URIError/);
|
|
||||||
|
|
||||||
assert.throws(function() {
|
|
||||||
vm.runInDebugContext('(function(f) { f(f) })(function(f) { f(f) })');
|
|
||||||
}, /RangeError/);
|
|
||||||
|
|
||||||
assert.strictEqual(typeof vm.runInDebugContext('this'), 'object');
|
|
||||||
assert.strictEqual(typeof vm.runInDebugContext('Debug'), 'object');
|
|
||||||
|
|
||||||
assert.strictEqual(vm.runInDebugContext(), undefined);
|
|
||||||
assert.strictEqual(vm.runInDebugContext(0), 0);
|
|
||||||
assert.strictEqual(vm.runInDebugContext(null), null);
|
|
||||||
assert.strictEqual(vm.runInDebugContext(undefined), undefined);
|
|
||||||
|
|
||||||
// See https://github.com/nodejs/node/issues/1190, accessing named interceptors
|
|
||||||
// and accessors inside a debug event listener should not crash.
|
|
||||||
{
|
|
||||||
const Debug = vm.runInDebugContext('Debug');
|
|
||||||
let breaks = 0;
|
|
||||||
|
|
||||||
function ondebugevent(evt, exc) {
|
|
||||||
if (evt !== Debug.DebugEvent.Break) return;
|
|
||||||
exc.frame(0).evaluate('process.env').properties(); // Named interceptor.
|
|
||||||
exc.frame(0).evaluate('process.title').getTruncatedValue(); // Accessor.
|
|
||||||
breaks += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
function breakpoint() {
|
|
||||||
debugger;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.strictEqual(breaks, 0);
|
|
||||||
Debug.setListener(ondebugevent);
|
|
||||||
assert.strictEqual(breaks, 0);
|
|
||||||
breakpoint();
|
|
||||||
assert.strictEqual(breaks, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can set listeners and breakpoints on a single line file
|
|
||||||
{
|
|
||||||
const Debug = vm.runInDebugContext('Debug');
|
|
||||||
const fn = require(fixtures.path('exports-function-with-param'));
|
|
||||||
let called = false;
|
|
||||||
|
|
||||||
Debug.setListener(function(event, state, data) {
|
|
||||||
if (data.constructor.name === 'BreakEvent') {
|
|
||||||
called = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Debug.setBreakPoint(fn);
|
|
||||||
fn('foo');
|
|
||||||
assert.strictEqual(Debug.showBreakPoints(fn), '(arg) { [B0]return arg; }');
|
|
||||||
assert.strictEqual(called, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// See https://github.com/nodejs/node/issues/1190, fatal errors should not
|
|
||||||
// crash the process.
|
|
||||||
const script = fixtures.path('vm-run-in-debug-context.js');
|
|
||||||
let proc = spawn(process.execPath, [script]);
|
|
||||||
const data = [];
|
|
||||||
proc.stdout.on('data', common.mustNotCall());
|
|
||||||
proc.stderr.on('data', data.push.bind(data));
|
|
||||||
proc.stderr.once('end', common.mustCall(function() {
|
|
||||||
const haystack = Buffer.concat(data).toString('utf8');
|
|
||||||
assert(/SyntaxError: Unexpected token \*/.test(haystack));
|
|
||||||
}));
|
|
||||||
proc.once('exit', common.mustCall(function(exitCode, signalCode) {
|
|
||||||
assert.strictEqual(exitCode, 1);
|
|
||||||
assert.strictEqual(signalCode, null);
|
|
||||||
}));
|
|
||||||
|
|
||||||
proc = spawn(process.execPath, [script, 'handle-fatal-exception']);
|
|
||||||
proc.stdout.on('data', common.mustNotCall());
|
|
||||||
proc.stderr.on('data', common.mustNotCall());
|
|
||||||
proc.once('exit', common.mustCall(function(exitCode, signalCode) {
|
|
||||||
assert.strictEqual(exitCode, 42);
|
|
||||||
assert.strictEqual(signalCode, null);
|
|
||||||
}));
|
|
@ -14,9 +14,9 @@ if (common.isWindows ||
|
|||||||
const base = require('./tick-processor-base.js');
|
const base = require('./tick-processor-base.js');
|
||||||
|
|
||||||
base.runTest({
|
base.runTest({
|
||||||
pattern: /RunInDebugContext/,
|
pattern: /MakeContext/,
|
||||||
code: `function f() {
|
code: `function f() {
|
||||||
require('vm').runInDebugContext('Debug');
|
require('vm').createContext({});
|
||||||
setImmediate(function() { f(); });
|
setImmediate(function() { f(); });
|
||||||
};
|
};
|
||||||
f();`
|
f();`
|
||||||
|
@ -16,7 +16,7 @@ const base = require('./tick-processor-base.js');
|
|||||||
base.runTest({
|
base.runTest({
|
||||||
pattern: /^{/,
|
pattern: /^{/,
|
||||||
code: `function f() {
|
code: `function f() {
|
||||||
require('vm').runInDebugContext('Debug');
|
require('vm').createContext({});
|
||||||
setImmediate(function() { f(); });
|
setImmediate(function() { f(); });
|
||||||
};
|
};
|
||||||
f();`,
|
f();`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user