MIDRANGE dot COM Mailing List Archive



Home » MIDRANGE-L » April 2014

Re: CLP pgm with 2 paramters intermittently gettinggarbagewhencalled from AJS



fixed

+1

Paul, you'll find that IBM do not consider this to be any kind of defect - it is a choice made when the system doesn't know what you want it to do with constants, instead of variables with defined sizes.

So maybe we can ask IBM to use a longer value for default padding - what do you choose? 100? Then parameters for IFS path names would easily be problematic. No matter what is selected, it won't be long enough for every situation.

You say you can find no documentation to support using a command.

For the benefit of all and for the archives, perhaps, it's been in the CL Programming manual forever (material I cite here is from V4R4, and I just found the exact same wording in V3R1 documentation), in a section named "Common Errors When Calling Programs and Procedures".

In that section, which also deals with numeric values (default to packed 15,5), is the following information -

===================================================================
The following methods can be used to correct errors in constructing command strings:

v Create the CALL command string to be submitted by concatenating the various portions of the command together into one CL variable. Submit the command string using the request data (RQSDTA) parameter of the SBMJOB command.

v For CL character variables larger than 32 characters where trailing blanks are significant, create a variable that is one character larger than needed and substring a non-blank character into the last position. This prevents the significant blanks from being truncated. The called program should ignore the extra character because it is beyond the length expected.

v Create a command that will initiate the program to be called. Submit the new command instead of using the CALL command. The command definition ensures the parameters are passed to the command processing program as expected.
===================================================================

As to a source search, I don't know of a way to determine from a SBMJOB of a CALL just what the variable lengths are - you have the same problem that the system has - there is no way to know lengths of variables from character strings.

Remember that CALLs use pointers - so the system allocates space at addresses for the parameters.

The called program expects a certain length of data at each address - if you don't do something in your CALL to ensure that enough memory is allocated for YOUR use, then junk is likely - whatever is in memory somewhere after the address, beyond the 32-character limit.

Using the RQSDTA parameter in SBMJOB of a CALL works when you put enough trailing blanks in - to the length of the parameter. You don't need to put an extra character afterwards, when using RQSDTA, because the system doesn't strip trailing blanks.

Using the CMD parameter in SBMJOB of a CALL, the system DOES strip trailing blanks, according to IBM's documentation in the same section. That is why it works to put a non-blank character in the position 1 after the length - this guarantees that enough memory is allocated, because it HAS to account for all the trailing blanks, plus that character. Here's the paragraph that confirms this truncation -

===================================================================
The contents of the character variable is passed as described previously, usually as a quoted character constant with the trailing blanks removed. As a result, the called program may not be passed enough data.
===================================================================

In your search, you are better off just looking for SBMJOB of a CALL or of using CALL in QCMDEXC. Then either go find the source for the called programs and check for size of character variables (and numerics, if not packed 15,5). Or just bite the bullet and create commands that do the CALL in the command-processing program.

You see, commands have parameters, and those parameters have sizes defined. When a command is run, it pre-allocates enough space for the defined size of each parameter. Badabing - no junk is possible.

HTH
Vern

On 4/11/2014 9:34 PM, Mark S Waterbury wrote:
Paul:

Think about it -- it is because you "declare" the type, length (and
decimal places) of each parameter when you create a command.

When you use the CALL command, it accepts a list of zero or more
"generic" parameters. The CALL command has no way to know, for example,
that the second parameter should be "packed decimal" 15 digits, 0 to the
right of the decimal.

Hope this helps,

Mark S. Waterbury

> On 4/11/2014 10:04 PM, Steinmetz, Paul wrote:
Buck, Rob, Mark, and everyone else who chimed in.

Good explanations.
I found some good documentation from CALL help text, also in V7R1 info center (see below).
>From previous info in this thread, is it still correct that if you make a CMD instead of doing a CALL, then this 32 byte issue goes away?
CALL is a CMD, so why would other commands be treated differently?

