Control execution of a Store app in a Visual Studio debug session for Windows Store apps (JavaScript)
Note
This article applies to Visual Studio 2015. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here
This quick start demonstrates how to navigate in the Visual Studio debugger and how to view the program state in a session.
This quick start is for developers who are new to debugging with Visual Studio and for developers who want to learn more about navigating in a Visual Studio debug session. It does not teach the art of debugging itself. The functions in the sample code are designed only to demonstrate the debugging procedures described in this topic. The functions do not employ best practices of app or function design. In fact, you will quickly discover that the functions, and the app itself, do not do much of anything at all.
The sections of this quick start were designed to be as independent as possible, so you can skip any section that includes information that you are already familiar with. You also aren't required to create a sample app. However, we do recommend it and have made the process as easy as possible.
Debugger keyboard shortcuts. Navigation in the Visual Studio debugger is optimized both for the mouse and the keyboard. Many of the steps in this topic include the keyboard accelerator or shortcut key in a parenthetical remark. For example, (Keyboard: F5) indicates that typing the key F5 starts or continues execution of the debugger.
Note
The Module pattern
Windows Store apps often use the JavaScript Module pattern to encapsulate data and functions in a page. The Module pattern uses a single, self-executing, and anonymous closure to keep the page functionality separate from the global namespace. In this topic, we call that function the module.
In this topic
You can learn how to:
Set and run to a breakpoint, step into a function, and examine program data
Step into, over, and out of functions
Set a conditional breakpoint, run to the cursor, and visualize a variable
View variable data in the Locals window
Create the sample app
Debugging is about code, so the sample app uses the framework of the Windows Store app only to create a source file in which you can see how navigating a debug session works and how to examine program state. All of the code that you will invoke is called from the module
function of the default.js file. No controls are added and no events are handled.
Create a blank JavaScript Windows Store app. Open Visual Studio. On the home page, choose the New Project link. On the New Project dialog box, choose JavaScript in the Installed list and then choose Windows Store. In the list of project templates, choose Blank Application. Visual Studio creates a new solution and project and displays the default.htm file in the code editor.
Note the script files that are loaded into the page.
The
base.js
andui.js
files create the Windows Library for JavaScript. The Windows Library for JavaScript is a set of JavaScript and CSS files that make it easier to create Windows Store apps using JavaScript. You use it together with HTML, CSS, and the Windows Runtime to create your app.Your code starts in the
default.js
file.
Open the default.js source file. In Solution Explorer, open the js node and choose
default.js
.Replace the page contents with the sample code. Delete all contents from the
default.js
file. Follow this link: Debugger navigation sample code (JavaScript), and then copy the code listed in the JavaScript section to the clipboard. (Choose Back in the browser or help viewer to return to this quick start page.) In the Visual Studio editor, paste the code into the now emptydefault.js
. Choose Ctrl+ S to save the file.You can now follow along with the examples in this topic.
Set and run to a breakpoint, step into a function, and examine program data
The most common way to start a debug session is to choose Start Debugging from the Debug menu (Keyboard: F5). The app starts and continues executing until a breakpoint is reached, you manually suspend execution, an exception occurs, or the app ends.
When execution is suspended in the debugger, you can view the value of an active variable in a data tip by pausing the mouse on the variable.
After you suspend execution of the app (which is also called breaking into the debugger), you control the way the rest of the program code executes. You can continue line by line, moving from a function call into the function itself, or you can execute a called function in a single step. These procedures are called stepping through the app. You can also resume the standard execution of the app, running to the next breakpoint that you have set, or to the line where you positioned your cursor. You can stop the debug session at any time. The debugger is designed to perform the necessary clean-up operations and exit execution.
Example 1
In this example, you set a breakpoint in the body of the module
function in default.js
as it calls the first of our user statements. You then step into the function, view variable values in debugger data tips, and then stop debugging.
Set a breakpoint. Set a breakpoint at the statement
callTrack = "module function";
that occurs right after the call toapp.start()
. Choose the line in the shaded gutter of the source code editor (Keyboard: Position the cursor on the line and choose the F9 key).The breakpoint icon appears in the gutter.
Run to the breakpoint. Start the debug session by choosing Start Debugging on the Debug menu (Keyboard: F5).
The app begins executing and suspends execution immediately before the statement at which you set the breakpoint. The current line icon in the gutter identifies your location and the current statement is highlighted.
You are now in control of the execution of the app and can examine the program state as you step through the program statements.
Step into the function. On the Debug menu, choose Step Into (Keyboard: F11).
Note that the debugger moves to the next line, which is a call to the
example1
function. Choose Step Into again. The debugger moves to the first code line of theexample1
function. The highlighted line has not been executed, but the function has been loaded on the call stack and the memory for local variables has been allocated.When you step into a line of code, the debugger performs one of the following actions:
If the next statement is not a call to a function in your solution, the debugger executes the statement, moves to the next statement, and then suspends execution.
If the statement is a call to a function in your solution, the debugger moves to the first line of the called function and then suspends execution.
Continue to step into the statements of
example1
until you have reached the exit point. The debugger highlights the closing curly brace of the function.
View variable values in data tips. Continue to step into the statements of
example1
until you have reached the exit point. The debugger highlights the closing curly brace of the function. When you pause the mouse on a variable name, the name and value of the variable are displayed in a data tip.Add a watch for the callTrack variable. The
callTrack
variable is used throughout this quick start to show the functions called in the examples. To make it easier to view the value of the variable, add it to a Watch window. Select the variable name in the editor and then choose Add Watch from the shortcut menu.You can watch multiple variables in a watch window. The values of watched variables, like values in data tip windows, are updated whenever execution is suspended. Your watched variables are saved across debug sessions.
Stop debugging. On the Debug menu, choose Stop Debugging (Keyboard: Shift+F5). This ends your debug session.
Step into, over, and out of functions
In contrast to stepping into a function called by a parent function, stepping over a function executes the child function and then suspends execution in the calling function as the parent resumes. You might step over a function when you are familiar with the way the function works and are sure that its execution will not affect the issue that you are investigating.
Stepping over a line of code that doesn't contain a function call executes the line just like stepping into the line.
Stepping out of a child function continues execution of the function and then suspends execution after the function returns to its calling function. You might step out of a long function when you have determined that the rest of the function is not significant.
Both stepping over and stepping out of a function execute the function.
Example 2
In this example, you step into, over, and out of functions.
Call the example2 function in the module function. Edit the
module
function and replace the line followingvar callTrack = "module function"
withexample2();
.Run to the breakpoint. Start the debug session by choosing Start Debugging on the Debug menu (Keyboard: F5). The debugger suspends execution at the breakpoint.
Step over the line of code. On the Debug menu, choose Step Over (Keyboard: F10). The debugger executes the
var callTrack = "module function"
statement in the same manner as stepping into the statement.Step into example2 and example2_a. Choose the F11 key to step into the
example2
function. Continue to step into theexample2
statements until you reach the linevar x = example2_a();
. Again, step into this line to move to the entry point ofexample2_a
. Continue to step into each statement ofexample2_a
until you return toexample2
.Step over a function. Note that the next line in
example2
,var y = example2_a();
is basically the same as the previous line. You can safely step over this line. Choose the F10 key to move from the resumption ofexample2
to this second call toexample2_a
. Note that thecallTrack
string indicates theexample2_a
function was executed twice.Step out of a function. Choose the F11 key to step into the
example2_b
function. Note thatexample2_b
is not very different fromexample2_a
. To step out of the function, choose Step Out on the Debug menu (Keyboard: Shift+F11). Note that thecallTrack
variable indicates thatexample2_b
was executed and that the debugger has returned to the point whereexample2
resumes.Stop debugging. On the Debug menu, choose Stop Debugging (Keyboard: Shift+F5). This ends your debug session.
Set a conditional breakpoint, run to the cursor, and visualize a variable
A conditional breakpoint specifies a condition that causes the debugger to suspend execution. The condition is specified by any code expression that can be evaluated as true or false. For example, you might use a conditional breakpoint to examine the program state in a frequently called function only when a variable reaches a certain value.
Running to the cursor is like setting a one-time breakpoint. When execution is suspended, you can select a line in the source and resume execution until the selected line is reached. For example, you might be stepping through a loop in a function and determine that the code in the loop is performing correctly. Rather than stepping through every iteration of the loop, you can run to the cursor that is positioned after the loop is executed.
Sometimes, it's difficult to view a variable value in the row of a data tip or other data window. The debugger can display strings, HTML, and Xml in a text visualizer that presents a formatted view of the value in a scrollable window.
Example 3
In this example, you set a conditional breakpoint to break at a specific iteration of a loop, then run to the cursor that is positioned after the loop. You also view the value of a variable in a text visualizer.
Call the example3 function in the module function. Edit the
module
function and replace the line followingvar callTrack = "module function";
with the lineexample3();
.Run to the breakpoint. Start the debug session by choosing Start Debugging on the Debug menu (Keyboard: F5). The debugger suspends execution at the breakpoint in the
module
function.Step into the example3 function. Choose Step Into on the Debug menu (Keyboard: F11) to move to the entry point of the
example3
function. Continue stepping into the function until you have iterated one or two loops of thefor
block. Note that it would take you a long time to step through all 1000 iterations.Set a conditional breakpoint. In the left gutter of the code window, right-click the line
s += i.toString() + "\n";
and then choose Condition on the shortcut menu.Select the Condition check box, and then type
i == 500;
in the text box. Choose the Is true option and choose OK. The breakpoint allows you to check the value at the 500th iteration of thefor
loop. You can identify a conditional breakpoint icon by its white cross.Run to the breakpoint. On the Debug menu, choose Continue (Keyboard: F5). Pause on the
i
to confirm that the current value ofi
is 500. Also note that the variables
is represented as single line and is much longer than the data tip window.Visualize a string variable. Click the magnifying glass icon in the data tip of the
s
.The Text Visualizer window appears and the value of the string is presented as a multi-line string.
Run to the cursor. Select the line
callTrack += "->example3";
and then choose Run to Cursor on the shortcut menu (Keyboard: Ctrl+F10). The debugger completes the loop iterations and then suspends execution at the line.Stop debugging. On the Debug menu, choose Stop Debugging (Keyboard: Shift+F5). This ends your debug session.
Use Run to Cursor to return to your code and delete a breakpoint
Running to the cursor can be very useful when you have stepped into library code from Microsoft or a third party. While stepping through library code can be informative, it often can take a long time. And usually, you are far more interested in your own code. This exercise shows you how to do it.
Set a breakpoint at the app.start call. In the
module
function, set a breakpoint at the lineapp.start()
Run to the breakpoint and step into the library function.
When you step into
app.start()
, the editor displays the code inbase.js
. Step into a few more lines.Step over and out of functions. As you step over (F10) and step out of (SHIFT+F11) code in
base.js
, you might come to the conclusion that examining the complexity and length of the start function is not what you want to be doing.Set the cursor to your code and run to it. Switch back to the
default.js
file in the code editor. Select the first line of code afterapp.start()
(You can't run to a comment or a blank line). Choose Run to Cursor from the shortcut menu. The debugger continues execution of the app.start function and suspends execution at the breakpoint.
View variable data in the Locals window
The Locals windows is a tree view of the parameters and variables in the scope chain of the currently executing function.
View variable data and the prototype chain of an object
Add an array object the module function. Edit the
module
function and replace the line followingvar callTrack = "module function"
withvar myArray = new Array(1, 2, 3);
Run to the breakpoint. Start the debug session by choosing Start Debugging on the Debug menu (Keyboard: F5). The debugger suspends execution at the breakpoint. Step into to the line.
Open the Locals window. On the Debug menu, point to Windows, and then choose Locals. (Keyboard: Alt+4).
Examine the local variables in the module function The Locals windows displays the variables of the currently executing function (the
module
function) as top level nodes of the tree. When you enter a function, JavaScript creates all the variables and gives them a value ofundefined
. Functions that are defined in the function have their text as a value.Step through the callTrack and myArray definitions. Find the callTrack and myArray variables in the Locals window. Step over (F10) the two definitions and notice that the Value and Type fields are changed. The Locals window highlights the values of variables that have changed since the last break.
Examine the myArray object Expand the
myArray
variable. Each element of the array is listed The [prototype] node that contains the inheritance hierarchy of theArray
object. Expand this node.The Methods node lists all the methods of the
Array
object.The [prototype] node contains the prototype of the
Object
object from whichArray
is derived. [prototype] nodes can be recursive. Each parent object in an object hierarchy is described in the [prototype] node of its child.
Stop debugging. On the Debug menu, choose Stop Debugging (Keyboard: Shift+F5). This ends your debug session.
Examine scope chain data
The scope chain of a function includes all variables that are active and reachable by the function. Global variables are part of the scope chain, as are any objects (including functions) that are defined in the function that defines the currently executing function. For example, the callTrack
variable that is defined in the module
function of default.js
is reachable by any function that is defined in the module
function. Each scope is listed separately in the Locals window.
The variables of the currently executing function are listed at the top of the window.
The variables of each function scope in the scope chain are listed under a [Scope] node for the function. The scope functions are listed by their order in the chain, from the function that defines the current function to the outermost function of the chain.
The [Globals] node lists the global objects that are defined outside of any function.
Scope chains can be confusing and are best illustrated by example. In the following example, you can see how the
module
function creates its own scope, and how you can create another level of scope by creating a closure.
Example 4
Call the example4 function from the module function. Edit the
module
function and replace the line followingvar callTrack = "module function"
with theexample4()
:Run to the breakpoint. Start the debug session by choosing Start Debugging on the Debug menu (Keyboard: F5). The debugger suspends execution at the breakpoint.
Open the Locals window. If necessary, on the Debug menu, point to Windows, and then choose Locals. (Keyboard: Alt+4). Note that the window lists all the variables and functions in the
module
function, and also contains a [Globals] node.Examine the global variables. Expand the [Globals] node. The objects and variables in the Global were set by the Windows Library for JavaScript. You can add your own variables to the global scope.
Step into example4 and examine its local and scope variables Step into (Keyboard: F11) the
example4
function. Becauseexample4
is defined in themodule
function, themodule
function becomes the parent scope.example4
can call any of functions in themodule
function and access its variables. Expand the [Scope] node in the Locals window and note that it contains the same and variables of themodule
function.Step into example4_a and examine its local and scope variables Continue to step into
example4
and into the call toexample4_a
. Note that the local variables are now fromexample4_a
, and that the [Scope] node continues to hold the variables of themodule
function. Even though the variables ofexample4
are active, they cannot be reached byexample4_a
and are no longer part of the scope chain.Step into multiplyByA and examine its local and scope variables Step through the rest of
example4_a
and into the linevar x = multiplyByA(b);
.The function variable
multiplyByA
has been set to themultiplyClosure
function which is a closure.multiplyClosure
defines and returns an inner function,multiplyXby
, and captures (closes over) its parameter and variable. In a closure, the returned inner function has access to the data of the outer function and so creates its own level of scope.When you step into
var x = multiplyByA(b);
, you move to thereturn a * b;
line in themultiplyXby
inner function.In the Locals window, only the parameter
b
is listed as a local variable inmultiplyXby
, but a new [Scope] level has been added. Expanding this node, you see that it contains the parameters, functions, and variables ofmultiplyClosure
, including thea
variable called in the first line ofmultiplyXby
. A quick check of the second [Scope] node reveals the module function variables, whichmultiplyXby
accesses in its next line.Stop debugging. On the Debug menu, choose Stop Debugging (Keyboard: Shift+F5). This ends your debug session.
Navigate to code by using the Call Stack window
The call stack is a data structure that contains information about the functions that are executing in the current thread of the application. When you hit a breakpoint, the Call Stack window displays a list of all of the functions that are active on the stack. The currently executing function is at the top of the Call Stack window list. The function that initiates the thread is at the bottom of the list. The functions in between show the call path from the initiating function to the current function.
In addition to showing the call path to the currently executing function, the Call Stack window can be used to navigate to code in the code editor. This functionality can be valuable when you are working with multiple files and you want to quickly move to a particular function.
Example 5
In this example, you step into a call path that contains five user-defined functions.
Call the example5 function in the module function. Edit the
module
function and replace the line followingvar callTrack = "module function";
with the lineexample5();
.Run to the breakpoint. Start the debug session by choosing Start Debugging on the Debug menu (Keyboard: F5). The debugger suspends execution at the breakpoint in the module function.
Open the Call Stack window. On the Debug menu, choose Windows, and then choose Call Stack (Keyboard: Alt+7). Note that the Call Stack window shows two functions:
Global code is the entry point of the
module
function at the bottom of the call stack.Anonymous function shows the line in the
module
function where execution is suspended. This is the top of the call stack.
Step into functions to reach the example5_d function. Choose Step Into on the Debug menu (Keyboard: F11) to execute the calls in the call path until you reach the entry point of the example5_d function. Note that each time that a function calls a function, the line number of the calling function is saved and the called function is placed at the top of the stack. The line number of the calling function is the point at which the calling function has suspended execution. A yellow arrow points to the currently executing function.
Use the Call Stack window to navigate to the example5_a code and set a breakpoint. In the Call Stack window, select the
example5_a
list item and then choose Go to Source on the shortcut menu. The code editor sets its cursor at the return line of the function. Set a breakpoint on this line. Note that the current execution line is not changed. Only the editor cursor has moved.Step into functions and then run to the breakpoint. Continue stepping into
example5_d
. Note that when you return from the function, it is taken off the call stack. Press F5 to continue the program execution. You stop at the breakpoint created in the previous step.Stop debugging. On the Debug menu, choose Stop Debugging (Keyboard: Shift+F5). This ends your debug session.
See Also
Start a debug session (JavaScript) Quickstart: Debugger navigation (JavaScript) Quickstart: Debug HTML and CSS Trigger suspend, resume, and background events for Windows Store) Debug apps in Visual Studio