Quantcast
Channel: Hey, Scripting Guy! Blog
Viewing all articles
Browse latest Browse all 3333

Setting a Breakpoint on a Variable

$
0
0

Summary: Ed Wilson, Microsoft Scripting Guy, talks about using variable breakpoints with the Windows PowerShell debugger.

Hello Windows PowerShell scripting dudes and dudettes!

Debugging Week continues, and today I am talking about using variable breakpoints with the Windows PowerShell debugger. Setting a breakpoint on line 1 of the script is useful for easily entering a debugging session. Setting a breakpoint on a variable can often make a problem with a script easy to detect. This is, of course, especially true when you have already determined that the problem is with a variable that is getting assigned a value or being ignored.

The following table shows the three modes of operation that can be used when the breakpoint is specified for a variable. You specify these modes by using the -mode parameter.

Access mode

Meaning

Write

Stops execution immediately before a new value is written to the variable.

Read

Stops execution when the variable is read—that is, when its value is accessed, either to be assigned, displayed, or used. In read mode, execution does not stop when the value of the variable changes.

ReadWrite

Stops execution when the variable is read or written.

To see when a script named BadScript.ps1 script writes to the $num variable, you use Write mode. When you specify the value for the -variable parameter, do not include the dollar sign in front of the variable name.

To set a breakpoint on a variable, you only need to supply the path to the script, the name of the variable, and the access mode. When a variable breakpoint is set, the System.Management.Automation.LineBreak .NET Framework class object that is returned does not include the access mode value. This is true even if you use the Get-PSBreakpoint cmdlet to directly access the breakpoint.

If you pipe the System.Management.Automation.LineBreak .NET Framework class object to the Format-List cmdlet, you will be able to see that the access mode property is available. In this example, you set a breakpoint when the $num variable is written to in the C:\fso\BadScript.ps1 script:

PS C:\> Set-PSBreakpoint -Variable num -Mode write -Script C:\FSO\BadScript.ps1
  ID Script            Line Command           Variable         Action
  -- ------            ---- -------           --------         ------
   3 BadScript.ps1                            num

PS C:\> Get-PSBreakpoint
  ID Script            Line Command           Variable         Action
  -- ------            ---- -------           --------         ------
   3 BadScript.ps1                            num

PS C:\> Get-PSBreakpoint  | Format-List * -Force
AccessMode : Write
Variable   : num
Action     :
Enabled    : True
HitCount   : 0
Id         : 3
Script     : C:\FSO\BadScript.ps1

After setting the breakpoint, when you run the script (if the other breakpoints have been removed or deactivated, which will be discussed later), the script enters the Windows PowerShell debugger when the breakpoint is hit (that is, when the value of the $num variable is written to).

If you step through the script by using the s command, you will be able to follow the sequence of operations. Only one breakpoint is hit when the script is run. This is on line 48 when the value is set to 0.

PS C:\> C:\fso\BadScript.ps1

Entering debug mode. Use h or ? for help.

Hit Variable breakpoint on 'C:\fso\BadScript.ps1:$num' (Write access)

At C:\fso\BadScript.ps1:43 char:1

+ $num = 0

+ ~~~~~~~~

[DBG]: PS C:\>> $num

0

[DBG]: PS C:\>> Write-Host $num

0

[DBG]: PS C:\>> s

At C:\fso\BadScript.ps1:44 char:1

+ SubOne($num) | DivideNum($num)

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[DBG]: PS C:\>> $num

0

[DBG]: PS C:\>> q

PS C:\>

Note  To quickly remove all breakpoints from a Windows PowerShell session, use the Get-PSBreakpoint cmdlet and pipe the output to the Remove-PSBreakpoint cmdlet:

Get-PSBreakpoint | Remove-PSBreakpoint

To set a breakpoint on a Read operation for the variable, you specify the -variable parameter and the name of the variable, the -script parameter with the path to the script, and Read as the value for the -mode parameter. This is shown here:

PS C:\> Set-PSBreakpoint -Variable num -Script C:\FSO\BadScript.ps1 -Mode read

  ID Script            Line Command           Variable         Action
  -- ------            ---- -------           --------         ------
   4 BadScript.ps1                            num

When you run the script, a breakpoint will be displayed each time you hit a Read operation on the variable. Each breakpoint will be displayed in the Windows PowerShell console as Hit Variable breakpoint, followed by the path to the script and the access mode of the variable.

In the BadScript.ps1 script, the value of the $num variable is read several times. The truncated output is shown here:

PS C:\> C:\fso\BadScript.ps1

Hit Variable breakpoint on 'C:\fso\BadScript.ps1:$num' (Read access)

At C:\fso\BadScript.ps1:44 char:1

+ SubOne($num) | DivideNum($num)

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[DBG]: PS C:\>> s

