Skip to content

Commit 52f768d

Browse files
authored
chore(debug): add product-specific extension host configs (#28)
1 parent 72a8a69 commit 52f768d

4 files changed

Lines changed: 290 additions & 9 deletions

File tree

.vscode/launch-extension-host.ps1

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
param(
2+
[Parameter(Mandatory = $true)]
3+
[ValidateSet("stable", "insiders")]
4+
[string] $Quality,
5+
6+
[Parameter(Mandatory = $true)]
7+
[int] $Port,
8+
9+
[Parameter(Mandatory = $true)]
10+
[string] $Workspace
11+
)
12+
13+
$ErrorActionPreference = "Stop"
14+
15+
switch ($Quality) {
16+
"stable" {
17+
$cli = "code"
18+
$installHint = "Shell Command: Install 'code' command in PATH"
19+
}
20+
"insiders" {
21+
$cli = "code-insiders"
22+
$installHint = "Shell Command: Install 'code-insiders' command in PATH"
23+
}
24+
}
25+
26+
if (-not (Get-Command $cli -ErrorAction SilentlyContinue)) {
27+
[Console]::Error.WriteLine("Missing '$cli' in PATH.`nInstall it from the target VS Code Command Palette:`n $installHint`nThen restart the terminal and try again.")
28+
exit 127
29+
}
30+
31+
function Get-ProcessCommandLine {
32+
param([int] $ProcessId)
33+
34+
try {
35+
$processInfo = Get-CimInstance Win32_Process -Filter "ProcessId = $ProcessId"
36+
return $processInfo.CommandLine
37+
} catch {
38+
return ""
39+
}
40+
}
41+
42+
try {
43+
$connections = @(Get-NetTCPConnection -LocalPort $Port -State Listen -ErrorAction SilentlyContinue)
44+
} catch {
45+
Write-Warning "Get-NetTCPConnection is unavailable; skipping stale inspector cleanup for port $Port."
46+
$connections = @()
47+
}
48+
49+
function Test-PortListening {
50+
try {
51+
return [bool](Get-NetTCPConnection -LocalPort $Port -State Listen -ErrorAction SilentlyContinue)
52+
} catch {
53+
return $false
54+
}
55+
}
56+
57+
function Wait-ForPortRelease {
58+
for ($attempt = 0; $attempt -lt 10; $attempt++) {
59+
if (-not (Test-PortListening)) {
60+
return
61+
}
62+
Start-Sleep -Milliseconds 200
63+
}
64+
65+
[Console]::Error.WriteLine("Port $Port is still in use after stopping stale extension host processes.")
66+
exit 1
67+
}
68+
69+
$processIds = @($connections | ForEach-Object { $_.OwningProcess } | Where-Object { $_ } | Sort-Object -Unique)
70+
$stoppedProcess = $false
71+
72+
foreach ($processId in $processIds) {
73+
$commandLine = Get-ProcessCommandLine -ProcessId $processId
74+
75+
if ([string]::IsNullOrWhiteSpace($commandLine)) {
76+
[Console]::Error.WriteLine("Port $Port is already used by PID $processId, but its command line could not be inspected.`nRefusing to stop it automatically.")
77+
exit 1
78+
}
79+
80+
$isExtensionHost = $commandLine -like "*--inspect=127.0.0.1:$Port*" `
81+
-or $commandLine -like "*--inspect-brk=127.0.0.1:$Port*" `
82+
-or $commandLine -like "*--inspect=localhost:$Port*" `
83+
-or $commandLine -like "*--inspect-brk=localhost:$Port*"
84+
85+
if ($isExtensionHost) {
86+
Stop-Process -Id $processId -Force -ErrorAction SilentlyContinue
87+
$stoppedProcess = $true
88+
continue
89+
}
90+
91+
[Console]::Error.WriteLine("Port $Port is already used by PID $processId, but it does not look like a VS Code extension host:`n$commandLine`nRefusing to stop it automatically.")
92+
exit 1
93+
}
94+
95+
if ($stoppedProcess) {
96+
Wait-ForPortRelease
97+
}
98+
99+
& $cli `
100+
--new-window `
101+
"--inspect-extensions=$Port" `
102+
"--extensionDevelopmentPath=$Workspace" `
103+
$Workspace
104+
105+
if ($LASTEXITCODE) {
106+
exit $LASTEXITCODE
107+
}

.vscode/launch-extension-host.sh

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
usage() {
5+
cat >&2 <<'EOF'
6+
Usage: launch-extension-host.sh <stable|insiders> <port> <workspace>
7+
EOF
8+
}
9+
10+
quality="${1:-}"
11+
port="${2:-}"
12+
workspace="${3:-}"
13+
14+
if [ -z "$quality" ] || [ -z "$port" ] || [ -z "$workspace" ]; then
15+
usage
16+
exit 2
17+
fi
18+
19+
case "$quality" in
20+
stable)
21+
cli="code"
22+
install_hint="Shell Command: Install 'code' command in PATH"
23+
;;
24+
insiders)
25+
cli="code-insiders"
26+
install_hint="Shell Command: Install 'code-insiders' command in PATH"
27+
;;
28+
*)
29+
usage
30+
exit 2
31+
;;
32+
esac
33+
34+
if ! command -v "$cli" >/dev/null 2>&1; then
35+
cat >&2 <<EOF
36+
Missing '$cli' in PATH.
37+
Install it from the target VS Code Command Palette:
38+
$install_hint
39+
Then restart the terminal and try again.
40+
EOF
41+
exit 127
42+
fi
43+
44+
is_port_listening() {
45+
lsof -tiTCP:"$port" -sTCP:LISTEN >/dev/null 2>&1
46+
}
47+
48+
wait_for_port_release() {
49+
for _ in 1 2 3 4 5 6 7 8 9 10; do
50+
if ! is_port_listening; then
51+
return 0
52+
fi
53+
sleep 0.2
54+
done
55+
56+
echo "Port $port is still in use after stopping stale extension host processes." >&2
57+
return 1
58+
}
59+
60+
if command -v lsof >/dev/null 2>&1; then
61+
stopped_process=false
62+
pids="$(lsof -tiTCP:"$port" -sTCP:LISTEN || true)"
63+
for pid in $pids; do
64+
command_line="$(ps -p "$pid" -o command= 2>/dev/null || true)"
65+
case "$command_line" in
66+
*"--inspect=127.0.0.1:$port"*|*"--inspect-brk=127.0.0.1:$port"*|*"--inspect=localhost:$port"*|*"--inspect-brk=localhost:$port"*)
67+
kill "$pid" 2>/dev/null || true
68+
stopped_process=true
69+
;;
70+
"")
71+
cat >&2 <<EOF
72+
Port $port is already used by PID $pid, but its command line could not be inspected.
73+
Refusing to stop it automatically.
74+
EOF
75+
exit 1
76+
;;
77+
*)
78+
cat >&2 <<EOF
79+
Port $port is already used by PID $pid, but it does not look like a VS Code extension host:
80+
$command_line
81+
Refusing to stop it automatically.
82+
EOF
83+
exit 1
84+
;;
85+
esac
86+
done
87+
88+
if [ "$stopped_process" = true ]; then
89+
wait_for_port_release
90+
fi
91+
else
92+
echo "Warning: lsof is not available; skipping stale inspector cleanup for port $port." >&2
93+
fi
94+
95+
"$cli" \
96+
--new-window \
97+
"--inspect-extensions=$port" \
98+
"--extensionDevelopmentPath=$workspace" \
99+
"$workspace"

.vscode/launch.json

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,47 @@
22
"version": "0.2.0",
33
"configurations": [
44
{
5-
"name": "Run Extension (Insiders)",
5+
"name": "Run Extension (Current VS Code)",
66
"type": "extensionHost",
77
"request": "launch",
88
"args": [
9-
"--extensionDevelopmentPath=${workspaceFolder}"
9+
"--extensionDevelopmentPath=${workspaceFolder}",
10+
"${workspaceFolder}"
1011
],
1112
"outFiles": [
1213
"${workspaceFolder}/out/**/*.js"
1314
],
1415
"preLaunchTask": "npm: watch"
1516
},
1617
{
17-
"name": "Run Extension (Stable)",
18+
"name": "Run Extension (Insiders via CLI)",
1819
"type": "node",
19-
"request": "launch",
20-
"runtimeExecutable": "/Applications/Visual Studio Code.app/Contents/MacOS/Electron",
21-
"runtimeArgs": [
22-
"--extensionDevelopmentPath=${workspaceFolder}",
23-
"${workspaceFolder}"
24-
]
20+
"request": "attach",
21+
"port": 9333,
22+
"timeout": 30000,
23+
"continueOnAttach": true,
24+
"skipFiles": [
25+
"<node_internals>/**"
26+
],
27+
"outFiles": [
28+
"${workspaceFolder}/out/**/*.js"
29+
],
30+
"preLaunchTask": "Launch Extension Host (Insiders CLI)"
31+
},
32+
{
33+
"name": "Run Extension (Stable via CLI)",
34+
"type": "node",
35+
"request": "attach",
36+
"port": 9334,
37+
"timeout": 30000,
38+
"continueOnAttach": true,
39+
"skipFiles": [
40+
"<node_internals>/**"
41+
],
42+
"outFiles": [
43+
"${workspaceFolder}/out/**/*.js"
44+
],
45+
"preLaunchTask": "Launch Extension Host (Stable CLI)"
2546
}
2647
]
2748
}

.vscode/tasks.json

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,60 @@
1010
"reveal": "silent"
1111
},
1212
"group": "build"
13+
},
14+
{
15+
"label": "Launch Extension Host (Insiders CLI)",
16+
"type": "shell",
17+
"command": "bash",
18+
"args": [
19+
"${workspaceFolder}/.vscode/launch-extension-host.sh",
20+
"insiders",
21+
"9333",
22+
"${workspaceFolder}"
23+
],
24+
"windows": {
25+
"command": "powershell",
26+
"args": [
27+
"-NoProfile",
28+
"-ExecutionPolicy",
29+
"Bypass",
30+
"-File",
31+
"${workspaceFolder}/.vscode/launch-extension-host.ps1",
32+
"insiders",
33+
"9333",
34+
"${workspaceFolder}"
35+
]
36+
},
37+
"dependsOn": "npm: watch",
38+
"dependsOrder": "sequence",
39+
"problemMatcher": []
40+
},
41+
{
42+
"label": "Launch Extension Host (Stable CLI)",
43+
"type": "shell",
44+
"command": "bash",
45+
"args": [
46+
"${workspaceFolder}/.vscode/launch-extension-host.sh",
47+
"stable",
48+
"9334",
49+
"${workspaceFolder}"
50+
],
51+
"windows": {
52+
"command": "powershell",
53+
"args": [
54+
"-NoProfile",
55+
"-ExecutionPolicy",
56+
"Bypass",
57+
"-File",
58+
"${workspaceFolder}/.vscode/launch-extension-host.ps1",
59+
"stable",
60+
"9334",
61+
"${workspaceFolder}"
62+
]
63+
},
64+
"dependsOn": "npm: watch",
65+
"dependsOrder": "sequence",
66+
"problemMatcher": []
1367
}
1468
]
1569
}

0 commit comments

Comments
 (0)