View previous topic :: View next topic
|
Author |
Message |
Kevin Vaz
New User
Joined: 18 Oct 2016 Posts: 11 Location: India
|
|
|
|
Hi,
I have a CICS web service and in one step I move 0 to many comp-5 variables. The problem that we have come across is that sometimes it gives ASRA and in Abend Aid we can see "Protection Exception" if the same details are requested again it works perfectly fine. We are not able to figure out why it fails sometimes and goes fine other times. |
|
Back to top |
|
|
enrico-sorichetti
Superior Member
Joined: 14 Mar 2007 Posts: 10872 Location: italy
|
|
|
|
Quote: |
... move 0 to many comp-5 variables ... |
tell us the method you use ...
Quote: |
.. sometimes it gives ASRA and in Abend Aid we can see "Protection Exception" ...
|
protection exception as You already know ( You should know ) means that the program is trying to access something where it should not,
the nature/type of the data accessed is irrelevant to the abend
anyway the info provided is not enough to give an advice
are You using somewhere loops where an idex/pointer might grow larger than expected ? |
|
Back to top |
|
|
Kevin Vaz
New User
Joined: 18 Oct 2016 Posts: 11 Location: India
|
|
|
|
Hi,
Thanks for your reply.
We are trying to initialize many comp-5 to 0
All these variables are declared as comp-5 in the same copybook.
Few of them are arrays.
so its like below where A to J are comp-5 variables.
Code: |
Move 0
To A
B
C
D(A)
E
F(A)
G(A,1)
H(A,1)
I
J(A) |
I think the issue is because we are moving 0 to variable(0).. and arrays in mainframe start from 1. but then why does it not fail every time?
edited to consolidate two contiguous posts |
|
Back to top |
|
|
sergeyken
Senior Member
Joined: 29 Apr 2008 Posts: 2010 Location: USA
|
|
|
|
The physical address of destination field for MOVE statement is calculated as:
(destination) = (array_start_address) + (element_size_in_bytes) * (index_value - lowest_index)
If index_value is outside of the range lowest_index...highest_index, then calculated physical address is outside of the memory chunk allocated for the whole array. Two results are possible (randomly):
1) This memory outside of this range may be still available to your program, but very likely you will accidentally override unexpected value(s) of other variables/fields/records/whatever.
2) This memory outside of the array is not allocated to your program, and that's why it is protected by memory access key. This situation for sure is causing "Protection exception" (e.g. ABEND S0C4/S0C5, etc.)
content of the merged post follows
It depends on the particular compiler how to handle the order of operations in the single MOVE
The A can be initialized to 0 either before, or after calculating the destination D(A), etc. There is a good chance that uninitialized (garbage) value of A is used to point to D(A)
Try to separate it, and verify the difference:
Code: |
Move 0 To A
Move 0 to D(A) |
edited to consolidate two contiguous posts |
|
Back to top |
|
|
sergeyken
Senior Member
Joined: 29 Apr 2008 Posts: 2010 Location: USA
|
|
|
|
Kevin Vaz wrote: |
I think the issue is because we are moving 0 to variable(0).. and arrays in mainframe start from 1. but then why does it not fail every time? |
Arrays "in mainframe" are defined differently in different languages/tools. In most cases the low index can be specified explicitly, but default value is often 1 (except C-like languages) |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
For a data-name used as a subscript, the address referened will be the start of the table plus (the length of the table item multiplied by ( value in data-name mnus one).
If the value in your data-name is zero (for A in your example, and I hope that is not a real name) then the storage you access is outside your table.
If your table is in "acquired" storage (GETMAIN, for instancce) and it is at the beginning of that storage, then whether you get an abend (protection exception) or "just" squish something else in error depends entirely on whether the storage accessed in error is "yours" or not. |
|
Back to top |
|
|
enrico-sorichetti
Superior Member
Joined: 14 Mar 2007 Posts: 10872 Location: italy
|
|
|
|
how arrays are defined and arranged in storage depend ONLY on the language and not on the environment ( computer/whatever architecture )
the ARRAY
Code: |
a11 a12 a13
a21 a22 a23 |
can be stored in
Column-major order
e.g., Fortran, ...
Code: |
a11 a21 a12 a22 a13 a23 |
Row-major order
e.g C/C++/Objective-C (for C-style arrays), Mathematica, PL/I, ...
Code: |
a11 a12 a13 a21 a22 a23 |
<sparse> or whatever jargon the language uses
e.g Swift, Java, ...
the elements in the same row are contiguous (like row-major order),
but not the rows.
/soapbox on
for large arrays on ancient <systems> where the cache allcation was pretty primitive
( modulo <something> the real storage address IIRC )
accessing it in the wrong order
would put a lot of strain the cache
every inner index increment would cause a cache-frame fetch from storage
tested on an IBM 3090 200
just filling an array with zeroes
no work at all done for about 20 seconds |
|
Back to top |
|
|
Robert Sample
Global Moderator
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
|
|
|
|
Quote: |
I think the issue is because we are moving 0 to variable(0).. and arrays in mainframe start from 1. but then why does it not fail every time? |
What you think is almost certainly wrong. Variable(0) is most likely part of your program memory and hence would not cause a protection exception. From the Enterprise COBOL Language Reference manual:
Quote: |
If the sending field (identifier-1) is reference-modified or subscripted, or is an alphanumeric or national function-identifier, the reference-modifier, subscript, or function is evaluated only once, immediately before data is moved to the first of the receiving operands.
Any length evaluation, subscripting, or reference-modification associated with a receiving field (identifier-2) is evaluated immediately before the data is moved into that receiving field.
For example, the result of the statement:
Code: |
MOVE A(B) TO B, C(B).
|
is equivalent to:
Code: |
MOVE A(B) TO TEMP.
MOVE TEMP TO B.
MOVE TEMP TO C(B). |
where TEMP is defined as an intermediate result item. The subscript B has changed in value between the time that the first move took place and the time that the final move to C(B) is executed |
However, if A does not have a value before your MOVE is executed, depending upon the specific code being used it is possible that you are referencing a random memory location, which may not be part of your program memory and hence WOULD cause a protection exception. |
|
Back to top |
|
|
sergeyken
Senior Member
Joined: 29 Apr 2008 Posts: 2010 Location: USA
|
|
|
|
Robert Sample wrote: |
Variable(0) is most likely part of your program memory and hence would not cause a protection exception. |
Not because of it is "part of your program".
Variable (0) is used as read-only in MOVE statement; it cannot cause "Protection exception" at all. The ABEND S0C4 is resulted only from the attempt to store new value into protected physical memory address.
Here, probability is 99.9% that the index used to define output fields in MOVE statement is outside of allowed range. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
There is no variable 0. It is a numeric literal. |
|
Back to top |
|
|
Bill Woodger
Moderator Emeritus
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
|
|
|
|
How COBOL deals with this:
Code: |
Move 0 To A
B
C
D(A)
E
F(A)
G(A,1)
H(A,1)
I
J(A) |
Is defined in the COBOL Standard. Zero will be placed in A, B, C, D using the current value of A as the subscript, so zero, so a problem, E, F with the same problem as D, and so with G, H and J. I will be zero.
The "zero" may be a different zero for any of the fields (some can be binary (of any type), packed-decimal, zoned-decimal, floating-point, it doesn't matter to the MOVE and the result will be correct - except for the zero-as-a-subscript).
Depending on the location of those items in relation to the start of the storage that is "yours" you've either squished your own storage or attempted to squish something that is not yours (so the S0C4).
Never use zero as a subscript.
Use descriptive names for data. Why scrunch things up like that? D(A). What's wrong with DESCRIPTIVE-NAME ( DESCRIPTIVE-SUBSCRIPT ).
Oh, forgetting, it is so much easier to write, and who cares if it makes it less convenient to maintain. Written once. Maintained several times. And for code like yours, probably a lot of "problem determination" as well.
Do it properly first time up. It'll save this type of thing, and save significantly over time. |
|
Back to top |
|
|
|