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.

What’s the difference between deps/v8 and the upstream V8?

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.

The maintenance processes of deps/v8 has been documented here, though now we have automated most of the work in our custom git command git node v8 thanks to @targos, et al…

Building V8 tests for deps/v8

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.

The 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 gclient from depot_tools to manage the dependencies and therefore the V8 directory must contains a valid git tree.

The script 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

1
tools/make-v8.sh x64.debug

Which builds deps/v8 in deps/v8/out.gn/x64.debug with the configuration:

1
2
3
4
5
is_debug = true
target_cpu = "x64"
v8_enable_backtrace = true
v8_enable_slow_dchecks = true
v8_optimized_debug = false

If you really want to customize the build process, just take a look at the make-v8.sh script, which is quite simple.

Running V8 tests in deps/v8

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:

1
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:

1
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.

Debugging deps/v8

These days I prefer to use the lldb plugin of VS code to debug C++ programs.

1
2
cd deps/v8
code .

To trigger the code path I want to debug, in the debugger configuration, write

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "cctest",
"program": "${workspaceFolder}/out.gn/x64.debug/cctest",
"args": [
"test-api/CodeCache"
],
"cwd": "${workspaceFolder}"
}
]
}

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.

V8 tests in the Node.js CI

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 deps/v8.

Summary

1
2
3
4
# Build deps/v8
tools/make-v8.sh x64.debug
# Run the 'CodeCache' case in test/cctest/test-api.cc of the V8 test suite
deps/v8/tools/run-tests.py --outdir out.gn/x64.debug 'cctest/test-api/CodeCache'