Batch Interrupter

Feature: 2026-02-17-autostop

Overview

The batch switch allows you to suspend the launch of a specific program within a chain without user intervention. When a program is suspended in this manner, a file containing its PID (process identifier) is generated. Using this information, a debugger such as gdb or the one included in SuperBOL Studio can be attached to the program to analyze its behavior.

Prerequisites

Programs to be interrupted and analyzed must be compiled in debug mode (the -g option) using a modified GnuCOBOL compiler. The intermediate C files generated by GnuCOBOL must be accessible to the debugger.

Operation

Prior to launching the chain, the list of programs to be interrupted must be defined in the COB_STOP_JOBS environment variable. These can be program names as specified by a PROGRAM-ID clause, or executable filenames (for programs compiled as executables using the GnuCOBOL -x option). Multiple program names must be separated by commas.

The name of the file used to store the interrupted program’s PID can be customized using the COB_JOB_PIDFILE variable. If this variable is not set, the file will be named $EXECUTABLE-$JOB.pid, where $EXECUTABLE is the name of the executable file (cobcrun for a module) and $JOB is the name of the program as it appears in the PROGRAM-ID clause.

The chain can then be executed normally. When it is interrupted, the gdb debugger can be attached to the program using the following command:

$ gdb -p $(cat file.pid)

Or, if you prefer to use gdbserver instead of gdb:

$ gdbserver --attach :port $(cat file.pid)

At the start of the debugging session, the program is stopped within a call to the raise function of the standard C library. To step back up into the COBOL program (or at least its C translation), you can use the finish command (press the Enter key several times to repeat the command).

The debugger included in SuperBOL Studio can also be attached to the program by entering the corresponding PID (refer to the SuperBOL Studio documentation for details).

Example

Assume we have a file prog.cob containing two programs with the PROGRAM-IDs prog1 and prog2, and a file subprog.cob containing a program with the PROGRAM-ID subprog. The program prog1 calls prog2 and subprog via a CALL statement.

Compile the programs as follows:

$ cobc -g -x prog.cob
$ cobc -g -m subprog.cob

This produces two binary files: prog and subprog.so. The -g option integrates debugging information into these two binaries and preserves the intermediate C files.

To interrupt the calls to prog1, prog2, and subprog, configure the COB_STOP_JOBS environment variable:

$ export COB_STOP_JOBS=prog1,prog2,subprog

Note: Since all programs contained within the prog executable are targeted, you could also have written:

$ export COB_STOP_JOBS=prog,subprog

Now, launch the program:

$ ./prog

Execution is silently interrupted. Using another terminal, locate the file containing the process PID:

$ ls *.pid
prog-prog1.pid

The execution successfully stopped at program prog1. Attach the debugger:

$ gdb -p $(cat prog-prog1.pid)

The debugger displays:

Program received signal SIGTSTP, Stopped (user).
__pthread_kill_implementation (no_tid=0, signo=20, threadid=140599531862272) at ./nptl/pthread_kill.c:44
44    ./nptl/pthread_kill.c: No such file or directory.
(gdb) 

Using the finish command, step back up to the program code:

(gdb) finish        (press Enter several times)

You will see:

Run till exit from #0  0x00007fdfe1cf1c10 in cob_set_cancel () from /opt/gnucobol-sb/lib/libcob.so.4
prog1_ (entry=0) at prog.c:185
185      b_2 = 0;
(gdb) 

From this point, you can explore the execution of the prog1 program.

If you resume execution (the continue command in gdb), it will automatically stop again at prog2, then subprog, producing the files prog-prog2.pid and prog-subprog.pid. (The PID obviously remains the same, but the presence of the file indicates which program has been interrupted).

Note: If prog.cob had been compiled as a module rather than an executable, the generated PID files would be named cobcrun-prog1.pid, cobcrun-prog2.pid, and cobcrun-subprog.pid.