Microsoft KB Archive/41393

From BetaArchive Wiki

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

The information in this article applies to:
- Microsoft COBOL for MS-DOS and OS/2, versions 3.0, 3.0a, and 4.0

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 "This is the MAIN COBOL program".
      DISPLAY "Press RETURN to call a C function...".
      ACCEPT INKEY.
      CALL "C_CSUB1" USING BY REFERENCE PASS-VALUE.
      ADD 1 TO PASS-VALUE.
      DISPLAY "Okay, here's where we'll make the dynamic call".
      DISPLAY "to the COB3.EXE self-standing COBOL program."
      DISPLAY "(Press RETURN)".
      ACCEPT INKEY.
      CALL "COB2".
      DISPLAY "Cool.  We're back from the COBOL subprogram.".
      DISPLAY "Press RETURN to call the C function again...".
      CANCEL "rksub".
      ACCEPT INKEY.
      CALL "C_CSUB1" USING BY REFERENCE PASS-VALUE.
      DISPLAY "We're finished, eh?".
   STOP RUN.
  * COB2 *****************
  $set ANS85
   IDENTIFICATION DIVISION.
   PROGRAM-ID. rksub.
   ENVIRONMENT DIVISION.
   DATA DIVISION.
   PROCEDURE DIVISION.
       DISPLAY " This is a dynamically linked COBOL sub ".
       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.