【问题标题】:How to debug Node.JS child forked process?如何调试 Node.JS 子分叉进程?
【发布时间】:2013-05-26 06:59:45
【问题描述】:

我正在尝试调试使用以下方法创建的子 Node.JS 进程:

var child = require('child_process');
child .fork(__dirname + '/task.js');

问题是在 IntelliJ/WebStorm 中运行时,父进程和子进程都在同一个端口上启动。

debugger listening on port 40893
debugger listening on port 40893

所以它只调试父进程。

有什么方法可以设置 IntelliJ 来调试子进程或强制它在不同的端口上启动,以便我可以在远程调试中连接它?

【问题讨论】:

    标签: node.js debugging intellij-idea


    【解决方案1】:

    我发现在 fork func 中设置 'execArgv' 属性会起作用:

    const child = fork('start.js', [], {
    cwd: startPath,
    silent: true,
    execArgv: ['--inspect=10245'] });
    

    【讨论】:

      【解决方案2】:

      快速简单的修复(使用 chrome://inspect/#devices 的地方)

      var child = require('child_process');
      child.fork(__dirname + '/task.js',[],{execArgv:['--inspect-brk']});
      

      然后在没有任何--inspect-brk 的情况下运行您的应用,主进程不会调试,但分叉的进程会并且不会发生冲突。

      在调试主进程时停止分叉冲突;

      child.fork(__dirname + '/task.js',[],{execArgv:['--inspect=xxxx']});
      

      其中xxxx 是一些未用于调试主进程的端口。尽管我还没有设法在调试器中轻松地同时连接到两者,即使它报告为正在侦听。

      【讨论】:

      • 对于其他人尝试使用 spawn 但无法正常工作,我发现这对我有用:child.spawn('node',['--inspect-brk', __dirname + '/task.js']);
      【解决方案3】:

      还有一种更现代的方式可以使用 Chrome DevTools 调试子(或任何)进程。

      使用 arg 启动您的应用程序

      --inspect
      

      如下:

      node --debug=9200 --inspect app/main.js
      

      您将看到带有每个子进程 URL 的消息:

      Debugger listening on port 9200.
      Warning: This is an experimental feature and could change at any time.
      To start debugging, open the following URL in Chrome:
          chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9200/207f2ab6-5700-4fc5-b6d3-c49a4b34a311
      Debugger listening on port 9201.
      Warning: This is an experimental feature and could change at any time.
      To start debugging, open the following URL in Chrome:
          chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9201/97be3351-2ea1-4541-b744-e720188bacfa
      Debugger listening on port 9202.
      Warning: This is an experimental feature and could change at any time.
      To start debugging, open the following URL in Chrome:
          chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9202/8eb8384a-7167-40e9-911a-5a8b902bb8c9
      

      如果要调试远程进程,只需将地址 127.0.0.1 更改为自己的即可。

      【讨论】:

      • --inspect 是现代的方式,但它与这里的问题没有太大关系——调试子进程。
      • Chrome 不会自动发现额外的端口。您必须告诉它手动与他们连接。
      【解决方案4】:

      如果“process.execArgv”确实有效,您必须尝试:

      if (debug) {
          process.argv.push('--debug=' + (40894));
      }
      

      这对我有用..

      【讨论】:

        【解决方案5】:

        是的。您必须在新端口中生成您的进程。使用集群进行调试有一种解决方法,您可以这样做:

        使用 --debug 命令启动您的应用,然后:

        var child = require('child_process');
        var debug = typeof v8debug === 'object';
        if (debug) {   
            //Set an unused port number.    
            process.execArgv.push('--debug=' + (40894));    
        }    
        child.fork(__dirname + '/task.js');
        

        debugger listening on port 40894

        【讨论】:

        • 我不知道为什么,但是我的 process.execArgv 是一个数组,我不得不将它修改为 process.execArgv.toString().indexOf('--debug') !== - 1个;为了让它工作。谢谢!
        • 使用节点 0.12.1,问题仍然存在,条件没有返回 true(检查调试),但是按照您建议的方式更改端口。
        【解决方案6】:

        这是 node.js 中的一个已知错误,最近已修复(尽管未向后移植到 v0.10)。

        更多详情请查看本期:https://github.com/joyent/node/issues/5318

        有一种变通方法,您可以更改每个工作进程的命令行,尽管 API 并不打算以这种方式使用(该变通方法将来可能会停止工作)。这是github问题的源代码:

        var cluster = require('cluster');
        var http = require('http');
        
        if (cluster.isMaster) {
          var debug = process.execArgv.indexOf('--debug') !== -1;
          cluster.setupMaster({
            execArgv: process.execArgv.filter(function(s) { return s !== '--debug' })
          });
          for (var i = 0; i < 2; ++i) {
            if (debug) cluster.settings.execArgv.push('--debug=' + (5859 + i));
            cluster.fork();
            if (debug) cluster.settings.execArgv.pop();
          }
        }
        else {
          var server = http.createServer(function(req, res) {
            res.end('OK');
          });
          server.listen(8000);
        }
        

        【讨论】:

        • 有没有办法用 child.fork() 实现同样的事情?
        • @GuyKorland 当然,只需将 --debug={port} 添加到子进程的命令行参数即可。
        • 另见this comment
        • 我在这方面遇到了困难,因为我将 child_process 模块影响到了一个名为 process 的局部变量,隐藏了节点进程全局变量,因此没有定义 process.execArgv。注意“进程”是一个节点全局变量!
        猜你喜欢
        • 2023-04-05
        • 1970-01-01
        • 2017-06-29
        • 1970-01-01
        • 2015-12-13
        • 2018-08-15
        • 2019-10-24
        • 1970-01-01
        • 2011-06-24
        相关资源
        最近更新 更多