How to programmatically detect debug mode in nodejs?
I've seen this question asked of other platform/languages - any ideas? I'd like to do something like:
if (detectDebug())
开发者_如何学JAVA{
require('tty').setRawMode(true);
var stdin = process.openStdin();
stdin.on('keypress', function (chunk, key) {
DoWork();
}
}
else
{
DoWork();
}
I'd like to be able to toggle keyboard input as a start for the script when debugging so that I can have a moment to fire up chrome to listen to my node-inspector port.
***Quick update - I'm guessing I can actually use "process.argv" to detect if --debug was passed in. Is this the best/right way?
NodeJS creates a v8debug
global object when running in debug mode: node debug script.js
So, a possible solution would be:
var debug = typeof v8debug === 'object';
For my use case, I use it because I want to avoid passing environment variables. My main node process starts child node processes and I want a node debug mainScript.js
to trigger debug mode for children as well (again, without passing env variables to child processes)
I use this
var debug = typeof v8debug === 'object'
|| /--debug|--inspect/.test(process.execArgv.join(' '));
which supports, --debug
, --debug-brk
, --inspect
and --inspect=1234
There is a node.js native support that using inspector.url()
to check if there is active inspector, it just shows if process is debug mode or not currently. See doc for more.
The global v8debug
variable mentioned in the other answers seem to be removed in Node v7.0.0 (see https://github.com/nodejs/node/issues/9617). Also, checking process arguments (i.e. process.execArgv
) seem to be unreliable since Node can enter debug mode at runtime. VS Code, for example, doesn't always starts Node with the --inspect
option even when debugging. (depend on your debug config)
The most reliable solution I could find is to use inspector.url()
to check if Node is listening for debug connections.
const inspector = require('inspector');
function isInDebugMode() {
return inspector.url() !== undefined;
}
I have tested this method with Node versions v12.22.1
, v14.16.1
, and v16.1.0
and it worked for all of them.
I think there's a bunch of confusion in this question.
Based on your question, I think what you really want is the node --debug-brk
command line flag. That will have node start v8 with a debugger running and automatically stop on a breakpoint before the first line of your .js
program. You don't need to reinvent this. I use this for debugging mocha tests, express.js startup issues, etc. This will eliminate your need to detect this manually.
Secondly, NODE_ENV=production
is nothing more than a convention that many programs use to indicate "you are running in production" and therefore certain things like really sending emails, using the real payment gateway, etc should be enabled. However what environment you are in when NODE_ENV
is NOT production (or is unset) should definitely NOT be assumed to be debugging. The most sane assumption there is that the environment is a development environment, but even then this whole convention is pretty brittle in my opinion.
Thirdly, just FYI check out tty.isatty() which will accurately tell you if your program is being run on an interactive terminal (like from a command shell). This will be false
when your program is being run by a process supervisor provided by your OS (upstart, sysvinit, etc). This check is commonly use to toggle command line programs between interactive and scripted modes. It's not entirely perfect or infallible, but it is widely adopted in the posix world.
Fourth, from some quick experimentation, the v8debug
global @Gabriel Petrovay indicates seems to only be set when doing node debug script.js
and not set when doing node --debug script.js
. Not sure why that is. If such a thing was reliable, that would seem like the most correct approach to finding out "is this v8 instance in debug mode".
var detectDebug = function() {
return process.env.NODE_ENV !== 'production';
};
to run in debug mode:
$ node app.js
to run in production mode:
$ NODE_ENV=production node app.js
Some frameworks recognize the production mode this way. See express.js doc.
The global.v8debug object only seems to be created / exposed when the debug or --debug-brk command line option is set. It's strange and annoying it's not created when --debug is set.
A hacky way to do this would be to look at the process.execArgv array (not process.argv) for --debug, --debug-brk or debug.
process.debugPort
appears to always be present and defaults to 5858. The only way to detect if the program was started explicitly with --debug
is to check the process.execArgv
array. --debug-brk
is pretty obvious to detect: your program won't do anything and you'll get a message about a debugger listening, so that's trivial to figure out. v8debug
appears to be present when the program is started with node debug file.js
or when a debugger like node-inspector is currently attached.
Keeping all that in mind, this code will detect whether a debugger (of any kind) is currently attached.
var debug, withDebug;
debug = false;
if (typeof v8debug !== "undefined" && v8debug !== null) {
console.log("v8 debug detected");
debug = true;
}
withDebug = process.execArgv.indexOf('--debug') > -1 || process.execArgv.indexOf('--debug-brk') > -1;
if (withDebug) {
console.log("started with debug flag, port: " + process.debugPort);
debug = true;
}
if ((typeof v8debug === "undefined" || v8debug === null) && !withDebug) {
console.log("neither detected");
}
There is no v8debug in versions of nodejs >=7. It seems that the most simple way is to check command line parameters. In debug mode there will be a word 'debug' or 'inspect'
const argv = process.execArgv.join();
const isDebug = argv.includes('inspect') || argv.includes('debug');
There simple solution is here.
But in general, detect debug mode is not easy - https://github.com/nodejs/node/issues/9617
Object.defineProperty(global, 'isDebugging', {
get: function () {
return typeof v8debug !== 'undefined';
}
});
This works well for webstorm
I had the same issue, how to check the app to see if it is running on --inspect
.
I m on nodejs 14, and the solution with the v8debug
that mentioned above, looks that it does not work any more, for clarity i post the message that i get when i try --debug
.
node: [DEP0062]:
node --debugand
node --debug-brkare invalid. Please use
node --inspectand
node --inspect-brk instead.
Solution
So how i tackle with this, is to query the process.execArgv
which is exactly what you need too.
snipet:
const isInspect = process.execArgv.join() === '--inspect'
//or ....process.execArgv.toString() === ...
This execArgv
, as the docs state:
The process.execArgv property returns the set of Node.js-specific command-line options passed when the Node.js process was launched. These options do not appear in the array returned by the process.argv property, and do not include the Node.js executable, the name of the script, or any options following the script name. These options are useful in order to spawn child processes with the same execution environment as the parent.
More in the docs: https://nodejs.org/docs/latest-v6.x/api/process.html#process_process_execargv
精彩评论