COBOL for AIX

 View Only

Becareful when declaring large XML variables in COBOL for AIX

By Archive User posted Mon June 18, 2018 07:33 PM

  

Originally posted by: BasilTK


Consider the COBOL snippet below:


$ cat test.cbl
000500 WORKING-STORAGE                 SECTION.
001000       01  WK-AREA.
002000     03  WK-XML-CODE             PIC  X(40000000).
.
.
.
003000   PROCEDURE                       DIVISION.
.
.
004000  XML-HANDLER-RTN                 SECTION.
004100     EVALUATE  XML-EVENT
004200         WHEN 'END-OF-ELEMENT'
004300                 IF  ( XML-TEXT = 0 )
044000                     PERFORM  WRITE
045000                 END-IF
046000     END-EVALUATE.
047000 END-XML-HANDLER-RTN.
.
.
048000     EXIT.
$

 

The above code in its entirety will compile correctly. However, when running the resulting exe, you may experience a segfault issue at runtime as shown below:

$ ./a.out
<Thread 1>
<Thread 1>  Signal received: SIGSEGV - Segmentation violation
<Thread 1>
<Thread 1>  Traceback:
<Thread 1>    Offset 0x00000020 in procedure TEST
<Thread 1>    --- End of call chain ---
IWZ995C  SIGSEGV signal received while executing code at location 0x10000880.
IWZ901S  Program exits due to severe or critical error.

Abort
$

 

However, if you comment out IF  ( XML-TEXT = 0 ), it runs fine without a segfault. Why so?

 

This is because we actually run out of memory on the stack due following line:
IF  ( XML-TEXT = 0 )

 

Notice that we reserve about 40 million bytes of memory on the stack for the following line:
03  WK-XML-CODE             PIC  X(40000000).

 

The IF statement below is comparing an alphanumeric to a numeric:

   IF ( XML-TEXT = 0 )

 

The numeric 0 gets turned into 1 byte zoned variable. It then compares the fiirst character of XML-TEXT to the one byte zoned number.   
COBOL rules then say if its not different in the first byte, blank pad and compare the rest of XML-TEXT to blanks.

It's at this stage where we run into the problem. To compare the rest of XML-TEXT to blanks, we first determine how big it could be; and right now in the example we try to create a character temp  equivalent in size to XML-TEXT which is "PIC  X(40000000)" in size, memset it to blanks and compare to XML-TEXT.   The character temp is in automatic storage (stack based). It is at this point where we try to create the temp and we end up failing due to the lack of available memory.
                      
The simplest solution is to increase the ulimit -s value to a large enough value.
ie
$ ulimit -s <large_enough_value>
or
$ ulimit -s unlimited
                                                                                
If ulimits cannot be modified for any reason, then the above test case can be modified to use reference modifications for the XML-TEXT in the IF statement.
                                                                                  
eg:
Instead of:                                                                       
IF( XML-TEXT = 0 )                                            
use:                                                                              
IF( XML-TEXT (1:1) = 0)                                        
                                                                                  
ie, the length of the characters that you want to compare.

 

Hope this helps!

0 comments
4 views

Permalink