Microsoft KB Archive/41393

COBOL Calls to C, COBOL, and C Again May Hang Machine

PSS ID Number: Q41393 Article last modified on 04-20-1993

3.00 3.00a 4.00 | 3.00 3.00a 4.00 MS-DOS | OS/2

Summary: Microsoft COBOL versions 3.0 and 3.0a can produce a program that may hang during run time under these conditions: 1. Main COBOL program calls a C function. 2. Returns from that function. 3. Calls a dynamically linked COBOL subprogram. 4. Returns from that dynamic subprogram. 5. Attempts to call the C function a second time. The machine hangs at this point. Microsoft has confirmed this to be a problem in Microsoft COBOL versions 3.0 and 3.0a under MS-DOS and under the MS-DOS compatibility box in MS OS/2 version 1.1. (This program was not tested in the protected mode of MS OS/2.) This problem also occurs in Microsoft COBOL Professional Development System version 4.0 for MS-DOS. We are researching this problem and will post new information here as it becomes available.

More Information: To work around the problem, make C the main program. The main C program will call the PROGRAM-ID of the main COBOL program, and the programs won’t hang. Since making C the main program eliminates the need for MINITC and makes the problem disappear, this may be a software problem in MINITC. (MINITC is required when COBOL is the main program and calls C.) The sample programs below demonstrate the problem. The first COBOL program makes a static call to a C function. The C function executes and returns properly to the main COBOL program. Then, the program makes a dynamic-link CALL to a separately compiled and linked COBOL subprogram. Upon returning from that subprogram, the main program does some DISPLAYs, CANCELs the external COBOL call, waits for a key press, and then makes the call to the C function again. At this point, the program hangs the computer. Compile the two COBOL programs with the following commands: COBOL COB1; COBOL COB2;

Code Example
* COB1 ****************** $SET ANS85 $SET osext(cbl) $SET no osvs $SET nosmalldd $SET vsc2 $SET rtncode-size(4) DATA DIVISION. WORKING-STORAGE SECTION. 01 PASS-VALUE PIC 9(4) comp-5 VALUE 1. 01 INKEY PIC X.  PROCEDURE DIVISION. MAIN. DISPLAY &quot;This is the MAIN COBOL program&quot;. DISPLAY &quot;Press RETURN to call a C function...&quot;. ACCEPT INKEY. CALL &quot;C_CSUB1&quot; USING BY REFERENCE PASS-VALUE. ADD 1 TO PASS-VALUE. DISPLAY &quot;Okay, here's where we'll make the dynamic call&quot;. DISPLAY &quot;to the COB3.EXE self-standing COBOL program.&quot; DISPLAY &quot;(Press RETURN)&quot;. ACCEPT INKEY. CALL &quot;COB2&quot;. DISPLAY &quot;Cool. We're back from the COBOL subprogram.&quot;. DISPLAY &quot;Press RETURN to call the C function again...&quot;. CANCEL &quot;rksub&quot;. ACCEPT INKEY. CALL &quot;C_CSUB1&quot; USING BY REFERENCE PASS-VALUE. DISPLAY &quot;We're finished, eh?&quot;. STOP RUN. * COB2 ***************** $set ANS85 IDENTIFICATION DIVISION. PROGRAM-ID. rksub. ENVIRONMENT DIVISION. DATA DIVISION. PROCEDURE DIVISION. DISPLAY &quot; This is a dynamically linked COBOL sub &quot;. EXIT PROGRAM. Next, compile the C function with the following: cl /c /Awfl csub1.c /* csub1.c / #pragma check_stack(off) void csub1(int a) { printf (“from c program #%d”,*a); } Finally, link the object modules together with the following: LINK COB1 MINITC CSUB1 /NOE; LINK COB2; To run the program, type the following: COB1

Additional reference words: 3.00 3.00a 4.00 Copyright Microsoft Corporation 1993.