Also, I opened PMR with IBM to confirm the 32 byte issue, using CALL or CMD
IBM has a doc. Passing parameters that are longer that 32 characters between two CL programs requires special handling.
http://www-01.ibm.com/support/docview.wss?uid=nas8N1014767
IBM confirmed this is not only from a command line, but can also occur pgm to pgm.
As a workaround, IBM is actually suggesting to make the parameter in the calling program 1 byte longer than the parameter in the called program.
IBM also confirmed that using a CMD instead of a call should not have the issue, however, not finding any documentation to confirm/support this.

Question, is there a source search I could perform that would find any program that has a call with a parameter defined with a length of 32 bytes or more.
This may take some coding, but will be worth time spent.

Call help text
Parameters can be passed and received as follows:
o Character string constants of 32 bytes or less are always passed
with a length of 32 bytes (padded on the right with blanks). If
a character constant is longer than 32 bytes, the whole length
of the constant is passed. If the parameter is defined to
contain more than 32 bytes, the calling program must pass a
constant that contains exactly that number of bytes. Constants
longer than 32 characters are not padded to the length expected
by the receiving program.

The receiving program can receive less than the number of bytes
passed (in this case, no message is sent). For example, if a
program specifies that 4 characters are to be received and
ABCDEF is passed (padded with blanks in 26 positions), only ABCD
is accepted and used by the program. Quoted character strings
can also be passed.

-----Original Message-----
From: midrange-l-bounces@xxxxxxxxxxxx [mailto:midrange-l-bounces@xxxxxxxxxxxx] On Behalf Of Buck Calabro
Sent: Friday, April 11, 2014 12:32 PM
To: midrange-l@xxxxxxxxxxxx
Subject: Re: CLP pgm with 2 paramters intermittently gettinggarbagewhencalled from AJS

On 4/11/2014 10:31 AM, Steinmetz, Paul wrote:
One last question.
Does the 32 character clear issue on a SBMJOB only apply to CLP.
No.

Is RPG, RPGLE, etc also impacted?
Yes.

Imagine writing a program in any language that has to receive an arbitrary message and store it in memory. This is what the command processor has to do in order to pass a pointer to a block of memory to the callee. It looks at the message, infers the data type and length and then allocates memory based on those inferences. Having allocated a block of memory, it shares the pointer with the callee, which then maps (like an RPG data structure with OVERLAY) its parameter to that memory block.

So the only question is this: What size variable should my arbitrary message processor set aside? We could allocate 64k, but if the average message is only 10 bytes, that's a lot of wasted space. We could allocate 10 bytes, but when we get a larger message we'd have to re-allocate the memory which takes time. The way to optimise the variable size then, is to analyse the incoming messages and choose a size that covers enough standard deviations to provide a tradeoff between wasting memory and wasting processor time.

IBM chose 32 bytes as that tradeoff point.

When I CALL a program - in any language - from the command line (or SBMJOB), the command processor allocates 32 bytes for a character variable, and re-allocates to the larger size if it finds that the supplied argument is larger than that. Numbers are always packed and put into a 15,5 memory block.

The problem comes when the callee defines a larger parameter, say 50 bytes and the command line supplies fewer than 50 characters. The command processor allocates, clears and loads 32 bytes, properly leaving any memory after that alone. The callee gets a pointer to 32 bytes of properly initialised memory and proceeds to process 50 bytes from that memory block.

The caller (the command processor) did not touch bytes 33 - 50 of that block, and no one knows for sure what previous memory operations did.
So what's in there might be blanks or it might not be. It's variable depending on the state of the memory pool your job is running in.

--buck
--
This is the Midrange Systems Technical Discussion (MIDRANGE-L) mailing list To post a message email: MIDRANGE-L@xxxxxxxxxxxx To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/midrange-l
or email: MIDRANGE-L-request@xxxxxxxxxxxx Before posting, please take a moment to review the archives at http://archive.midrange.com/midrange-l.







Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2014 by MIDRANGE dot COM and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available here. If you have questions about this, please contact