Skip to content
Snippets Groups Projects
README.md 9.92 KiB
Newer Older
# Camelian Systems COBOL debugger

This extension provides source-level debugging of COBOL programs compiled with the GnuCOBOL COBOL compiler.

June 12, 2020  
Bob Dubner  
rdubner@symas.com
COBOL source code is compiled with the GnuCOBOL compiler.  Debugging information and a gdb extension are added to the executable by the Camelian cbl-gdb routines.  The resulting executable can be debugged directly by the Gnu gdb debugger.  That executable can also be debugged on the source-code level with this extension, which provides a VSC Debug Adapter that is aware of the Camelian extensions to gdb that makes source-level debugging possible.

## Prerequisites - GnuCOBOL

In order to debug a COBOL program, it must first be compiled with an appropriate version of the GnuCOBOL compiler.  The compiler must be the 3.1 version, which has not, at this writing, been formally released.

GnuCOBOL-3.1-dev installation packages for Ubuntu, RedHat, and Windows can be found at [Camelian Systems downloads](https://camelian.systems/pages/downloads.html).  

Those who prefer to build from source can find GnuCOBOL source code at the SVN repository https://svn.code.sf.net/p/open-cobol/code/branches/gnucobol-3.x  The build sequence starts with `./autogen.sh`

A more build-ready tarball, with certain system-independent elements pre-built with known-good tools, can be downloaded from [here](https://ci.appveyor.com/api/projects/GitMensch/gnucobol-3-x/artifacts/gnucobol-3.1-dev.tar.gz?job=Image:%20Ubuntu1804).  The build sequence starts with `./configure`.

More information can be found at https://sourceforge.net/projects/open-cobol/

## Prerequisites - Camelian cbl-gdb debugging extensions

As part of the compilation process, the cbl-gdb extensions need to be applied before the executable can be debugged using gdb and VSC.

Download and install the appropriate `Camelian GnuCOBOL Debugging Extensions package` from [Camelian Systems downloads](https://camelian.systems/pages/downloads.html). 
If you didn't install this extension from Microsoft's repositories, then you probably downloaded a file named cbl-gdb-2.1.2.vsix, which is a Visual Studio Code extension package.  You have a couple of options for loading the extension into VS code:
- From inside Visual Studio Code, use the Command Palette `(Ctrl+Shift+P)` to find "Extensions: Load extension from VSIX..."  Select that, and point it at the .VSIX file.
- From the command line, execute `code --install-extension cbl-gdb-2.1.2.vsix`
There are a number of COBOL formatting extensions available at Microsoft's Extension Marketplace.  We've found that `Enterprise COBOL for z/OS` seems to coexist with our Debugging Adapter, and does a reasonable job of formatting the COBOL source code.

## Additional configuration of Visual Studio Code.

Use the Command Palette `(Ctrl+Shift+P)` To search for `Settings`, or navigate to `File > Preferences > Settings` from the menu.  Select the `User` tab, and then `User > Features > Debug`.  Activate the `Allow Breakpoints Anywhere` option.

## Getting Started / Troubleshooting Guide

Were you to contact me for help getting this package running on your system, I would go through this series of steps to convince myself all the pieces were working correctly.

### Create a simple test program

Create an empty directory; I'm naming it `ctest`.

Create a text file CTEST.CBL

```
000001 IDENTIFICATION DIVISION.
000002 PROGRAM-ID. CTEST.
000003 DATA DIVISION.
000004 WORKING-STORAGE SECTION.
000005 01 D123 PIC 999 VALUE 123.
000006 PROCEDURE DIVISION.
000007 DISPLAY "Simple".
000008 DISPLAY "as".
000009 DISPLAY "one".
000010 DISPLAY "two".
000011 DISPLAY "three".
000012 DISPLAY D123.
000013 GOBACK.
000014 END PROGRAM CTEST.
```        
### Verify that GnuCOBOL is the right version:

The shell command `cobc --version | head -n 1` should return  

    cobc (GnuCOBOL) 3.1-dev.0

or greater.

### Verify that GnuCOBOL compiles ctest:

Execute the shell command `cobc -x CTEST.CBL && ./CTEST`

The resulting output should be

```
Simple
as
one
two
three
123
```

### Verify that the Camelian Debugging Extensions are in place:

Execute the shell command `cobcd -x CTEST.CBL && ./CTEST`

*Note that the `cobc` command has been replaced with the `cobcd` command.*

The displayed results should be the same as for `cobc`.

### Verify that gdb debugging works:

Execute the shell command `gdb -q CTEST`

The immediate output from GDB should look like this:

```
$ gdb -q CTEST
Reading symbols from CTEST...
registering CPrint (Usage is "print  <COBOL identifier>") [Version 2.9]
registering CWatch (Usage is "cwatch <COBOL identifier>")
```

*It is important that the two lines indicating CPRINT and CWATCH have been registered appear here.  If they are missing, then the cbl-gdb package wasn't completely installed.*

Entering the following sequence of commands: `l, b 7, r, n, n, n, n, n, n, n` should produce this output:

```
$ gdb -q CTEST
Reading symbols from CTEST...
registering CPrint (Usage is "print  <COBOL identifier>") [Version 2.9]
registering CWatch (Usage is "cwatch <COBOL identifier>")
(gdb) l
1       000001 IDENTIFICATION DIVISION.
2       000002 PROGRAM-ID. CTEST.
3       000003 DATA DIVISION.
4       000004 WORKING-STORAGE SECTION.
5       000005 01 D123 PIC 999 VALUE 123.
6       000006 PROCEDURE DIVISION.
7       000007 DISPLAY "Simple".
8       000008 DISPLAY "as".
9       000009 DISPLAY "one".
10      000010 DISPLAY "two".
(gdb) b 7
Breakpoint 1 at 0xf10: file CTEST.CBL, line 7.
(gdb) r
Starting program: /home/bob/projects/ctest/CTEST
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, CTEST_ (entry=0) at CTEST.CBL:7
7       000007 DISPLAY "Simple".
(gdb) n
Simple
8       000008 DISPLAY "as".
(gdb) n
as
9       000009 DISPLAY "one".
(gdb) n
one
10      000010 DISPLAY "two".
(gdb) n
two
11      000011 DISPLAY "three".
(gdb) n
three
12      000012 DISPLAY D123.
(gdb) n
123
13      000013 GOBACK.
(gdb) n
[Inferior 1 (process 9710) exited normally]
(gdb)
```

### Putting it all together

At this point, Visual Studio Code has been installed, and the VSC extension for the Camelian Debugging Extensions has been installed into VSC.  GnuCOBOL 3.1-dev (or higher) has been installed and tested.  The Camelian cbl-gdb debugging extensions have also been installed and tested.

We are now ready to demonstrate source-level debugging of COBOL with Visual Studio Code.

Change the working directory to your `ctest` folder.

Launch VSC with `code .`

Select the `Run` view.  (From the menu, select View > Run.  On a Linux system Ctrl+Shift+D will get you there.)  

Because you do not already have a `.vscode` subdirectory, the Run view will offer you the opportunity to `create a launch.json file`  Select it.

A `select environment` dropdown list will appear.  Select `Camelian cbl-gdb GnuCOBOL debugging`.  Your `launch.json` file will appear.

*Note: Save yourself some future inconvenience by changing the line*

    "program": "${workspaceFolder}/${fileBasenameNoExtension}",

*to*

    "program": "${workspaceFolder}/CTEST",

In the editor view, select the file `CTEST.CBL`.

Set a breakpoint on Line 7 `000007 DISPLAY "Simple".`

*If you can't set a breakpoint (shown as a red dot to the left of the editor's line number) see the note up above about setting the Debug option* `Allow Breakpoints Anywhere`.

Launch the program with `Run > Start Debugging (F5)` from the menu, or press the `F5` key.

You will immediately get an error response:  `Could not find the task 'make'`

Select `Configure Task`, and then choose the option `Create tasks.json file from template`, and then choose `Others Example to run an arbitrary external command`.

Edit your new `tasks.json` file to look like this:

```
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "make",
            "type": "shell",
            "command": "cobcd -x CTEST.CBL"
        }
    ]
}
```
Once that's done, go back to looking at the CTEST.CBL file in the editor view and press F5 again.

VSC will compile the CTEST.CBL program and use gdb to launch it, and it will trap at the breakpoint on Line 7.  That will be indicated by a yellow pentagon surrounding the red breakpoint dot.
In the VARIABLES pane, you will see the variable 01-D123 and its contents.
You are now ready to start working with more complex COBOL programs.
## Advanced topic: Attaching to existing processes
If you are in the business of attaching to existing processes, you'll need a different launch.json file.  You'll need an `attach` configuration and an `inputs` section:

```
    "configurations": [
        {
            "name": "Attach to COBOL debugger",
            "type": "cbl-gdb",
            "request": "attach",
            "cwd":"${workspaceFolder}",
            "solibs":"${env:PRIM_LIBRARY_PATH}",
            "target": "${input:attachtopid}",
        }
    ],
    "inputs": [
        {
            "id": "attachtopid",
            "type": "promptString",
            "description": "Enter the PID to attach to",
            "default": ""
        }
    ]
```

When you execute `Debug > Start Debugging (F5)` and choose `Attach to COBOL debugger`, you will be asked `Enter the PID to attach to`.  You'll need to know the PID (perhaps the application will have been designed to tell you what its PID is, or you'll have found the PID through ps(1) or pgrep(1)
Take special note of the `"solibs"` variable.  As described here it gets set from a global environment variable.  It doesn't have to be set that way, but if the application involves dynamically-loaded shared libraries, the `"solibs"` variable somehow has to be set to a colon-separated list of folders that include the location of your libraries (assuming you have any, of course).  If `"solibs"` isn't set, then the instance of gdb launched by Visual Studio Code won't be able to find the symbols for those libraries.