<#23169 pants executing pants via subprocess hangs...
# github-notifications
q
#23169 pants executing pants via subprocess hangs when sandboxer enabled Issue created by cburroughs So to get it out of the way, why we do this has a convoluted history and maybe we should not, but in a few places do
pants run /some/python/code.py
that itself does something like
subprocess.check_output('pants run something/else.py
. When the sandboxer is is enabled, this hangs (see below). We can work around it by setting
env["PANTS_SANDBOXER"] = "false"
which is fine for these corner cases.
Copy code
#!/usr/bin/env bash
set -euo pipefail

cd $(mktemp -d)

cat > pants.toml <<EOF
[GLOBAL]
pants_version = "2.31.0"

backend_packages = [
  "pants.backend.python",
]

[python]
interpreter_constraints = ["==3.11.*"]
EOF

mkdir hello caller

cat > hello/hello.py <<EOF
print("Hello, world!")
EOF

cat > hello/BUILD <<EOF
python_sources()
EOF

cat > caller/caller.py <<'EOF'
import os
import subprocess
import sys

env = {**os.environ, "PANTS_CONCURRENT": "true"}
result = subprocess.run(
    ["pants", "run", "hello/hello.py"],
    capture_output=True,
    text=True,
    env=env,
)
print(result.stdout, end="")
print(result.stderr, end="", file=sys.stderr)
sys.exit(result.returncode)
EOF

cat > caller/BUILD <<EOF
python_sources()
EOF

echo "=== Step 1: pants run hello/hello.py (baseline) ==="
pants run hello/hello.py
echo

echo "=== Step 2: pants run caller/caller.py (subprocess calls pants run) ==="
pants run caller/caller.py
echo

echo "=== Step 3: same as step 2 but with sandboxer enabled ==="
echo "    (expected: hangs)"
timeout 30 env PANTS_SANDBOXER=true pants run caller/caller.py || {
    exit_code=$?
    if [ $exit_code -eq 124 ]; then
        echo "CONFIRMED: hung for 30s and was killed by timeout"
    else
        echo "Exited with code $exit_code"
    fi
}
Copy code
$ bash reproduce.sh 
=== Step 1: pants run hello/hello.py (baseline) ===
15:23:51.80 [INFO] Initializing scheduler...
15:23:51.97 [INFO] Scheduler initialized.
15:23:54.37 [INFO] Completed: Scheduling: Find interpreter for constraints: CPython==3.11.*
15:23:54.39 [INFO] Completed: Scheduling: Building local_dists.pex
15:23:54.41 [INFO] Completed: Scheduling: Test binary /usr/bin/bash.
15:23:54.41 [INFO] Completed: Scheduling: Test binary /bin/bash.
15:23:54.43 [INFO] Completed: Scheduling: Building hello.pex
Hello, world!

=== Step 2: pants run caller/caller.py (subprocess calls pants run) ===
15:23:54.76 [INFO] Completed: Scheduling: Building caller.pex
Hello, world!
15:23:58.38 [INFO] Completed: Scheduling: Find interpreter for constraints: CPython==3.11.*
15:23:58.38 [INFO] Starting: Building local_dists.pex
15:23:59.63 [INFO] Completed: Building local_dists.pex
15:23:59.63 [INFO] Completed: Scheduling: Building local_dists.pex
15:23:59.64 [INFO] Completed: Scheduling: Test binary /bin/bash.
15:23:59.64 [INFO] Completed: Scheduling: Test binary /usr/bin/bash.
15:23:59.65 [INFO] Starting: Building hello.pex
15:24:00.88 [INFO] Completed: Building hello.pex
15:24:00.88 [INFO] Completed: Scheduling: Building hello.pex

=== Step 3: same as step 2 but with sandboxer enabled ===
    (expected: hangs)
15:24:01.26 [INFO] Initialization options changed: sandboxer: False -> True. Reinitializing scheduler...
15:24:01.55 [INFO] Using sandboxer socket path /tmp/run/pants/874749acbb00656d/sandboxer.sock
15:24:01.63 [INFO] Scheduler initialized.
15:24:03.49 [INFO] Completed: Scheduling: Find interpreter for constraints: CPython==3.11.*
15:24:03.49 [INFO] Completed: Scheduling: Building local_dists.pex
15:24:03.51 [INFO] Completed: Scheduling: Test binary /usr/bin/bash.
15:24:03.52 [INFO] Completed: Scheduling: Test binary /bin/bash.
15:24:03.52 [INFO] Completed: Scheduling: Building caller.pex
CONFIRMED: hung for 30s and was killed by timeout
Traceback (most recent call last):
  File "/tmp/pants-sandbox-Ascl58/./.cache/pex_root/venvs/3/68d48f7221c912ec582b9a8e3729214fdbb0f09c/73c7d7c618fac01449fa6e57a21210c0eb8a8f21/pex", line 380, in <module>
    boot(
  File "/tmp/pants-sandbox-Ascl58/./.cache/pex_root/venvs/3/68d48f7221c912ec582b9a8e3729214fdbb0f09c/73c7d7c618fac01449fa6e57a21210c0eb8a8f21/pex", line 355, in boot
    runpy.run_module(module_name, run_name="__main__", alter_sys=True)
  File "<frozen runpy>", line 226, in run_module
  File "<frozen runpy>", line 98, in _run_module_code
  File "<frozen runpy>", line 88, in _run_code
  File "/tmp/pants-sandbox-Ascl58/./caller/caller.py", line 6, in <module>
    result = subprocess.run(
             ^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/subprocess.py", line 550, in run
    stdout, stderr = process.communicate(input, timeout=timeout)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/subprocess.py", line 1209, in communicate
    stdout, stderr = self._communicate(input, endtime, timeout)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/subprocess.py", line 2115, in _communicate
    ready = selector.select(timeout)
            ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/selectors.py", line 415, in select
    fd_event_list = self._selector.poll(timeout)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyboardInterrupt
(An LLM wrote the
reproduce.sh
after git bisect pointed to this starting when we enabled the sandboxer) pantsbuild/pants