java_binary
outputs a wrapper script that includes a --debug[=<port>]
flag that will tell the JVM to wait for debugging. For example:
bazel run //:my-target -- --debug
Another strategy that gives more direct control and shows you how your Starlark rule is running the binary is to run the build with --subcommands
. With this Bazel will print out all the commands it runs during the build. Then find the command line corresponding to the invocation of the java_binary
you're interested in. Then you can copy/paste that command (including the cd
part) and modify it to include the debug flags, and debug it as you would any other process.
For example:
bazel build //:some-target-using-the-binary --subcommands=pretty_print
This should output something like:
INFO: Analyzed target //:some-target-using-the-binary (...).
INFO: Found 1 target...
SUBCOMMAND: # //:some-target-using-the-binary [action '...']
(cd /private/var/tmp/_bazel_username/hash/execroot/core && \
exec env - \
LC_CTYPE=en_US.UTF-8 \
LD_LIBRARY_PATH='' \
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin \
bazel-out/exec-config/bin/path/to/binary/package/TheBinaryToDebug \
@bazel-out/target-config/bin/some-target-using-the-binary-0.params)
--sandbox_debug
may be needed to prevent Bazel from deleting the execution root sandbox.
Note also that --subcommands
will only print the commands that are actually executed during the build, so a fully cached / fully incremental build will print nothing. You may need to do a clean
, or delete some of the outputs of the action you're interested in so that bazel runs that command.
bazel run //:my-target -- --debug
– Karlise