如何以编程方式检测nodejs中的调试模式?

j03*_*03m 31 debugging node.js

我已经看到这个问题涉及其他平台/语言 - 任何想法?我想做点什么:

if (detectDebug())
{
    require('tty').setRawMode(true);    
    var stdin = process.openStdin();

    stdin.on('keypress', function (chunk, key) {
        DoWork();
    }
}
else
{
    DoWork();
}
Run Code Online (Sandbox Code Playgroud)

我希望能够在调试时切换键盘输入作为脚本的开始,这样我就可以有时间启动chrome来监听我的node-inspector端口.

***快速更新 - 我猜我实际上可以使用"process.argv"来检测是否传入了--debug.这是最佳/正确的方法吗?

Gab*_*vay 46

v8debug在调试模式下运行时,NodeJS创建一个全局对象:node debug script.js

因此,一个可能的解决方案是:

var debug = typeof v8debug === 'object';
Run Code Online (Sandbox Code Playgroud)

对于我的用例,我使用它是因为我想避免传递环境变量.我的主节点进程启动子节点进程,我想要为子进程node debug mainScript.js触发调试模式(同样,不将env变量传递给子进程)

  • 谢谢,这也更好地回答了问题(这不是"我怎样才能设置生产模式") (4认同)
  • 对于每个@Alex,似乎全局节点在较新版本的Node(包括最新的LTS)中不存在。 (3认同)
  • 自从几个主要的Node版本开始以来,这一直没有起作用。 (3认同)

Leo*_*ele 32

其他答案中提到的全局v8debug变量似乎在 Node v7.0.0 中被删除(参见https://github.com/nodejs/node/issues/9617)。此外,检查进程参数(即process.execArgv)似乎不可靠,因为 Node 可以在运行时进入调试模式。例如,VS Code 并不总是使用该--inspect选项启动 Node,即使在调试时也是如此。(取决于您的调试配置)

我能找到的最可靠的解决方案是检查inspector.url()Node 是否正在侦听调试连接。

const inspector = require('inspector');

function isInDebugMode() {
    return inspector.url() !== undefined;
}
Run Code Online (Sandbox Code Playgroud)

我已经使用 Node 版本v12.22.1v14.16.1、 和测试了此方法,v16.1.0并且它对所有版本都有效。


ben*_*ael 22

我用这个

var debug = typeof v8debug === 'object' 
            || /--debug|--inspect/.test(process.execArgv.join(' '));
Run Code Online (Sandbox Code Playgroud)

支持,--debug,--debug-brk,--inspect--inspect=1234

  • 好答案.在测试我的vscode扩展时,v8debug不存在,所以最佳答案对我不起作用.但是--debug-brk就在那里,所以你的代码抓住了它:) (3认同)
  • 对于使用 TypeScript 的用户,请记住在 v8debug 前面加上 global.v8debug。请记住,较新版本的 NodeJS 甚至没有设置 v8debug,所以这就是为什么我评论的这个答案是最好的,因为它捕获了更现代版本的 NodeJS。 (2认同)

Lel*_*sin 16

有一个 node.js 原生支持,inspector.url()用于检查是否有活动检查器,它只显示当前进程是否处于调试模式。请参阅文档了解更多信息。

  • 终于有实际答案了:) (2认同)

Pet*_*ons 9

我认为这个问题有很多混乱.

基于你的问题,我认为你真正想要的是node --debug-brk命令行标志.这将使节点启动v8并运行调试器,并在.js程序的第一行之前自动停在断点上.你不需要重新发明这个.我用它来调试mocha测试,express.js启动问题等.这将消除你手动检测它的需要.

其次,NODE_ENV=production只不过是许多程序用来表示"你在生产中运行"的惯例,因此应该启用某些事情,如真正发送电子邮件,使用真实的支付网关等.但是,在NODE_ENV生产(或未设置)时,您所处的环境绝对不应该被假定为调试.最明智的假设是环境是一个开发环境,但即便如此,在我看来,整个惯例都非常脆弱.

第三,只是FYI检查tty.isatty(),它会准确地告诉你程序是否在交互式终端上运行(比如命令shell).这将是false您的程序由您的操作系统提供的进程主管(upstart,sysvinit等)运行的时候.此检查通常用于在交互模式和脚本模式之间切换命令行程序.它并不完全完美或绝对可靠,但它在posix世界中被广泛采用.

第四,从一些快速实验v8debug来看,全球性的@Gabriel Petrovay指示似乎只是在做的node debug script.js时候设置,而不是在做的时候设置node --debug script.js.不知道为什么会这样.如果这样的事情是可靠的,那么这似乎是找出"这是调试模式中的这个v8实例"的最正确的方法.


小智 6

var detectDebug = function() {
    return process.env.NODE_ENV !== 'production';
};
Run Code Online (Sandbox Code Playgroud)

在调试模式下运行:

$ node app.js
Run Code Online (Sandbox Code Playgroud)

在生产模式下运行:

$ NODE_ENV=production node app.js
Run Code Online (Sandbox Code Playgroud)

一些框架以这种方式识别生产模式。请参阅express.js 文档


Dal*_*son 5

只有在设置了debug或--debug-brk命令行选项时,才会创建/公开global.v8debug对象.当设置--debug时,它不会被创建,这很奇怪而且很烦人.

一个hacky方法是查看process.execArgv数组(不是process.argv)--debug, - debug-brk或debug.

  • 似乎在process.execArgv中可用 (2认同)

jco*_*lum 5

process.debugPort似乎始终存在,默认为 5858。检测程序是否显式启动的唯一方法--debug是检查process.execArgv数组。--debug-brk很明显可以检测到:您的程序不会执行任何操作,并且您会收到一条有关调试器正在侦听的消息,因此很容易弄清楚。当程序启动时或当前附加诸如节点检查器之类的调试器时,v8debug似乎存在。node debug file.js

记住所有这些,此代码将检测当前是否附加了调试器(任何类型)。

 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");
  }
Run Code Online (Sandbox Code Playgroud)