On deps/v8 in Node.js
I recently ran into a V8 test failure that only showed up in the V8 fork of Node.js but not in the upstream. Here I’ll write down my workflow used to debug the failure in case anyone (or myself) need to do this again and don’t know where to start.
For those who are not familiar with the directory structure of Node.js: the
deps/v8 directory in Node.js core is practically a fork of V8. On top of the current stable branch of V8, we “float” several patches that are maintained by ourselves. In principle, these patches should be reviewed and merged in the upstream, they are floated mostly just for special version control in our branch.
When you run
make test from the project directory Node.js, it only builds the test suite of Node.js and runs that. V8 is built as part of Node.js, but
make test does not build or run V8’s own tests.
deps/v8 directory is not maintained as a git submodule. This is fine when we just need to build V8 as an embedder - Node.js maintains a set of build files (currently as many floated GYP files) to make sure the configuration of V8 required by Node.js can be built separately. But to build V8 and run its own tests, we need to use
depot_tools to manage the dependencies and therefore the V8 directory must contains a valid git tree.
tools/make-v8.sh in Node.js (which calls into
deps/v8/tools/node/fetch_deps.py) automates the creation of a temporary git tree out of an existing V8 checkout in
deps/v8. You can invoke it using the root Makefile in the project directory of Node.js via
make v8. I prefer to be explicit and just do
deps/v8/out.gn/x64.debug with the configuration:
is_debug = true
If you really want to customize the build process, just take a look at the
make-v8.sh script, which is quite simple.
To run any V8 tests, I would just use the test runner of V8 like what I would do when I work on V8 itself. For example to run the
CodeCache test case in API tests:
deps/v8/tools/run-tests.py --outdir out.gn/x64.debug 'cctest/test-api/CodeCache'
The tests do not have to be run by the python test runner. The test runner just knows how to find tests with the patterns given and invoke the tests with the correct command. You can also use the
--verbose flag in the test runner to see the actual commands and run those instead. For instance the command used to run the test case above is:
deps/v8/out.gn/x64.debug/cctest test-api/CodeCache --random-seed=-1132920576 --nohard-abort --enable-slow-asserts --verify-heap
In case you have not run V8 tests before - the entire V8 test suite is enormous and takes very long to run. I usually only run a subset of the tests that are related to my changes locally.
These days I prefer to use the lldb plugin of VS code to debug C++ programs.
To trigger the code path I want to debug, in the debugger configuration, write
This gives me a regular IDE debugging experience.
Of course you can also use the gdb or lldb console to debug the tests. I wrote a blog post a while back on some tricks you can use to debug V8 with these debuggers.
On a side note, in the Node.js repository we currently use https://ci.nodejs.org/job/node-test-commit-v8-linux/ in the Jenkins CI to run V8 tests whenever there is a patch to update the fork in
# Build deps/v8