Skip to content

Support startDebugging DAP reverse request #2244

@jborean93

Description

@jborean93

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-EnhancementA feature request (enhancement).Needs: TriageMaintainer attention needed!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions