Live debugging a nodejs app? - node.js

How can I debug a running nodejs app? I've found tools such as node-inspector, but it seems to only support starting the app and debugging from there.

Debugging a running nodejs app.
This is the combination of a little documented feature of V8 mixed with a non-documented feature of the node.js debugger client. Say you have an already running node process that you want to debug.
# start the remote debugger in the already running node process
kill -s USR1 pid
# attach to the debugger using the node.js client
node debug host:5858
# see where you are
debug> pause
debug> bt
From there you can poke around. You can also continue and pause again to see if you seem to consistently end up in the same code area.
Debugging a nodejs app.
V8 comes with an extensive debugger which is accessible out-of-process via a simple TCP protocol. Node has a built-in client for this debugger. To use this, start Node with the debug argument; a prompt will appear:
% node debug myscript.js
< debugger listening on port 3000
connecting... ok
break in /home/username/Code/myscript.js:1
1 x = 5;
2 setTimeout(function () {
3 debugger;
debug>
cont, c - Continue execution
next, n - Step next
step, s - Step in
out, o - Step out
pause - Pause running code
Check API for other commands reference and other details
You can also use node-inspector . Use it from any browser supporting websockets. Breakpoints, profiler, livecoding etc... It is really awesome.
Install it with
npm install -g node-inspector
then run
node-debug app.js

Related

Retain Node.js debug mode when starting another process

To debug a Node.js process, I use:
node --inspect-brk foo_bar.js
But what if that instance would start another, separate instance, and this one would be - how to run that instance in debug mode as well?
The problem is, I am using the commander.js library for Node.js, like so:
var program = require('commander')
...
program.parse(process.argv)
This creates another instance of Node.js process, and hence I lose the debug functionality (I am debugging via Chromium browser). How can I overcome this?
Note: Commander only creates another process if you implement the subcommand using a stand-alone executable.
Commander detects debugger options being passed to the node invocation, and passes them to the subprocess with the debugging port incremented by 1.
e.g.
// index.js
const { program } = require('commander');
program
.command('sub', 'stand-alone');
console.log('1');
console.log('2');
program.parse();
// index-sub.js
console.log('3');
console.log('4');
% node --inspect-brk index.js sub
Debugger listening on ws://127.0.0.1:9229/25005682-6bf4-44fb-bdb2-2cc7749bb328
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
1
2
Debugger listening on ws://127.0.0.1:9230/00d1924a-3122-4bef-86f2-65d562fbf3ed
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
3
4

Is it possible to debug node js code that runs before the debugger attaches?

Using the instructions found here I have setup Visual Studio Code to debug my nodejs code.
But it takes the debugger a few seconds to attach to node. And during that few seconds the code just runs.
So a file like this, with a breakpoint on line 1:
• 1 console.log('')
Will never break because it quits before the debugger attaches.
I can quickly ^c the code then restart and sometimes catch the debugger but this is unreliable.
Is there an event I can wait for in my code so that I know the debugger is attached and it is safe to continue?
Or is there a better configuration for doing this?
Yes, using the --inspect-brk option for node instead of --inspect.
so when running your code it would look something like this
node --inspect-brk server.js

Webstorm debugger breakpoints doesn't work in nodejs

When I try to set a breakpoint and debug the file, the debugger just run the app without stopping at breakpoints.
This is my code:
console.log('123');
And this is my output:
/usr/bin/node --debug-brk=39765 --nolazy index.js
debugger listening on port 39765
123
Process finished with exit code 0
Does anyone has an idea what could be the problem?
Try to disable js.debugger.v8.use.any.breakpoint in WebStorm registry.
You can do it by going to Help -> Find Action
In there just enter Registry.
For me disabling this option made debugging anything node-related much faster and much more predictable.
Wanted to chime in and say that it is absolutely critical that you use --debug-brk and not --debug with getting WebStorm breakpoints to work for remote debugging as well as running the server directly from webstorm.
Even though --debug-brk technically just stops and waits for the debugger to join, and --debug allows you to join later, my breakpoints failed with just --debug no matter the remote configuration I tried.
As far as I can tell, connecting WebStorm 11 to a node.js server on the debug port, with only --debug, will connect but fail to load any breakpoints that work.
disabling js.debugger.use.node.options in the webstorm registry helped me
https://youtrack.jetbrains.com/issue/WEB-47774#focus=Comments-27-4436526.0-0
Debug breakpoints not work in my PhpStorm 2016.3.2 with NodeJS 7.7.x. My expectation is, that WebStorm will have same issue.
If you downgrade to Node 6 (I tested with 6.9.4), it starts working correctly.
For me the issue was that WebStorm didn't play well with my typescripts. It would say debugger listening and then run through the entire program without stopping at the breakpoint as described in the question.
The workaround I used was to simply put the breakpoint in compiled js file and debug from there instead.
Go to Run -> View Breakpoints... or hit
shift+command+F8 in OS X.
Select your breakpoint from the list and make sure Suspend is checked.
Fixed the issue by enabling generation of 'map' file in the TypeScript configuration.
Add '--sourceMap' in Tools-->Languages & Frameworks-->TypeScript-->Options
I'm having the same issue in version 2022.2 but I don't think it is a problem with the version
Here are the potential solutions;
Go to;
WebStorm -> Preference -> Build, Execution, Deployment -> Debugger
Click "Allow unsigned requests" checkbox and make it checked
This solved my issue.
Or
Check your local environment. What I mean by saying check your local environment is usually more than one service is trying to use the same debugger port if we speak about the e.g. nodejs.
You will get the following message if you try to run two services at the same time in the debug mode;
Starting inspector on 127.0.0.1:9229 failed: address already in use
Try to start the main service first that you try to debug.

nodejs start debugger on different port

Im a little confused with all this nodejs debug syntax flying around.
I simply want to start the debugger on a process when I run it on a different port.
Normally I start debugging by node debug file.js
but now I have to process` running that I need to debug
Now I found the command node --debugger=7873 file.js but that starts the debugger and jumps past all the breaks and I tried node --debugger=7837 --debug-brk file.js but that forces me to consume another teminal window. How can I just run a script on a different port in the same terminal or with out using nohup?
node debug --port=[your port] your_program.js
responsible _debugger code here

Is it possible to see inside redis module bundled with socket.io

Since we can configure socket.io to use redis for it's internal workings like this:
var RedisStore = require('socket.io/lib/stores/redis')
, redis = require('socket.io/node_modules/redis')
, pub = redis.createClient()
, sub = redis.createClient()
, client = redis.createClient();
io.set('store', new RedisStore({
redisPub : pub
, redisSub : sub
, redisClient : client
}));
How is it possible to see inside of this RedisStore to see what data socket.io is inserting and removing. I set my socket.io configuration to use the redis instance installed from node-redis like this:
redis = require('redis')
but I don't see any socket.io activity going on and I wonder if socket.io is actually using redis. I do see my cookies being stored in redis because I configured express and connect to use redis as the MemoryStore, but I don't see anything related to socket.io.
For local redis node.js development/debugging I do this.
Start redis server in background and run the cli monitor in the same tty:
redis-server &
redis-cli monitor -h host -p port
You can leave - switches off if using local defaults.
You can also run a redis slave that echos all master commands and SYNCs the current redis-server's memory held data into a textfile defaulting to ./dump.rdb. The file can be loaded into redis and viewed with a text editor.
redis-cli --slave -h host -p port
vim ./dump.rdb
A basic node.js Passport session-cookie would look something like this:
sess:L2C4MPtAUmlO4zHGkXnq4icuÃ#U#Z{"cookie":{"originalMaxAg null,"expiresÀhttpOnly":true,"path":"/"}passport L}
To further help see inside you may want to step through your app and put breakpoints in the areas where your node code and redis driver interact.
You can use this to watch the handshake process, see incorrect data exchanging, problems with the socket, etc by stepping through your functions, and observing the changes in state during control flow.
The node app for this job is node-inspector.
It will allow you to view your app running in a debugging environment similar
to Chrome dev tools, where you can set breakpoints to pause, step in and out
of functions, and move forward in time until the next breakpoint or exception
triggers a pause.
npm -g install node-inspector
You install it with the '-g' global switch as you use it across multiple projects.
running the program without any options in a terminal window produces this output for me:
~/passaic-streaming git:weekend-refactor ❯❯❯
Node Inspector v0.7.0
Visit http://localhost:8080/debug?port=5858 to start debugging.
You can configure the HOST, PORT, DEBUG-PORT using config or ENV variables
(DEBUG_PORT, port 5858, passed as a parameter sets up a socket connection
between the running node process and your browser running the web-app).
Now, there are three ways to run your node.js code in debug mode. You do this after first running node-inspector:
node --debug-brk app.js
node --debug app.js
node app.js // then send a SIGUSR1 to the node process:
// pgrep node
// kill -s USR1 PID
Use the first command '--debug-brk', until you got everything working, as it tells your code to stop on your module's first line.
browser http://localhost:8080/debug?port=5858
It can take a little time to load depending on your app size. But once there you'll have a source tab to step through code, and a console tab.
The '--debug' will work fine on an express app, you may just need to hit an endpoint or do some transaction or tell it to pause at a breakpoint manually.
Some node scripts are too fast to get caught by the node-inspector listener and until you set up breakpoints in the source code it can be convenient to break on the first line, hence the command.
You can also put 'node debugger';lines around areas like:
// connect to Redis for sessionStore
node debugger; // node-inspector will pause here.
redisClient = redis.createClient(
options.PORT, options.HOST, options.REDIS_OPTIONS));
The main reason you may need to use the SIGUSR1 and not start the app in debug mode is if you are using the node.js cluster API.
If you try to monitor an app that is using clustering and creating multiples node processes, then if you try to debug in node < 0.11.x you'll see this problem with the socket:
Failed to open socket on port 5858, waiting 1000 ms before retrying
Failed to open socket on port 5858, waiting 1000 ms before retrying
In the unstable node versions the child_process.fork command listens on a debugger port 5858+1, so 59, 60, etc, depending on the workers you have.
For now in node 0.10.x if you need to inspect the state of a worker in a clustered app you'll have to start node not in '--debug' mode and instead send the kill USR1 signal to the process.
To coerce more logging out of node with redis put your node_redis driver in debug mode:
redis = require('redis');
redis.debug_mode = true; //turn on debug mode
Also if using connect-redis middleware if you start like this:
DEBUG=* node app.js
Then you will see connect-redis output like this:
connect:redis SETEX "sess:FVDBpNoFDFIOkynFDLcpM6St" ttl:604799
{"cookie":{"originalMaxAge":604799991,"expires":"2014-03-08T22:38:32.620Z","httpOnly":true,"path":"/"},"passport":{"user":"52edfdfdf3da2rer0c06eb34"}} +50ms
Finally, the team at StrongOps/Strongloop has part of their command line tools node-inspector baked in.
npm install -g strong-cli
slc debug app.js
It will boot the node-inspector, open the web browser to the proper inspector, and in the latest node versions -- it understands clustering.

Resources