Hit Variable breakpoint on 'C:\fso\BadScript.ps1:$num' (Read access)

 At C:\fso\BadScript.ps1:44 char:1

+ SubOne($num) | DivideNum($num)

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[DBG]: PS C:\>> s

At C:\fso\BadScript.ps1:22 char:1

+ {

+ ~

[DBG]: PS C:\>> s

At C:\fso\BadScript.ps1:23 char:2

+  $num-1

+  ~~~~~~

[DBG]: PS C:\>>

If you set the ReadWrite access mode for the -mode parameter for the variable $num for the BadScript.ps1 script, you receive this feedback: 

PS C:\> Set-PSBreakpoint -Variable num -Mode ReadWrite -Script C:\FSO\BadScript.ps1

  ID Script            Line Command           Variable         Action
  -- ------            ---- -------           --------         ------
   6 BadScript.ps1                            num

When you run the script (assuming you have disabled the other breakpoints), you will hit a breakpoint each time the $num variable is read or written to. If you get tired of typing s and pressing ENTER while you are in the debugging session, you can press ENTER, and it will repeat your previous s command as you continue to step through the breakpoints.

When the script has stepped through the code and arrives at the error in the BadScript.ps1 script, type q to exit the debugger. This is shown here:

PS C:\> C:\fso\BadScript.ps1
Hit Variable breakpoint on 'C:\fso\BadScript.ps1:$num' (ReadWrite access)

At C:\fso\BadScript.ps1:43 char:1
+ $num = 0
+ ~~~~~~~~
[DBG]: PS C:\>> s
At C:\fso\BadScript.ps1:44 char:1
+ SubOne($num) | DivideNum($num)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[DBG]: PS C:\>> s
Hit Variable breakpoint on 'C:\fso\BadScript.ps1:$num' (ReadWrite access)

At C:\fso\BadScript.ps1:44 char:1
+ SubOne($num) | DivideNum($num)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[DBG]: PS C:\>> s
Hit Variable breakpoint on 'C:\fso\BadScript.ps1:$num' (ReadWrite access)

At C:\fso\BadScript.ps1:44 char:1
+ SubOne($num) | DivideNum($num)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[DBG]: PS C:\>> s
At C:\fso\BadScript.ps1:22 char:1
+ {
+ ~
[DBG]: PS C:\>> q
PS C:\>

When you use the ReadWrite access mode of the -mode parameter for breaking on variables, the breakpoint does not tell you if the operation is a Read operation or a Write operation. You have to look at the code that is being executed to determine if the value of the variable is being written or read.

By specifying a value for the -action parameter, you can include regular Windows PowerShell code that will execute when the breakpoint is hit. If, for example, you are trying to follow the value of a variable within the script and you want to display the value of the variable each time the breakpoint is hit, you might want to specify an action that uses the Write-Host cmdlet to display the value of the variable.

By using the Write-Host cmdlet, you can also include a string that indicates that the value of the variable that is being displayed. This is crucial for picking up variables that never initialize; and therefore, it is easier to see than a blank line that would be displayed if you attempted to display the value of an empty variable. The technique of using the Write-Host cmdlet in an -action parameter is shown here:

PS C:\> Set-PSBreakpoint -Variable num -Action { write-host "num = $num" ;
Break } -Mode readwrite -script C:\FSO\BadScript.ps1

  ID Script            Line Command           Variable         Action
  -- ------            ---- -------           --------         ------
   5 BadScript.ps1                            num               write-host "...

When you run the C:\FSO\BadScript.ps1 with the breakpoint set, you receive the following output inside the Windows PowerShell debugger:

PS C:\> C:\fso\BadScript.ps1
num = 0
Hit Variable breakpoint on 'C:\FSO\BadScript.ps1:$num' (ReadWrite access)

At C:\fso\BadScript.ps1:43 char:1
+ $num = 0
+ ~~~~~~~~
[DBG]: PS C:\>> s
At C:\fso\BadScript.ps1:44 char:1
+ SubOne($num) | DivideNum($num)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[DBG]: PS C:\>> s
num = 0
Hit Variable breakpoint on 'C:\FSO\BadScript.ps1:$num' (ReadWrite access)

At C:\fso\BadScript.ps1:44 char:1
+ SubOne($num) | DivideNum($num)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[DBG]: PS C:\>> c
num = 0
Hit Variable breakpoint on 'C:\FSO\BadScript.ps1:$num' (ReadWrite access)

At C:\fso\BadScript.ps1:44 char:1
+ SubOne($num) | DivideNum($num)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[DBG]: PS C:\>> q
PS C:\>

That is all there is to using variable breakpoints with the Windows PowerShell debugger. Debugging Week will continue tomorrow when I will talk about more cool stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy


Viewing all articles
Browse latest Browse all 3333

Trending Articles