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
## Basic methodology
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).
## Installation
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`
## Additional extensions
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
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.