programing

오류 시 디버거를 입력할 수 있는 방법이 있습니까?

newstyles 2023. 11. 5. 11:04

오류 시 디버거를 입력할 수 있는 방법이 있습니까?

오류에 대한 응답으로 PowerShell 디버거를 입력할 수 있는 방법이 있습니까?ErrorAction매개 변수에는 여러 값이 있지만 다음과 같은 것이 없습니다.Debug. 제가 원하는 것은 디버거를 중단점을 설정한 경우 열리듯이 열되되 오류가 발생할 때만 열 수 있도록 하는 것입니다(예를 들어,Write-Error).

편집 나는 약간의 설명을 해야 합니다.저는 주로 C# 개발자이고 파워셸을 처음 접하는 사람입니다. 제가 기대하는 것은 비주얼 스튜디오 디버거가 "처리되지 않은 예외"에 대해 제공하는 것과 유사한 동작입니다.PowerShell 명령에서 예외를 던지는 것이 더 일반적인 것으로 보이는 반면 사용자 지정 스크립트에서는 대부분 Write-Error를 사용하는 것으로 보입니다.저는 그 둘을 특별히 구별하고 싶지는 않지만, 둘 다 다루고 싶습니다.

트레버 설리번의 아래 답변은 당신이 사용할 수 있는Set-PSBreakpoint -Command Write-Error -Action { break; };그런 사건들을 잡는 데 도움이 되는 것 같습니다하지만 많은 경우에 실제로 명령어를 던지는 것이 제가 어기고 싶은 예외라는 것을 알게 되었습니다.로만 쿠즈민의 대답은 만약 당신이 설정한다면 효과가 있는 것처럼 보입니다.$ErrorActionPreference = "stop", 그런데 프로그램을 밟을 수 없다는 문제가 있는데 그 위치를 벗어나서 대본을 끝내는 것 같아요. 만약에.$ErrorActionPreference = "continue"그것은 나에게 효과가 없습니다.일반적으로 트랩은 중첩 범위에서 발생하는 유사한 문제가 있는 것으로 보이며, 이는 원하지 않습니다.

물론이야.를 사용하여 PowerShell에 조건부 중단점을 생성할 수 있습니다.Set-PSBreakpointcmdlet.다음 코드를 고려합니다.스크립트 파일로 저장하고 실행합니다.무슨 일이 일어나고 있는지 이해하는 데 도움이 되는 댓글이 줄을 잇습니다.

중단점에는 세 가지 유형이 있습니다.

  • 변수
  • 사령부

명령 중단점

이 코드 예제는 명령 중단점 유형을 사용하고 있습니다. 왜냐하면 중단점을 설정하도록 지시하기 때문입니다.Get-WmiObject명령들.특정 선 번호 또는 변수 중단점 유형을 번갈아 지정할 수 있습니다.당신은 사용합니다.-Action중단점을 설정할 조건을 지정하는 parameter.사용해야 합니다.break키워드를 입력합니다.-Action ScriptBlockPowerShell 스크립트의 실행을 일시 중지하도록 디버거에 지시합니다.

# 1. Reset $Error to $null
$WmiError = $null;

# 2. Clean up any existing breakpoints
Get-PSBreakpoint | Remove-PSBreakpoint;

# 3. Set breakpoint, but only on Get-WmiObject commands, when the $WmiError variable is not $null
Set-PSBreakpoint -Command Get-WmiObject -Action { if ($WmiError) { break; } };

# 4. Failed Get-WmiObject command
Get-WmiObject -Class Win32_NonExistentClass -ErrorVariable WmiError;

# 5. Successful Get-WmiObject command
#    PowerShell breaks here, because:
#     - It's a Get-WmiObject command
#     - The $WmiError variable is not null
Get-WmiObject -Class Win32_BIOS;

사용한다고 하셨으니까.Write-Error, 당신이 설정할 수 있는 것은PSBreakpoint…의 전화로Write-Error출현합니다.다음은 이를 수행하는 방법의 예입니다.

Set-PSBreakpoint -Command Write-Error -Action { break; };

꽤 쉽죠?

변수 중단점

이 예제에서는 변수를 사용합니다.PSBreakpoint입력합니다. 변수의 내용이 수정된 경우에만 입력합니다.사용할 수 있습니다.-Mode어떤 조건에서 변수 중단점이 적중되었는지 결정하는 매개변수:

  • 읽어주세요
  • 읽기쓰기
  • 쓰기

코드:

# 1. Clean up any existing breakpoints
Get-PSBreakpoint | Remove-PSBreakpoint;

# 2. Set a PSBreakpoint of type "variable" on a variable named "Data," but only when it has changed
Set-PSBreakpoint -Action { Write-Host -ForegroundColor Green -Object ('The $Data variable has changed! Value is: {0}' -f $Data); break; } -Variable Data -Mode Write;

# 3. No break on this line, because we are not changing the variable
Write-Host -Object $Data;

# 4. Execution is paused on this line, because we change the variable
$Data = 1;

선 구분점

이제 변수와 명령을 살펴봤으니 PSBreakpointtypes, 탐색할 마지막 중단점 유형은 line breakpoint입니다.만약 당신이 아래의 코드를 복사/붙여넣고, 저장하고, 실행한다면, 코드가 Write-Host 라인에서 깨지는 것을 볼 수 있을 것입니다(실제로는 9번 라인입니다). 그러나 다음과 같은 경우에만.Name소유물$Service변수가 다음과 같습니다.WinRM. 그것이 그의 조건부 진술입니다.-Action매개변수의ScriptBlock정의합니다.

# 1. Clean up any existing breakpoints
Get-PSBreakpoint | Remove-PSBreakpoint;

# 2. Set a PSBreakpoint of type "line" on line #8, but only if the $Service variable's Name property equals 'winrm'
Set-PSBreakpoint -Action { if ($Service.Name -eq 'winrm') { break; } } -Line 9 -Script $MyInvocation.MyCommand.Path;

# 3. Get a list of Windows Services and iterate over them
foreach ($Service in (Get-WmiObject -Class Win32_Service)) {
    Write-Host -Object ('Service name is: {0}' -f $Service.Name);
}

네, 오류 시 디버거에 침입하는 간단한 방법이 있습니다.오류가 발생할 때마다 변수는StackTrace업데이트됩니다.그래서 저는 다음과 같은 방법을 사용합니다. 프로필에는 다음과 같은 두 가지 기능(스위치)이 있습니다.

<#
.Synopsis
    Sets $StackTrace breakpoint
.Link
    rbps
#>
function sbps {
    $null = Set-PSBreakpoint -Variable StackTrace -Mode Write
}

<#
.Synopsis
    Removes $StackTrace breakpoint
.Link
    sbps
#>
function rbps {
    Get-PSBreakpoint -Variable StackTrace | Remove-PSBreakpoint
}

첫 번째가 호출되면 오류에 대한 디버거 침입이 실제로 활성화됩니다.오류 시StackTrace가 기록되고 중단점이 트리거됩니다.

두 번째 함수는 오류 발생 시 디버거에 침입합니다.

대부분의 경우에 이 방법은 저에게 효과적입니다.


갱신하다

프로파일 기능 없이 이 기법을 사용하려면 Debug-Error.ps1과 같은 도우미 스크립트를 사용할 수 있습니다.이상적으로 경로에 위치하여 명령을 수행해야 합니다.Debug-Error그리고.Debug-Error -Off언제든지 사용 가능합니다.

블로그 게시물도 참조하십시오.


Connect 관련 티켓 몇 장:

변수에 중단점을 설정한 다음 변수의 값을 변경하는 함수를 만들 수 있습니다.

function Debug-Here {
    if(!(Get-PSBreakpoint -Variable DebugHereCount)) {
        $SCRIPT:DebugHere= Set-PSBreakpoint -Variable DebugHereCount
    }
    $DebugHereCount++
}

그런 다음 트랩의 함수를 스크립트의 맨 위에 호출하여 종료 오류를 모두 잡습니다.

trap { Debug-Here }

아니면 a에서 부르든지.try-catch진술.

Get-Item DoesNotExist.txt -ErrorAction Stop

try {
    $x = 0
    $y = 1/$x
}
catch {
    Debug-Here
}

디버그 모드가 되면 다음을 확인합니다.$Error[0]뭐가 문제를 일으켰는지 알아보려고요

약간 호키하지만 쓰기 오류나 던지기 문장에서 작동합니다.

$error.clear()
$global:errcnt=0
Set-PSBreakpoint -Command * -action {if ($error.count -ne $global:errcnt) {$global:errcnt=$error.count;break}}

언급URL : https://stackoverflow.com/questions/20912371/is-there-a-way-to-enter-the-debugger-on-an-error