Snapshot Debugging

Note

With Business Central 17.2 - Snapshot Debugging is available in production cloud environments.

Snapshot debugging allows recording AL code that runs on the server, and once it has run, debug the recorded snapshot in Visual Studio Code. To create and download a snapshot file that exists on the server on behalf of an end-user, the user must be part of the D365 Snapshot Debug permission set. For more information, see Assign Permissions to Users and Groups. One of the advantages of snapshot debugging is that it provides the ability to inspect code execution and variables in the production environment in a cloud service, on a specified user session.

Snapshot debugging introduces the concept of snappoints. A snappoint is a breakpoint in Visual Studio Code that is set when creating a snapshot, they do not, however, stop execution of code like when using regular debugging. Snappoints instruct execution to log the state at the breakpoint for later offline inspection. Snapshot debugging will record AL code as it runs on the server, but will only collect variable information on:

  • Snappoints
  • AL exceptions

Note

With Business Central version 18.1, it is possible to snapshot debug event subscribers triggered from built-in codeunit triggers if a snappoint is placed in an AL file on the stack trace that leads to the built-in method. For more information, see Snapshot debugging built-in methods.

Important

To enable snapshot debugging it is very important that the symbols on the tenant match the symbols on the server. This is not automatically detected, and must be manually checked. In this release, you can ensure this by copying the specific sandbox and download symbols from that copy. Furthermore, any code that snappoints are set in, must have been deployed, otherwise debugging will not work. For more information, see the section Downloading symbols on the snapshot debugger endpoint.

Snapshot debugging keyboard shortcuts

In the following sections you can read more about how to initialize, view the status, and finalize a snapshot debugging session. For these actions, the following keyboard shortcuts are useful to familiarize yourself with. For additional keyboard shortcuts, see Keyboard Shortcuts.

Keyboard Shortcut Action
F7 Start a snapshot debugging session
Shift+F7 List all available snapshots
Alt+F7 Finish a snapshot debugging session

Initializing a snapshot debugging session

From Visual Studio Code, you start a snapshot by creating a snapshot configuration file. There are two template configurations for a snapshot, which are accessed by selecting Add Configuration in Visual Studio Code.

  • AL: Initialize a snapshot debugging session locally
  • AL: Initialize a snapshot debugging session on cloud

Choose whether to run the session on a cloud service or locally. The configuration file contains the following information:

Setting Description
userId The GUID of the user on whose behalf a snapshot debugging will be started. For on-premises, this can also be the user name in user password authentication scenarios. The user must be able to start, or have a session type opened that is specified in the breakOnNext parameter.
Note: Specifying userId does not work with Windows authentication: "authentication" : "Windows", in which case you can only choose sessionId or attach to the next session. For more information, see JSON Files.
sessionId A session ID for the user specified above in userId.
snapshotVerbosity Determines how much execution context to be recorded. If SnapPoint is specified, then only methods that hit a snappoint will be recorded.
tenant The AAD tenant ID for the tenant to connect to. Specify this if targeting a different tenant from the user's own AAD tenant, for example when running as a delegated admin.

When a configuration is defined, a snapshot debugging session can be initialized by pressing Ctrl+Shift+P and then selecting AL:Initialize Snapshot Debugging or by pressing F7.

Note

If you are going to use the snapshot for profiling the code, you must enable the configuration parameter called executionContext. For more information, see AL Profiler Overview.

To record the AL execution, the server will now wait for a connection to happen where the following rules apply:

  • If a sessionId is specified for a userId for a given tenant then it will be that session that will be snapshot debugged.
  • If only a userId is specified for a given tenant then the next session that is specified in the breakOnNext configuration parameter is snapshot debugged.
  • If no userId is specified then the next session on a given tenant that validates the breakOnNext parameter will be snapshot debugged.

Tip

If you are having difficulty getting the snapshot debugger to attach to a new session using WebClient for the breakOnNext configuration parameter, then close the browser window and try again.

Once a snapshot debugging session is initialized the snapshot debugging session counter on the status bar will be updated and look like this:

Snapshot Debugger Counter.

Status of a snapshot debugging session

Clicking on the status bar icon or pressing Shift+F7 will bring up a list of all available snapshots.
The status list will show the state of a snapshot-debugged session.

A snapshot debugging session can be in one of the three states:

  • Initialized - A request is issued and the server is waiting for the next session to be snapshot debugged based on the above rules.
  • Started - You have attached to an end-user session to snapshot debug.
  • Finished - When the snapshot debugging session has finished.
  • Downloaded - When the snapshot file is downloaded.

Finishing a snapshot debugging session

You finish a snapshot debugging session by pressing Alt+F7. This brings up all snapshot sessions that have been started. Choosing one will close the session debugging on the server and download the snapshot file.

Important

The snapshot file can contain customer privacy data and must therefore be handled according to privacy compliance and should be deleted when it is not needed anymore.

Snapshot debugging sessions that have produced a snapshot file can be debugged. The location of a snapshot file is controlled by the al.snapshotOutputPath configuration parameter. By default it is local to the current workspace and it is called ./.snapshots. For more information, see AL Language Extension Configuration.

