Files
Norio Nomura 77f5a1ff79 Add hack/codesign/debugserver that wraps the LLDB debugserver to codesign the target executable.
# `hack/codesign/debugserver`

This script wraps the LLDB `debugserver` to `codesign` the target executable.
This is needed for [Delve](https://github.com/go-delve/delve) to work properly
on macOS with the virtualization framework.

## How to use this script with Delve

### Use `DELVE_DEBUGSERVER_PATH` environment variable

Override `debugserver` by setting the `DELVE_DEBUGSERVER_PATH` environment variable.
Ref: [Environment variables - Using Delve](https://github.com/go-delve/delve/blob/master/Documentation/usage/README.md#environment-variables)

e.g. in `.vscode/launch.json`:
```jsonc
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "hostagent for input instance",
            "type": "go",
            "request": "launch",
            "mode": "debug",
            // Use integratedTerminal to stop using ctrl+C
            "console": "integratedTerminal",
            "program": "${workspaceFolder}/cmd/limactl",
            "buildFlags": [
                "-ldflags=-X github.com/lima-vm/lima/pkg/version.Version=2.0.0-alpha.0",
            ],
            "env": {
                "CGO_ENABLED": "1",
                "DELVE_DEBUGSERVER_PATH": "${workspaceFolder}/hack/codesign/debugserver",
                "LIMA_SSH_PORT_FORWARDER": "true",
            },
            "cwd": "${userHome}/.lima/${input:targetInstance}",
            "args": [
                "--debug",
                "hostagent",
                "--pidfile", "ha.pid",
                "--socket", "ha.sock",
                "--guestagent", "${workspaceFolder}/_output/share/lima/lima-guestagent.Linux-aarch64",
                "${input:targetInstance}"
            ],
		},
    ],
    "inputs": [
        {
            "id": "targetInstance",
            "type": "promptString",
            "description": "Input target instance parameter for `limactl` command",
        }
    ]
}
```

### Override `debugserver` in the PATH

You can also override the `debugserver` in the PATH environment variable.

e.g. in `.vscode/launch.json`:
```diff
             "env": {
                 "CGO_ENABLED": "1",
-                "DELVE_DEBUGSERVER_PATH": "${workspaceFolder}/hack/codesign/debugserver",
+                "PATH": "${workspaceFolder}/hack/codesign:${env:PATH}",
             },
```

Signed-off-by: Norio Nomura <norio.nomura@gmail.com>
2025-09-20 20:47:48 +09:00

114 lines
4.0 KiB
Bash
Executable File

#!/bin/bash
# SPDX-FileCopyrightText: Copyright The Lima Authors
# SPDX-License-Identifier: Apache-2.0
# # `hack/codesign/debugserver`
#
# This script wraps the LLDB `debugserver` to `codesign` the target executable.
# This is needed for [Delve](https://github.com/go-delve/delve) to work properly
# on macOS with the virtualization framework.
#
# ## How to use this script with Delve
#
# ### Use `DELVE_DEBUGSERVER_PATH` environment variable
#
# Override `debugserver` by setting the `DELVE_DEBUGSERVER_PATH` environment variable.
# Ref: [Environment variables - Using Delve](https://github.com/go-delve/delve/blob/master/Documentation/usage/README.md#environment-variables)
#
# e.g. in `.vscode/launch.json`:
# ```jsonc
# {
# "version": "0.2.0",
# "configurations": [
# {
# "name": "hostagent for input instance",
# "type": "go",
# "request": "launch",
# "mode": "debug",
# // Use integratedTerminal to stop using ctrl+C
# "console": "integratedTerminal",
# "program": "${workspaceFolder}/cmd/limactl",
# "buildFlags": [
# "-ldflags=-X github.com/lima-vm/lima/pkg/version.Version=2.0.0-alpha.0",
# ],
# "env": {
# "CGO_ENABLED": "1",
# "DELVE_DEBUGSERVER_PATH": "${workspaceFolder}/hack/codesign/debugserver",
# "LIMA_SSH_PORT_FORWARDER": "true",
# },
# "cwd": "${userHome}/.lima/${input:targetInstance}",
# "args": [
# "--debug",
# "hostagent",
# "--pidfile", "ha.pid",
# "--socket", "ha.sock",
# "--guestagent", "${workspaceFolder}/_output/share/lima/lima-guestagent.Linux-aarch64",
# "${input:targetInstance}"
# ],
# },
# ],
# "inputs": [
# {
# "id": "targetInstance",
# "type": "promptString",
# "description": "Input target instance parameter for `limactl` command",
# }
# ]
# }
# ```
#
# ### Override `debugserver` in the PATH
#
# You can also override the `debugserver` in the PATH environment variable.
#
# e.g. in `.vscode/launch.json`:
# ```diff
# "env": {
# "CGO_ENABLED": "1",
# - "DELVE_DEBUGSERVER_PATH": "${workspaceFolder}/hack/codesign/debugserver",
# + "PATH": "${workspaceFolder}/hack/codesign:${env:PATH}",
# },
# ```
set -eu -o pipefail
script_dir="$(dirname "$0")"
# Codesign the target executable if vz.entitlements exists
entitlements="${script_dir}/../../vz.entitlements"
if [ -f "${entitlements}" ]; then
prev_arg=
for arg in "$@"; do
# find the target executable in the args next to "--"
if [ "${prev_arg}" = "--" ]; then
codesign --entitlements "${entitlements}" --force -s - -v "${arg}" || {
echo "error: codesign failed" >&2
exit 1
}
break
fi
prev_arg="${arg}"
done
fi
# Simulate how Delve locates debugserver
# https://github.com/go-delve/delve/blob/65a6830eb7f0b882e0c52df0ef9585945ed55470/pkg/proc/gdbserial/gdbserver.go#L103-L129
# 1. PATH (in this script, excluding the directory of this script to avoid recursion)
candidate_paths="$(echo "${PATH}" | tr ':' '\n' | grep --fixed-strings --invert-match --line-regexp "${script_dir}" | paste -sd: -)"
# 2. CommandLineTools LLDB path
CLT_path="/Library/Developer/CommandLineTools"
candidate_paths="${candidate_paths}:${CLT_path}/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/"
# 3. Xcode LLDB path (if Xcode is installed)
if developer_dir=$(xcode-select --print-path 2>/dev/null) && [ "${developer_dir}" != "${CLT_path}" ]; then
# Xcode is installed
candidate_paths="${candidate_paths}:${developer_dir}/../SharedFrameworks/LLDB.framework/Versions/A/Resources/"
fi
# Find debugserver in the candidate paths
debugserver=$(PATH="${candidate_paths}" command -v debugserver) || {
echo "error: debugserver not found" >&2
exit 1
}
# Execute debugserver with the original arguments
exec "${debugserver}" "$@"