Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add starlark debugger python script interface #24814

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
load("@com_google_protobuf//bazel:java_proto_library.bzl", "java_proto_library")
load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
load("@com_google_protobuf//bazel:py_proto_library.bzl", "py_proto_library")
load("//tools/build_rules:utilities.bzl", "java_library_srcs")

package(default_visibility = ["//src:__subpackages__"])
Expand Down Expand Up @@ -28,3 +29,18 @@ proto_library(
srcs = ["starlark_debugging.proto"],
visibility = ["//visibility:public"],
)

py_proto_library(
name = "starlark_debugging_py_proto",
deps = [":starlark_debugging_proto"],
visibility = ["//visibility:public"],
)

# Used by tools/starlarkdebug
py_library(
name = "starlark_debugging_py_proto_library",
srcs = [":starlark_debugging_py_proto"],
deps = ["@com_google_protobuf//:protobuf_python"],
imports = ["."], # Avoid very long import path
visibility = ["//visibility:public"],
)
48 changes: 48 additions & 0 deletions tools/starlarkdebug/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright 2018 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

package(default_visibility = ["//visibility:public"])

py_library(
name = "debugger",
srcs = ["debugger.py"],
deps = [
"//src/main/java/com/google/devtools/build/lib/starlarkdebug/proto:starlark_debugging_py_proto_library",
],
imports = ["."],
)

py_binary(
name = "trace",
srcs = ["trace.py"],
deps = [":debugger"],
)

py_library(
name = "python_sandbox",
srcs = [
"testsupport/__init__.py",
"testsupport/python_sandbox.py",
],
imports = ["."],
)

py_test(
name = "debugger_test",
srcs = ["debugger_test.py"],
deps = [
":debugger",
":python_sandbox",
],
)
70 changes: 70 additions & 0 deletions tools/starlarkdebug/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Starlark debug

This is the debugger and trace tool presented at Build Meetup 2021 (tutorial in video):
https://www.youtube.com/watch?v=D7-BbD6QjeU

Note that this is experimental and may break due to lack of verification. That
said it have "just worked" for three years (except known issues) using
Bazel ranging from 4 to 8, probably due to low activity in the debugger
protocol.

## Preconditions

Since you cannot start python in interactive mode using `bazel run` you need
to build the starlark_debugger protobuf interface and then either copy it
alongside the debugger tool or pass it's location in the PYTHONPATH
environment variable.

```
STARLARK_DEBUGGER_PROTO=src/main/java/com/google/devtools/build/lib/starlarkdebug/proto
bazel build //${STARLARK_DEBUGGER_PROTO}:starlark_debugging_py_proto
export PYTHONPATH="$(realpath bazel-bin/${STARLARK_DEBUGGER_PROTO})"
python3 tools/starlarkdebug/debugger.py --help
```

Note that above will use bazel to build the python interface but uses a local
python installation to run the debugger. This installation needs the protobuf
package installed which may fail due to mismatching protobuf versions in which
you can:
* Create a virtual python environment and install the protobuf version bazel uses there
* Use protoc tool to generate the debugging interface with your version

## Setup bazel for debugging

Bazel needs to be running with the debugger active for the debugger tool to run
otherwise you will get a `connection refused` message or similar.

Execute the command to debug as normal but add a few extra build flags for
it to wait for the debugger tool to connect. Here is a sample bazelrc file:
```
build:starlark_debug # Enable the skylark debugger
build:starlark_debug --experimental_skylark_debug
build:starlark_debug --experimental_skylark_debug_server_port=7200
build:starlark_debug --keep_state_after_build=false
```

You can optionally add `--build=false` to the command
line as the build phase is not relevant for the starlark debug.

Note if bazel exits immediately without triggering a breakpoint you may
need to run `bazel shutdown` to clear the analysis cache. Disabling the
`keep_state_after_build` flag (as in the example above) will prevent bazel
to cache the execution in memory.

## Interactive debugger

The easiest usage as shown in the tutorial is to first execute the command
to debug as normal with additional debug flags and then execute the debugger
in interactive mode in another terminal while bazel waits for a debugger to
attach.

```
python3 -i tools/starlarkdebug/debugger.py
```

## TODO:s (good place to chime in)

* Sandboxed tests for the StarlarkDebugger API
with sandboxed means not allowing python code to have side effects
* Integration test with the Starlark debugger
* Could we interact with the java debugger as well?
Loading