Downloading symbols on the snapshot debugger endpoint

In order to download symbols on a production server, you need permission related entries. The read-only access to the Published Application table emphasized in the D365 Snapshot Debug permission set should be granted.

Debugging requires that symbols on the server are matched with the symbols that the user has locally. If this is not the case, and you set a breakpoint on a given line in Visual Studio Code, the line of code may differ from what is on the server.

Symbols download is using the snapshotInitialize debug configuration settings in Visual Studio Code, which is set up when you choose either AL: Initialize a snapshot debugging session locally or AL: Initialize a snapshot debugging session on cloud.

{
            "name": "snapshotInitialize: MyServer",
            "type": "al",
            "request": "snapshotInitialize",
            "environmentType": "OnPrem",
            "server": "http://localhost",
            "serverInstance": "BC190",
            "authentication": "UserPassword",
            "breakOnNext": "WebClient"
        },

Important

Debugging requires that symbols on the server are matched with the symbols that the user has locally. If this is not the case, and you set a breakpoint on a given line in Visual Studio Code, the line of code may differ from what is on the server. This is why you must download symbols from production servers for snapshot debugging in order for a breakpoint set on one line to match with what the server understands of this line. This is to avoid a scenario where you set a breakpoint in a DAL file on line 12, but line 12 on the server is an empty line or a completely different line if the symbols are not the same.

Debugging a snapshot file

There are two user actions that will start snapshot debugging:

  • Creating a new launch debug configuration and specifying the snapshot file name in the snapshotFileName configuration setting. This is the only setting that is needed besides the type, request, and name.
  • Clicking on the status icon or by pressing Shift+F7 and selecting a finished snapshot-debugged session.

Once a snapshot debugging session starts in Visual Studio Code, code execution will stop at the first snappoint. AL exceptions will be treated as snappoints, with the only difference that they cannot be removed by user actions. Other snappoints are just regular breakpoints that can be removed or re-added by user actions. If no snappoints are specified the first recorded methods; the first line is the entry breakpoint.

The user can set breakpoints and continue execution to that breakpoint for testing, for example, if a line is hit, but it is the snappoint that carries the real information.

Snapshot debugging built-in codeunit triggers

Built-in codeunit triggers can be snapshot-debugged if they are part of the stack trace, these are System Action Triggers, or Company Triggers. This provides a way to snapshot debug that part of the Base App too. To help locate where built-in codeunit triggers are called, use the Event Recorder in Business Central. From the code, when all symbols on the snapshot endpoint have been downloaded, see Downloading symbols on the snapshot debugger endpoint, you can add AL code that contains a reference to that particular event subscription and then use Go to Definition to locate the place where that particular codeunit trigger is defined in the .dal file. Adding a snappoint to the code in the .dal file and then initiating the snapshot debugger session will ensure that the code is part of the stacktrace. When the generated snapshot file is then opened in the debugger, the execution will break on the snappoint.

Snapshot debugging versus regular debugging

Snapshot debugging is almost the same as a regular debugging with the differences mentioned in the following:

Snapshot versus regular debugging
Breakpoints can be added and removed and they will be hit if given a breakpoint; the breakpoint is in the execution context of a recorded state. This means that if walking the execution stack for a breakpoint and the next stepped line is reached, then the code will break on the breakpoint.
A snappoint is a breakpoint in Visual Studio Code that is set when creating a snapshot, they do not, however, stop execution of code like when using regular debugging. Snappoints instruct execution to log the state at the breakpoint for later offline inspection.
You can always navigate through all the breakpoints with Continue (F5). The order may not be the same as the execution order on the Business Central server. This is due to the fact that some calls on the server are AL calls with non-walkable stacks. Some are direct server calls on the server like triggers. A snapshot debugging session on the Business Central server can only record AL calls and walk AL stack traces.
This is also true when stepping. The rule of thumb is that breakpoints within the reach are hit first, and if there are none; the next line is hit. Breakpoints on triggers may not always qualify as code within reach.
Variable data is only shown on snappoints.
If there are no frames available snapshot debugging will stop.
Stepping out of triggers with no recorded stack information will move execution to the first recorded method's first line. This may be very far from the user's execution of interest. For example, stepping out from an OnOpenPage trigger with a snappoint may land on deep inside base code execution where recording has started. Navigating with F5 will start over breakpoint resolution, thus this is an exit strategy from a scenario like this.
A snappoint may resolve as a non-reachable breakpoint if there was no execution state on the server hitting the snappoint.
A snapshot debugger session with a Business Central server will be closed if not attached to after 30 minutes.
If a snapshot debugger session is started, it has to be finished after 10 minutes.

See Also

Debugging
Attach and Debug Next
Developing Extensions
JSON Files
AL Code Navigation
EnableLongRunningSQLStatements Property
EnableSQLInformationDebugger Property
LongrunningSQLStatementsThreshold Property
NumberOfSQLStatements Property