diff --git a/examples/ChildDebugSessionAttach.ps1 b/examples/ChildDebugSessionAttach.ps1 new file mode 100644 index 0000000000..c06a57f2a7 --- /dev/null +++ b/examples/ChildDebugSessionAttach.ps1 @@ -0,0 +1,22 @@ +# Example on how Start-DebugAttachSession can be used to attach to another +# process. This launches a child process that runs ChildDebugSessionTarget.ps1 +# but it can be adapted to attach to any other PowerShell process that is +# either already running or started like this example. To test this example, +# add a breakpoint to ChildDebugSessionTarget.ps1, select the +# 'PowerShell Launch Current File' configuration and press F5. + +$pipeName = "TestPipe-$(New-Guid)" +$scriptPath = Join-Path -Path $PSScriptRoot -ChildPath 'ChildDebugSessionTarget.ps1' + +$procParams = @{ + FilePath = 'pwsh' + ArgumentList = ('-CustomPipeName {0} -File "{1}" -WaitForAttach' -f $pipeName, $scriptPath) + PassThru = $true +} +$proc = Start-Process @procParams + +Start-DebugAttachSession -CustomPipeName $pipeName -RunspaceId 1 + +# We need to ensure this debug session stays alive until the process exits. If +# we exit early then the child debug session will also exit. +$proc | Wait-Process diff --git a/examples/ChildDebugSessionTarget.ps1 b/examples/ChildDebugSessionTarget.ps1 new file mode 100644 index 0000000000..ed4c9f2a6a --- /dev/null +++ b/examples/ChildDebugSessionTarget.ps1 @@ -0,0 +1,31 @@ +[CmdletBinding()] +param ( + [Parameter()] + [switch] + $WaitForAttach +) + +if ($WaitForAttach) { + # For an attach request we need to wait for the debug pipe runspace to be + # opened before continuing. There is no builtin way to do this so we + # poll the runspace list until a new one is created. + $runspaces = Get-Runspace + while ($true) { + if (Get-Runspace | Where-Object { $_.Id -notin $runspaces.Id }) { + break + } + Start-Sleep -Seconds 1 + } + + # Windows PowerShell 5.1 will not sync breakpoints until the debugger has + # stopped at least once. We use Wait-Debugger to make this happen. + if ($PSVersionTable.PSVersion -lt '6.0') { + Wait-Debugger + } + else { + Start-Sleep -Seconds 1 # Give the debugger time to sync breakpoints + } +} + +$processInfo = "This process is running with PID $PID and has runspace ID $([Runspace]::DefaultRunspace.Id)" +Write-Host $processInfo # Place breakpoint here