0% found this document useful (0 votes)
151 views5 pages

Using HEAPZONES To Fix C Storage Overlays On ZOS

Uploaded by

Atthulai
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
151 views5 pages

Using HEAPZONES To Fix C Storage Overlays On ZOS

Uploaded by

Atthulai
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 5

Longpela Expertise Home 

| Press Room | Contact Us | Site Map


About Us LongEx Mainframe Quarterly - August 2021
Consulting
Inside Th
Training  
Our Consultants
 Front
technical: Using
HEAPZONES to Fix C Storage  techn
FAQ
C Sto
In the Community Overlays on z/OS z/OS
It's not hard to create a storage overlay in a C program: even easier when  techn
Our e-zine that C program runs on z/OS. If you're tracking a storage overlay down, Probl
Our Books one of the z/OS tools is the Language Environment (LE) HEAPZONES Strin
parameter. In this article, we'll see how it works.  techn
Our Articles
Storage Overlays HEAP
Free Tools and Code Stora
Mainframe Links Suppose we have the following C program:
z/OS
#include <stdlib.h>
char *str1;
Lookup Mainframe main() {
str1 = malloc(15);  Printer Frie
Software
strcpy(str1,"This is a test string");
printf(str1);  Read Previ
free(str1);
}
C programmers will instantly see our problem: we're copying a 21-byte Longp
string into a 15-byte array. When we run this in a batch job, we get a user help w
abend from Language Environment: langua
+CEE3798I ATTEMPTING TO TAKE A DUMP FOR ABEND U4094 TO DATA SET: can po
DZS.D174 to z/O
IGD100I 03DE ALLOCATED TO DDNAME SYS00001 DATACLAS ( ) system
IEA822I COMPLETE TRANSACTION DUMP WRITTEN TO DZS.D174.T0101429.DZSRUNP z/OS. 
+CEE3797I LANGUAGE ENVIRONMENT HAS DYNAMICALLY CREATED A DUMP.
IEA995I SYMPTOM DUMP OUTPUT 031 your o
USER COMPLETION CODE=4094 REASON CODE=0000002C expert
TIME=01.01.42 SEQ=00141 CPU=0000 ASID=0036
PSW AT TIME OF ERROR 078D1400 85DDF9A6 ILC 2 INTC 0D
NO ACTIVE MODULE FOUND
NAME=UNKNOWN
DATA AT PSW 05DDF9A0 - 00181610 0A0DA7F4 001C1811
Language Environment has detected that some of its control information
has been overwritten, and abended with a dump. The SYSOUT DD doesn't
tell us much more:
CEE0802C Heap storage control information was damaged.
The traceback information could not be determined.
This is going to be hard to diagnose. This isn't the only message from a
storage overlay. We may get S0C1 or S0C4 abends if the damage isn't
detected by Language Environment. If running in CICS, we may see some
ASRA/ASRB abends, or user abends like U4038, U4087, U4088, U4092 or
U4094 abends. We may see other nasty messages that are victims of our
storage overlay.
Introducing HEAPZONES
Introduced in z/OS 2.1, HEAPZONES is a lightweight way of detecting
storage overlays from programs writing 'over the end' of variables. They
work with heap storage: think malloc and friends. So, let's tweak our
program:
#pragma runopts(HEAPZONES(8,MSG,16,MSG))
#include <stdlib.h>
char *str1;
main() {
printf(str1);
str1 = malloc(15);
strcpy(str1,"This is a test string");
printf(str1);
free(str1);
}
We've added a #pragma statement to the top. This tells Language
Environment to create a buffer zone of 8 bytes (31-bit addresses) and 16
bytes (64-bit addresses) at the end of our variables. Now if we run our
program, it ends with a return code of zero! We also see something
different written to our SYSOUT:
CEE3716I The heap check zone following the storage at address 1AF39D40
for
length
X'00000010' has been overlayed at
address 1AF39D50. Each byte in the zone from 1AF39D50 to
1AF39D54 should contain the value X'55'.
CEE3717I Control information in a heap check zone has been damaged.
The value at address 1AF39D54 should be greater
than 1AF39D40 and less than or equal to 1AF39D50.
From entry point main at compile unit offset +000000C8 at
entry
offset +000000C8 at address 1AF00A80.
1AF39D40: E38889A2 4089A240 8140A385 A2A340A2 |This is a test s |
1AF39D50: A3998995 874B004F |tring..| |
So, Language Environment has checked this buffer zone at our free() call,
and found that it was overwritten. It's also telling us the text that stomped
over our buffer zone. Suppose we have two variables that we use as
follows:
#pragma runopts(HEAPZONES(8,TRACE,16,TRACE))
#include <stdlib.h>
char *str1, *str2;
main() {
printf(str1);
str1 = malloc(15);
str2 = malloc(50);
strcpy(str1,"This is a test string.");
printf(str1);
free(str1);
free(str2);
}
This still works. Our buffer zone is added to the end of each variable. Nice.
HEAPZONES OPTIONS
So, we've achieved two things. Our program now executes with a zero
return code, and we've got information that there's been an overlay.
Suppose we want our program to abend when this happens, but give us
the same information. We could tweak our #pragma statement to look
like:
#pragma runopts(HEAPZONES(8,ABEND,16,ABEND))
Now, when we run our program, it abends with a U4042 abend:
+CEE3798I ATTEMPTING TO TAKE A DUMP FOR ABEND U4042 TO DATA SET:
DZS.D175.
IGD100I 03DE ALLOCATED TO DDNAME SYS00001 DATACLAS ( )
IEA822I COMPLETE TRANSACTION DUMP WRITTEN TO DZS.D174.T0239105.DZSRUNP
+CEE3797I LANGUAGE ENVIRONMENT HAS DYNAMICALLY CREATED A DUMP.
IEA995I SYMPTOM DUMP OUTPUT 450
USER COMPLETION CODE=4042 REASON CODE=00000003
TIME=02.39.10 SEQ=00199 CPU=0000 ASID=0036
PSW AT TIME OF ERROR 078D1400 85DDF9A6 ILC 2 INTC 0D
NO ACTIVE MODULE FOUND
NAME=UNKNOWN
DATA AT PSW 05DDF9A0 - 00181610 0A0DA7F4 001C1811
Note that this is different to our 'old' abend of a U4094. U4042 with a
reason code of 3 is always an abend because of HEAPZONES. We could
also simply ignore the abend by coding something like:
#pragma runopts(HEAPZONES(8,QUIET,16,QUIET))
Our job ends with a return code of zero, and there's no Language
Environment messages in SYSOUT. But this isn't recommended: we're just
hiding the error. A final option is to specify TRACE:
#pragma runopts(HEAPZONES(8,TRACE,16,TRACE))
This is the same as specifying MSG, but we also get some extra diagnostic
information: a traceback:
Traceback:
DSA Entry E Offset Statement Load Mod
1 CEEVHMSG +00000846 CEEPLPKA
2 CEEV#FH +0000023C CEEPLPKA
3 main +000000C8 DZSC
4 EDCZMINV +000000C2 CEEEV003
5 CEEBBEXT +000001C6 CEEPLPKA
Helpful to find the area in our program where LE found the overlay: our
free() statement is at x'C8' bytes after the beginning of our main
statement.
Some Gotchas
There are some things to remember when using HEAPZONES. For a start,
consider this program:
#pragma runopts(HEAPZONES(8,MSG,16,MSG))
#include <stdlib.h>
char *str1;
main() {
printf(str1);
str1 = malloc(15);
strcpy(str1,"This is a test string");
printf(str1);
}
We've removed our free() function call. If we run this job again, it will
simply end with a zero return code, and no messages. Basically, the same
as coding QUIET in the pragma statement. This is because we've
instructed Language Environment to get our buffer at the end, but without
a free() function call, LE never checks it for overlays.
Have a look at this program:
#pragma runopts(HEAPZONES(8,TRACE,16,TRACE))
#include <stdlib.h>
char str1[15];
main() {
strcpy(str1,"This is a test string.");
printf(str1);
}
Rather than using malloc, we've defined the variable as a character array.
Now we have a similar situation to before when we omitted the free()
function: zero return code as HEAPZONES obtained a buffer, but not
messages as we're not freeing the area.
Let's look at another program:
#pragma runopts(HEAPZONES(8,TRACE,16,TRACE))
#include <stdlib.h>
char *str1, *str2;
main() {
printf(str1);
str1 = malloc(15);
strcpy(str1,"This is a test string. A really, really long one!");
printf(str1);
free(str1);
}
We get our original U4094 abend, with no nice messages from
HEAPZONES.
This is because we're copying a 49-byte string into a 15-byte field. We've
specified a buffer zone of 8 bytes in length, but 15+8 (23) bytes is still
less than the string we're copying in. If we specified a larger buffer zone
so that our string wouldn't run over the edge, we'd be fine.
So, it would be tempting to define a bigger buffer zone (the maximum size
is 1024 bytes) to handle this. However, this would greatly increase the
storage used. So, we need to balance our storage usage against the size
of the strings that may overlay our storage.
There are a few other issues with HEAPZONES:
 Turning it on will affect performance, and not in a good way. It
