Consider you want to debug a test case of the JDK like serviceability/AsyncGetCallTrace. This test, and many others, are implemented using the Regression Test Harness for the JDK (jtreg):
jtreg is the test harness used by the JDK test framework. This framework is intended primarily for regression tests. It can also be used for unit tests, functional tests, and even simple product tests — in other words, just about any type of test except a conformance test, which belong in a TCK.
As well as API tests, jtreg is designed to be well suited for running both positive and negative compiler tests, simple manual GUI tests, and (when necessary) tests written in shell script. jtreg also takes care of compiling tests as well as executing them, so there is no need to precompile any test classes.
JTREG is quite powerful, allowing you to combine C++ and Java code, but it makes debugging the C++ parts hard. You could, of course, just debug using printf. This works but also requires lots of recompiles during every debugging session. Attaching a debugger like gdb is possible but rather cumbersome, especially if you want to bring this into a launch.json to enable debugging in VSCode.
git clone https://github.com/parttimenerd/vsreg
Then pass the make test command to it, which you use to run the test that you want to debug:
vsreg/vsreg.py “ASGCT debug” — make test TEST=jtreg:test/hotspot/jtreg/serviceability/AsyncGetCallTrace JTREG=”VERBOSE=all”
Be sure always to pass JTREG=”VERBOSE=all”: vsreg executes the command, parses the output, and adds a launch config with the label “ASGCT debug” to the .vscode/launch.json file in the current folder.
The utility is MIT licensed and only tested on Linux.
You’re now able to select “ASGCT debug” in “Run and Debug”:
You can choose the launch config and run the jtreg test with a debugger:
The debugger pauses on a segfault, but there are always a few at the beginning of the execution that can safely be ignored. We can use the program’s pause to add a break-point at an interesting line. After hitting the break-point, we’re able to inspect the local variables…
… and do things like stepping over a line:
If you want to recompile the tests, use make images test-image. You can add a task to your .vscode/tasks.json file and pass the label to the –build-task option:
“label”: “Make test-image”,
“args”: [“images”, “test-image”],
“problemMatcher”: [“$gcc”] }
vsreg has a few options:
usage: vsreg.py [-h] [-t TEMPLATE] [-d] [-b TASK] LABEL COMMAND [COMMAND …]
Create a debug launch config for a JTREG test run
LABEL Label of the config
COMMAND Command to run
-h, –help show this help message and exit
-t TEMPLATE, –template TEMPLATE
Template to use for the launch config,
or name of file without suffix in
-d, –dry-run Only print the launch config
-b TASK, –build-task TASK
Task to run before the command
An example template looks like this:
“description”: “Enable pretty-printing for gdb”,
“description”: “The new process is debugged after a fork. The parent process runs unimpeded.”,
“text”: “-gdb-set follow-fork-mode child”,
vsreg fills in $NAME (with the label), program (with the used Java binary), args, cwd, environment and preLaunchTask.
vsreg is one of these utilities that solve one specific itch: I hope it also helps others; feel free to contribute to this tool, adding new templates and other improvements on GitHub.
The tool is inspired by bear, “a tool that generates a compilation database for clang tooling.”
If you’re wondering why I have a renewed interest in debugging: I’m working full-time on a new proof-of-concept implementation related to JEP 435.
The post Debugging OpenJDK Tests in VSCode (Without Losing Your Mind) appeared first on foojay.