Debugging Errors Within NodeJS
Today I had the pleasure of meeting Mr. Ryan Dahl himself at CodeConf 2011, and he shared with me a few interesting tricks that you can use to debug the internals of NodeJS. These tips are useful if you think you are experiencing a bug somewhere within the NodeJS codebase, or would just like a look under the hood of the system. I wanted to write these down and share them in case anyone else found them useful.
First of all, you need to make a fork of the NodeJS repository and pull it down locally so you can start playing. I’ll assume you know how to do that, moving on…
./ configure —debug && make
Once you’ve got the codebase, you likely ran ./configure && make. If you did that, you’ll see a
node executable that you could run that would represent the master branch you just cloned. However, if you configure with the
--debug switch, you get a special version of the code with a full blown V8 debug edition + Ryan’s baked in defensive assertions.
The defensive assertions are useful because they can help tell you if you’ve given or done something to NodeJS that it actively does not want/allow you to do with it, as if using the system as you intended to literally responds with a testing-style pass/fail assertion. Rad!
This version takes a significantly longer amount of time to compile, but its really nice to be able to see whats going on from the perspective of the inline assertions that can be tripped when testing for NodeJS bugs. Also, with the full blown V8 debug edition, I imagine cool things can be done with it via gdb, but I am not wise enough to exploit them, yet.
when making the debug binary, make sure you run your node files through the new
node_g binary that should live at the project root. It compiles and lives along side the regular version just fine.
I believe this is available to you in non-debug mode as well, but its a totally cool way to see the process steps that node is taking when doing any given command that implements this idiom.
when running a script, say:
you may want to know what exactly the sockets inside of NodeJS are doing with your data at a very granular level. the
NODE_DEBUG env variable provides this insight, simply add the following to your command:
NODE_DEBUG=http node wackyhttp.js
You should get out a large stream of
console.log describing all sorts of neat stuff from within NodeJS! You can also combine them, say you are wondering what the HTTPS system is doing, you could do the following:
NODE_DEBUG=http,https,tls node somethingsecure.js
This will give you the console log traces across those three modules. Killer!!
A Note about Debugging + Defensive Idioms for functional programming
Jonathan Rentzsch gave a great Talk today at CodeConf about integrating your assumption testing right into your codebase, such that you are always testing your code, whenever it runs, rather than simply relying on a series of tests cases that have to be run in an isolated and inorganic situation. Ryan seems to have totally integrated a lot of the defensive programming techniques directly into the codebase of NodeJS, however the assertions appear to be stripped out in the non-debug version for the binary.
Either way, the combination of inline assertions + exposing verbosity at the module level via environment variables is not exactly new, but is exciting to see so well executed in a functional environment. I definitely had a bit of an “a ha” moment, when seeing it all come together. Excited to dig further into the NodeJS codebase to find more functional wisdom.