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!