-
Notifications
You must be signed in to change notification settings - Fork 237
Description
Prerequisites
- I have written a descriptive issue title.
- I have searched all issues to ensure it has not already been requested.
Summary
I would like to spawn multiple debug launch configurations through a single debug session. This allows me to start a single PowerShell script that might launch separate runspaces or processes that I want to debug without manually having to setup the launch configuration JSON, going to the debug tag, selecting the configuration, then clicking run.
The startDebugging request is a reverse request that can be sent by the DAP server to the DAP client to launch extra configuration options for the same debug type. This would allow the initial debugged script to be able to launch whatever debug session on demand rather than having to make the end user do all that manual work.
The scenario I have this in mind for is for a remote session where the remote runspace is configured with the script to run and will send back a startDebugging
request for VSCode to attach to that runspace before continuing on.
Proposed Design
My proposal is to implement this as a new function in PSES like the following:
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
using namespace System.Collections
using namespace System.Threading
using namespace System.Threading.Tasks
function Start-NewDebugSession {
<#
.EXTERNALHELP ..\PowerShellEditorServices.Commands-help.xml
#>
[OutputType([Task])]
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[ValidateSet('Attach', 'Launch')]
[string]
$Request,
[Parameter(Mandatory)]
[IDictionary]
$Configuration
)
# Var will be set by PSES in configurationDone before launching script
if (-not (Get-Variable -Name __psEditorServices_DebugServer -ErrorAction Ignore)) {
$err = [ErrorRecord]::new(
[Exception]::new("Cannot start a new debug session unless running in an existing debug session"),
"NotUnderDebugSession",
[ErrorCategory]::InvalidOperation,
$null)
$err.ErrorDetails = [ErrorDetails]::new("")
$err.ErrorDetails.RecommendedAction = 'Launch script with debugging'
$PSCmdlet.WriteError($err)
return
}
$config = $configuration.Clone()
# Must be true or else a deadlock occurs trying to launch
# in the currently busy terminal.
$config.createTemporaryIntegratedConsole = $true
$resp = $__psEditorServices_DebugServer.SendRequest(
"startDebugging",
@{
configuration = $config
request = $Request.ToLowerInvariant()
}
)
$task = $resp.Returning[object]([CancellationToken]::new($false))
# Maybe do this by default but have a `-NoWait` switch parameter
# while (-not $task.AsyncWaitHandle.WaitOne(300)) { }
# $null = $task.GetAwaiter().GetResult()
$task
}
The PSES will set/unset the variable in the runspace allowing the function to access it. Hopefully the $__
prefix will demonstrate that it should not be used by end users.
I'm not sure how to deal with the task that is created. In this implementation it's just returned so the user could await it if they want. I didn't await it in the function as the caller might need to do work between starting the debug session and when it would expect the response. For example starting an attach session on a custom named pipe might require the caller to wait for the connection and start streaming the data before expecting the startDebugging
response. There is no response data that is received back from the DAP client so the response is just an indication it processed the request.