Last active
July 14, 2017 03:07
-
-
Save sobolews/957e8cc9768f505d816c to your computer and use it in GitHub Desktop.
Debugging an infinite loop in node.js 6.0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Install lldb-3.6 and llnode. On Ubuntu: | |
git clone https://github.com/indutny/llnode | |
cd llnode | |
sudo apt-get install lldb-3.6 lldb-3.6-dev | |
git clone https://chromium.googlesource.com/external/gyp.git tools/gyp | |
./gyp_llnode -Dlldb_dir=/usr/lib/llvm-3.6/ -Dlldb_lib=lldb-3.6 | |
make -C out/ -j9 | |
sudo make install-linux | |
Make sure cores are enabled: | |
su - | |
echo "core.%p" > /proc/sys/kernel/core_pattern # or whatever pattern you like, just not apport | |
exit | |
ulimit -c unlimited | |
In a test clone of Pokemon-Showdown: | |
battle-engine.js: | |
Battle.prototype.runDecision = function (decision) { | |
+ while(1) {} | |
// returns whether or not we ended in a callback | |
Then start a battle, and choose leads. The process `node battle-engine.js' will pin a CPU. | |
ps aux | grep node | |
carl 21678 10.6 3.3 1217876 130476 pts/14 Sl+ 01:03 0:03 /home/carl/node6/bin/node app.js | |
carl 21687 0.4 0.4 642620 16872 pts/14 Sl+ 01:03 0:00 /home/carl/node6/bin/node verifier.js | |
carl 21692 36.5 3.1 976936 126036 pts/14 Rl+ 01:03 0:10 /home/carl/node6/bin/node battle-engine.js | |
carl 21697 1.2 0.7 910908 30152 pts/14 Sl+ 01:03 0:00 /home/carl/node6/bin/node sockets-nocluster.js | |
carl 21702 10.2 3.2 979852 128448 pts/14 Sl+ 01:03 0:03 /home/carl/node6/bin/node team-validator.js | |
# The rogue process's PID is 21692 | |
kill -6 21692 # SIGABRT, this should produce a core in the current directory: core.21692 | |
lldb-3.6 $(which node) -c ./core.21692 | |
(lldb) target create "/home/carl/node6/bin/node" --core "./core.21692" | |
Core file '/home/carl/projects/Pokemon-Showdown/./core.21692' (x86_64) was loaded. | |
(lldb) bt | |
* thread #1: tid = 0, 0x00002ca29aaf3403, name = 'node', stop reason = signal SIGABRT | |
* frame #0: 0x00002ca29aaf3403 | |
frame #1: 0x00002ca29aaf2daa | |
frame #2: 0x00002ca29aaee04b | |
frame #3: 0x00002ca29aae7c12 | |
... | |
^ The useless unnamed addresses above are the JS stack frames. | |
(lldb) v8 bt | |
* SBThread: tid = 0x0000 * frame #0: 0x00002ca29aaf3403 Battle.runDecision(this=0x000011dec5f8b9a9:<Object: Object>, 0x000011dec5fec411:<Object: Object>) at /home/carl/projects/Pokemon-Showdown/battle-engine.js:3910:42 fn=0x0000205952d75c01 | |
frame #1: 0x00002ca29aaf2daa Battle.go(this=0x000011dec5f8b9a9:<Object: Object>) at /home/carl/projects/Pokemon-Showdown/battle-engine.js:4146:33 fn=0x0000205952d75cc1 | |
frame #2: 0x00002ca29aaee04b Battle.commitDecisions(this=0x000011dec5f8b9a9:<Object: Object>) at /home/carl/projects/Pokemon-Showdown/battle-engine.js:4220:46 fn=0x0000205952d75ee9 | |
frame #3: 0x00002ca29aae7c12 Battle.choose(this=0x000011dec5f8b9a9:<Object: Object>, 0x00002a4ce867e519:<String: "p2">, 0x000011dec5ff0799:<String: "team 1">, 0x00001a4ed8805ce9:<String: "1">) at /home/carl/projects/Pokemon-Showdown/battle-engine.js:4191:37 fn=0x0000205952d75e39 | |
... | |
Aha! The llnode extension allows lldb to read the JS frames. We now have our stack trace! | |
You can also poke around using `v8 i': Let's look at the `this' from frame #0 (the Battle object) | |
v8 i 0x000011dec5f8b9a9 | |
0x000004abfbf8b9a9:<Object: Object properties { | |
.log=0x000004abfbf8be41:<Array: length=30>, | |
.sides=0x000004abfbf8bea9:<Array: length=2>, | |
.roomid=0x000004abfbf82a19:<String: "battle-customgam...">, | |
... | |
See also: https://asciinema.org/a/29589 | |
Note: for some reason that I couldn't fathom, cores made by using gcore on the running battle-engine process fail to load properly in lldb. I could only load the ones that I actually `kill -6'd manually. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment