Skip to content

Calling action scriptblock for registered Powershel.Exiting EngineEvent throws NullReferenceException if script block contains 'finally' block #11869

@grzegorz-wolszczak

Description

@grzegorz-wolszczak

Steps to reproduce

  1. create file code.ps1 with content:
Register-EngineEvent -SourceIdentifier Powershell.Exiting -Action { 
    Write-Host "Start ExitHandler"
    try{   
        try{}
        catch{}
        finally{ }            
    }
    catch{
        # print all exceptions (with all inner)
        # code from the book "Windows Powershell in action 3rd edition, page 534"
        $ErrorRecord = $Error[0]
        $out=""
        $out+= $($ErrorRecord | Format-List -Property * -Force | out-string)
        $out+= $($ErrorRecord.InvocationInfo | Format-List -Property * | out-string)
        $Exception = $ErrorRecord.Exception
        for ($depth = 0; $Exception -ne $null; $depth++)
        {
            $out+= $("$depth" * 80)
            $out+= $($Exception | Format-List -Property * -Force | out-string)
            $Exception = $Exception.InnerException
        }
        Write-Host "$out"
    }
    Write-Host "End ExitHandler"
}
exit 
  1. Create second file run_code.ps1 with content (in the same directory):
pwsh "${PsScriptRoot}/code.ps1"
  1. run file run_code.ps1

Expected behavior

User should see two printed lines

Start ExitHandler
End ExitHandler

Actual behavior

User sees exception details similar to this:

PSMessageDetails      :
Exception             : System.NullReferenceException: Object reference not set to an instance of an object.
                           at System.Management.Automation.ExceptionHandlingOps.SuspendStoppingPipeline(ExecutionContext context)
                           at System.Management.Automation.Interpreter.FuncCallInstruction`2.Run(InterpretedFrame frame)
                           at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
                           at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject          :
CategoryInfo          : OperationStopped: (:) [], NullReferenceException
FullyQualifiedErrorId : System.NullReferenceException
ErrorDetails          :
InvocationInfo        : System.Management.Automation.InvocationInfo
ScriptStackTrace      : at <ScriptBlock>, ...\code.ps1: line 7
PipelineIterationInfo : {}



MyCommand             :
BoundParameters       : {}
UnboundArguments      : {}
ScriptLineNumber      : 7
OffsetInLine          : 5
HistoryId             : -1
ScriptName            : ...\code.ps1
Line                  :     Write-Host "Start ExitHandler"

PositionMessage       : At ...\code.ps1:7 char:5
                        +     Write-Host "Start ExitHandler"
                        +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PSScriptRoot          : ...
PSCommandPath         : ...\code.ps1
InvocationName        :
PipelineLength        : 0
PipelinePosition      : 0
ExpectingInput        : False
CommandOrigin         : Internal
DisplayScriptPosition :


00000000000000000000000000000000000000000000000000000000000000000000000000000000
Message        : Object reference not set to an instance of an object.
Data           : {System.Management.Automation.Interpreter.InterpretedFrameInfo}
InnerException :
TargetSite     : Boolean SuspendStoppingPipeline(System.Management.Automation.ExecutionContext)
StackTrace     :    at System.Management.Automation.ExceptionHandlingOps.SuspendStoppingPipeline(ExecutionContext context)
                    at System.Management.Automation.Interpreter.FuncCallInstruction`2.Run(InterpretedFrame frame)
                    at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
                    at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
HelpLink       :
Source         : System.Management.Automation
HResult        : -2147467261

Environment data

Name                           Value
----                           -----
PSVersion                      6.2.4
PSEdition                      Core
GitCommitId                    6.2.4
OS                             Microsoft Windows 10.0.18362
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

The funny thing is that if you comment out line 6 finally{ } the code will work.
I was trying to find some more information about what kind of code can/cannot appear in Powershell.Exiting action scriptblock but did not find any restrictions etc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-BugIssue has been identified as a bug in the productWG-Enginecore PowerShell engine, interpreter, and runtime

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions