Debugging Mainframe COBOL programs with VS Code
By: Iurii Shchekochikhin
Tags: Mainframe, Vscode, Debugging, Cobol, DevOps

Many developers do multi-platform development where learning new steps to do common tasks like debugging is painful. How can I simply use a common IDE like VS Code to debug Cobol?

Grace Hopper coined the word Bug and Debug after finding a moth in a calculator in 1945. Similarly, Debugging is the process of finding and resolving defects or problems within a computer program that prevents the correct operation of computer software or a system.

Debugging is an essential part of software development as it is one of the basic developer tools used to understand the code, find problems, and test various flows through an application. This along with other skills and tools support, successfully build and delivery of an application, including a mainframe application.

Although, until now, mainframe developers didn’t have many options on how to debug code. Their choices are basically limited to 3270 (green screen) based interfaces or dated Eclipse-based interfaces. Choices have been limited partially because there has not been a standard way to integrate debugging capability across different IDEs.

Enter DAP — debug adapter protocol — which allows separation of the user experience from the backend debugging platform. Through DAP a user experience like that of VS Code can be the same whether the language is Java or Cobol by utilizing an extension (adapter) to transform the backend debugger actions into VS Code debugger experience.

For more information on DAP take a few minutes to read an article written by my Broadcom colleague Azat. He explains the details and the magic of DAP. Broadcom has leveraged the DAP architecture to bring mainframe application debugging to multiple IDEs that support DAP delivered as part of Code4z.

InterTest CICS & Batch

Broadcom has created the first DAP Debug Adapter for modern IDEs supporting debugging of mainframe COBOL applications. The Debugger for Mainframe extension is the debug adapter that uses the DAP protocol to connect to IDE and CA InterTest™ to enable debugging of COBOL CICS and Batch applications in the two most popular IDEs — Microsoft Visual Studio Code and Eclipse Che (a browser-based IDE). For more information about the Eclipse Che environment and Broadcom’s contribution to it please see this article.

CA InterTest is a Broadcom product that allows you to debug CICS, Batch, COBOL/HLASM or PL/I applications running on Mainframe. By trapping application errors, it enables users to detect and resolve errors interactively as they occur. The Debugger for Mainframe extension uses APIs to connect to CA InterTest GUI server on z/OS.

All you need to do is (if you don’t have it yet) to install the InterTest GUI server and configure your CICS regions (for debugging CICS transactions). Referring to Broadcom tech documentation, where are instructions for installation and configuration.

VS Code debugging capabilities

A key capability in Visual Studio Code is its great debugging support. The Debugger for Mainframe extension utilizes this functionality to allow a similar experience with Cobol as with other languages. The modern and user-friendly UI works in combination with another Broadcom tool — COBOL Language Support.

COBOL Language Support provides syntax awareness for the COBOL language. So when a developer is looking at an application source or listing they can easily visualize the syntax of the code and leverage other edit capabilities like control flow visualization and variable resolution.

The Debugger for Mainframe supports many launch configurations including support for multiple programs running in parallel. You can use different types of breakpoints. For example, unconditional, conditional, hit counts, and log breakpoints as needed to best fit your debugging scenario. All the variable data can be inspected and modified within the VS Code tree representation of the data structures or within the ‘Watch’ functionality together with additional information like a variable type.

Announcement — the latest version of Debugger for Mainframe v1.3.0 is now available on VS Code Marketplace. This version supports debugging multiple COBOL programs in parallel.

Unconditional breakpoints are the typical way to start debugging the code. However, with conditional breakpoints, you can be more selective in defining what circumstances will trigger the program to stop. Thus, being able to focus on a particular program condition saving development time and improved efficiency. For example this conditional statement my_variable = P’-1548' will only stop on the breakpoint when the value of the variable ‘my_variable’ is equal to -1548.

Similarly, to add detail to the debugging scenario ‘Hit counts’ breakpoints can be used. In this case, you can specify exactly what iteration of the line of the code the program should stop.

If needed, you can also print out your custom messages together with variables values into the debug console using the ‘log point’ type of the breakpoint.

So what does the step by step debugging process look like? After all the mainframe build and deployment preparations are done, you are ready to get started. First, you’ll need to configure the connection with InterTest by providing the necessary information about the InterTest server location, and connection credentials.

The upcoming sections will focus on differences between the setup for CICS and BATCH.

Setting up debugging with CICS

Based on the program name the InterTest will provide the exact version of listing (for InterTest that is called the PROTSYM). That’s why there is no need for PROTSYM names in the CICS launch configuration. Also, you’ll need to specify a CICS region with the transaction for the program.

Let’s take a look at this example. Using an InterTest server on myintertest.com host at 1819 port, a CICS application id of “HELLOWORD”, a program name of “DAPDEMO” and my username of “username” then the launch configuration for vscode will look like this:

{

“name”: “Debugger for Mainframe: CA INTERTEST™ FOR CICS”,

“type”: “intertest-cics”,

“request”: “launch”,

“programName”: “DAPDEMO”,

“interTestHost”: “ca11.lvn.broadcom.net”,

“interTestPort”: 1819,

“interTestUserName”: “username”,

“interTestSecure”: true,

“cicsApplId”: “HELLOWORLD”

}

To test your configuration you can try to fetch an extended source file. This extended source file is needed for debugging anyway as it is where breakpoints are established. To trigger this fetch — Press F1 and search for the “Fetch Extended Sources” command from the command panel. Click to issue this command to get the extended source file.

When this completes, you’ll see an editor window with the listing of your program. You can now put breakpoints in it.

To start a debugging session you need to press the green “play” button in the vs code UI (similar to starting Java debugging). This will communicate with InterTest and start the monitoring of the application which becomes visible as the bottom edge of the IDE will turn orange. To stop monitoring the red “stop” button is pressed. A debug session is independent of a CICS transaction, therefore many transactions as are needed can be in one debug session.

After creating the necessary debug breakpoints into the listing, start the debug session. To get started click on the green “run” button. The IDE will connect to the InterTest server and with an established connection, all breakpoints from the listing are populated to the CICS region. They are visible on the green screen by entering CNTL=INQ in the CICS region. Also, the vscode bottom bar will turn orange to indicate the user that the session is listening on the CICS transaction.

With a monitoring set, the application needs to be started by triggering the transaction. During the application execution, the debugger will be paused at breakpoints or ABEND events. Note, a transaction can be triggered as many times as you need during the same debugging session.

When the debugger has stopped the application, a list of variables will appear. The variables are visible in the tree form where roots are variables of first or special levels (66, 77) and nodes are lower-level variables.

You can read and change the value of each variable. Any changes are preserved till the end of the current transaction.

From the stopped state, there are two ways to continue — stepping or resume execution. Stepping is a command to execute the next statement and go back in a stopped state. A resume is a command to continue execution until the next breakpoint or ABEND event.

To stop debugging you should press the red “stop” button.

Setting up debugging with BATCH

Now let’s see how debugging of BATCH applications differs from CICS. The main difference is that CICS is a runtime that does not go away upon completion so a transaction can be restarted, but with Batch, the application starts and completes which also ends the debug session.

InterTest for batch controls the execution of the COBOL application. Therefore InterTest needs the dataset name contained in the JCL job used to start the application. A new JCL which starts InterTest and the program to be started is needed (if one does not exist).

You can convert your program’s original JCL to JCL with InterTest by calling the “Batch: Convert JCL” command. And if you have a section about original JCL in your launch configuration, the vscode extension will create or update a converted JCL dataset.

Another difference from CICS is that with BATCH it’s impossible to detect which PROTSYM contains the source code of a running program. Therefore, it is necessary to specify a PROTSYM dataset name in the launch configuration.

{

“name”: “batch launch cfg example”,

“type”: “intertest-batch”,

“request”: “launch”,

“programName”: [

“HELLOCBL”

],

“protsym”: [

“EXAMPLE.DSN.HELLOCBL.PROTSYM”

],

“convertedJCL”: “EXAMPLE.DSN.HELLOCBL.JCL.CONV(CONVHELLO)”,

“originalJCL”: {

“inDSN”: “EXAMPLE.DSN.HELLOCBL.JCL(CONVHELLO)”,

“stepName”: “HELLO”

},

“interTestHost”: “my.intertest.con”,

…….

This is an example of a BATCH launch configuration. As you can see the type is intertest-batch. Datasets with original and converted JCLs are provided. A PROTSYM and a program name are in place,

Now you can convert the original JCL to a converted JCL and start debugging. This conversion is required only the first time or when you need to have original JCL changes in the converted JCL. You don’t need to do this conversation every time when you start a debug session.

From this point, the debugging process is the same as for CICS.

Please see this short video for a demonstration of how to install Debugger for Mainframe, configure it for debugging CICS applications, and use it.

You can download the Debugger for Mainframe for free from VSC Marketplace either as a separate extension or as part of the Code4z package (a complete mainframe developer solution)

To learn more about CA InterTest™ please refer to the product documentation.

Special thanks to Dana Boudreau and Tomas Cech for help with the content of this post.

Stay in touch with us, join us on our Code4z Slack channel!