will also increase storage used, so best to only use it when you
need it.
 IBM recommend that HEAPZONES and HEAPCHK are used
separately – not together.
 Can's use the LE options HEAPZONES and RPTSTG(ON) at the
same time.
Finally, you can't specify HEAPZONES at the system level or region level.
So, we can't specify it in our PARMLIB CEEPRMxx member, of for an entire
CICS region. For our batch job, we could specify the LE options using the
CEEOPTS DD:
//STEP1 EXEC PGM=DZSC
//STEPLIB DD DISP=SHR,DSN=DZS.LOAD
//SYSPRINT DD SYSOUT=*
//CEEOPTS DD *
HEAPZONES(8,TRACE,16,TRACE)
We could also create a CEEUOPT module, and bind it with our module. If
we can't code pragma statements, this will be the way to go for CICS and
IMS programs.
Not a Solution for Everything
HEAPZONES is an excellent tool in our toolbox for diagnosing storage
overlays: perfect when our programs are running 'off the edge' of our
variables. Or in other words, perfect for C. But HEAPZONES comes at a
cost, so it should only be used if necessary, and removed when problems
have been diagnosed. Remember also that this isn't the only tool in our
toolbox. We talk about some more in our partner article.

David Stephens

LongEx Quarterly is a quarterly eZine produced by Longpela Expertise. It


provides Mainframe articles for management and technical experts. It is
published every November, February, May and August.
The opinions in this article are solely those of the author, and do not
necessarily represent the opinions of any other person or organisation. All
trademarks, trade names, service marks and logos referenced in these
articles belong to their respective companies.
Although Longpela Expertise may be paid by organisations reprinting our
articles, all articles are independent. Longpela Expertise has not been paid
money by any vendor or company to write any articles appearing in our e-
zine.

 © Copyright 2021 Longpela Expertise  |  ABN 55 072 652 147


 Legal Disclaimer | Privacy
Websit

You might also like