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

时间:2011-07-31 12:28:45

标签: debugging node.js

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

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

    stdin.on('keypress', function (chunk, key) {
        DoWork();
    }
}
else
{
    DoWork();
}

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

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

11 个答案:

答案 0 :(得分:46)

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

所以,一个可能的解决方案是:

var debug = typeof v8debug === 'object';

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

答案 1 :(得分:20)

我用这个

var debug = typeof v8debug === 'object' 
            || /--debug|--inspect/.test(process.execArgv.join(' '));

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

答案 2 :(得分:8)

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

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

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

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

第四,从一些快速实验中,v8debug全局@Gabriel Petrovay指示似乎仅在执行node debug script.js时设置,而在执行node --debug script.js时未设置。不知道为什么会这样。如果这样的事情是可靠的,那么这似乎是找出“这是调试模式中的这个v8实例”的最正确的方法。

答案 3 :(得分:5)

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

执行此操作的一种hacky方法是查看process.execArgv数组(不是process.argv)--debug, - debug-brk或debug。

答案 4 :(得分:3)

var detectDebug = function() {
    return process.env.NODE_ENV !== 'production';
};

以调试模式运行:

$ node app.js

以生产模式运行:

$ NODE_ENV=production node app.js

一些框架以这种方式识别生产模式。见express.js doc

答案 5 :(得分:3)

process.debugPort似乎始终存在,默认为5858.检测程序是否使用--debug显式启动的唯一方法是检查process.execArgv数组。 --debug-brk很明显可以检测到:您的程序无法执行任何操作,并且您将收到有关调试程序监听的消息,因此可以轻而易举地解决问题。当程序以v8debug启动或当前附加了类似node-inspector的调试程序时,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");
  }

答案 6 :(得分:2)

nodejs> = 7版本中没有v8debug。 似乎最简单的方法是检查命令行参数。在调试模式下,会有一个单词' debug'或者'检查'

const argv = process.execArgv.join();
const isDebug = argv.includes('inspect') || argv.includes('debug');

答案 7 :(得分:1)

有一个node.js本机支持,它使用inspector.url()检查是否存在活动的检查器,它仅显示进程当前是否为调试模式。有关更多信息,请参见doc

答案 8 :(得分:1)

简单的解决方法是here

但是一般来说,检测调试模式并不容易-https://github.com/nodejs/node/issues/9617

答案 9 :(得分:0)

Object.defineProperty(global, 'isDebugging', {
    get: function () {
        return typeof v8debug !== 'undefined';
    }
});

这适用于webstorm

答案 10 :(得分:0)

其他答案中提到的全局 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;
}

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