Home > Archive > Cobol > June 2004 > Is it possible to use the value of the PROGRAM ID within the source code?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Is it possible to use the value of the PROGRAM ID within the source code?
|
|
| David Latimer 2004-06-08, 8:55 am |
| I'm using MicroFocus COBOL 4.0 on UnixWare 2.1.3.
I'd quite like to be able to use the Program Id in every program using
the same phrase (e.g. MOVE prog id TO XYZ).
There are other ways of getting the same result but I just wondered if
this was possible.
David L.
| |
| Robert Wagner 2004-06-09, 8:55 pm |
| david@quantumcat.demon.co.uk (David Latimer) wrote:
>I'm using MicroFocus COBOL 4.0 on UnixWare 2.1.3.
>
>I'd quite like to be able to use the Program Id in every program using
>the same phrase (e.g. MOVE prog id TO XYZ).
>
>There are other ways of getting the same result but I just wondered if
>this was possible.
You cannot get it from Cobol but you can get it from Unix. Some Unixen store it
in an environment variable named _ (underscore). I know Solaris does. To read it
say:
01 program-name pic x(30) value spaces.
01 a-underscore pointer.
linkage section.
01 underscore pic x(30).
call 'cobgetenv' using z'_' returning a-underscore
set address of underscore to a-underscore
unstring underscore delimited by low-value into program-name
This only works if you compile to an executable, not .gnt.
The following will work on any species of Unix:
call 'system' using z"pgrep -s0 | xargs -Ipid ps -fppid | awk '{print $8}' | sed
-e'/CMD/d' -e'/xargs/d' -e'/ksh/d' -e'/awk/d' -e'/sed/d' >xxx"
Your program name will be in file xxx. Alternatively, you could send it to an
environment variable which can be read as above by changing >xxx to
| xargs -Iprog export _=prog
If you compile to .gnt, change awk to print $9. I used the -f option on ps so it
would show the whole command line.
| |
| Richard 2004-06-10, 3:55 am |
| robert.deletethis@wagner.net (Robert Wagner) wrote
[color=darkred]
> If you compile to .gnt, change awk to print $9. I used the -f option on ps so it
> would show the whole command line.
That is not going to show the name of any CALLed programs, which is
probably the point of the request.
| |
| Robert Wagner 2004-06-10, 3:55 am |
| riplin@Azonic.co.nz (Richard) wrote:
>robert.deletethis@wagner.net (Robert Wagner) wrote
>
>
it[color=darkred]
>
>That is not going to show the name of any CALLed programs, which is
>probably the point of the request.
No, he wants the name of the Main program, probably to print in a log file or
report header. The logic getting the name would best be in a called program.
Printing 'getmyname' on every report would not be informative.
If programs are compiled to .gnt, the gnt _is_ a called program .. called by
cobrun, which would appear in column 8.
| |
| Stephen Gennard 2004-06-10, 8:55 am |
| You could use x/open syntax...
01 ws-stuff pic x(80).
display 0 upon argument-number
accept ws-stuff from argument-value
display "Main exe is : " ws-stuff
It works with both "cobrun xx" and your program built as an exe....
--
Stephen
"David Latimer" <david@quantumcat.demon.co.uk> wrote in message
news:a9026f4e.0406080231.4a745813@posting.google.com...
> I'm using MicroFocus COBOL 4.0 on UnixWare 2.1.3.
>
> I'd quite like to be able to use the Program Id in every program using
> the same phrase (e.g. MOVE prog id TO XYZ).
>
> There are other ways of getting the same result but I just wondered if
> this was possible.
>
> David L.
| |
| docdwarf@panix.com 2004-06-10, 8:55 am |
| In article <40c800ce.497169106@news.optonline.net>,
Robert Wagner <robert.deletethis@wagner.net> wrote:
>riplin@Azonic.co.nz (Richard) wrote:
>
>it
>
>No, he wants the name of the Main program, probably to print in a log file or
>report header.
Mr Wagner, how do you manage to translate 'I'd quite like... *every*
program using the same phrase' to 'he wants the name of the Main program'?
DD
| |
| Stephen Gennard 2004-06-10, 8:55 am |
| If you had Server Express you could use CBL_GET_PROGRAM_INFO...
01 ws-pi-function pic x(4) comp-5.
01 ws-pi-param.
03 ws-pi-size pic x(4) comp-5.
03 ws-pi-flags pic x(4) comp-5.
03 ws-pi-handle usage pointer.
03 ws-pi-prog-id usage pointer.
03 ws-pi-gpi-attrs pic x(4) comp-5.
01 ws-pi-name-buf pic x(60).
01 ws-pi-name-len pic x(4) comp-5.
procedure division.
move 0 to ws-pi-function
move 20 to ws-pi-size
move 2 to ws-pi-flags
move length of ws-pi-name-buf to ws-pi-name-len
call "CBL_GET_PROGRAM_INFO" using
by value ws-pi-function
by reference ws-pi-param
by reference ws-pi-name-buf
by reference ws-pi-name-len
end-call
display "Return-code : " return-code
display ws-pi-name-buf
"David Latimer" <david@quantumcat.demon.co.uk> wrote in message
news:a9026f4e.0406080231.4a745813@posting.google.com...
> I'm using MicroFocus COBOL 4.0 on UnixWare 2.1.3.
>
> I'd quite like to be able to use the Program Id in every program using
> the same phrase (e.g. MOVE prog id TO XYZ).
>
> There are other ways of getting the same result but I just wondered if
> this was possible.
>
> David L.
| |
| Richard 2004-06-10, 8:55 pm |
| robert.deletethis@wagner.net (Robert Wagner) wrote
>
> No, he wants the name of the Main program,
Where did you get that from ? What part of "every" did you not
understand ?
> probably to print in a log file or report header.
I do that, using the name of the program that prints the report, not
just the name of the 'main' program which is the same one in most of
my systems.
> The logic getting the name would best be in a called program.
> Printing 'getmyname' on every report would not be informative.
Then obviously, to me at least, this would _not_ be the 'best' if the
result would be completely useless. So why did you put 'best' ?
But he probably doesn't want 'mainprog' on every report either.
> If programs are compiled to .gnt, the gnt _is_ a called program .. called by
> cobrun, which would appear in column 8.
So, you have satisfied his 'every' with just 1 out of, potentially,
dozens of programs with different names.
The way that I get the program name available in each program in many
systems is to pass a parameter block around on each CALL that includes
the name used by the CALL. This, of course, is not a simple solution
for a system that doesn't do that.
The easiest way is probably to process all the source code to pick up
the word after Program-id (or use the file name) and add a W-S item
for all source files.
| |
| Robert Wagner 2004-06-10, 8:55 pm |
| docdwarf@panix.com wrote:
>Mr Wagner, how do you manage to translate 'I'd quite like... *every*
>program using the same phrase' to 'he wants the name of the Main program'?
Just a guess. Besides, there's no easy way to get the name of a called program.
| |
| Robert Wagner 2004-06-10, 8:55 pm |
| riplin@Azonic.co.nz (Richard) wrote:
>robert.deletethis@wagner.net (Robert Wagner) wrote
>
>
>Where did you get that from ? What part of "every" did you not
>understand ?
>
>
>I do that, using the name of the program that prints the report, not
>just the name of the 'main' program which is the same one in most of
>my systems.
In the case of reports, I hardcode the program name in the header. If a program
prints two reports, I suffix the name with 1 and 2.
In the case of error messages from batch programs, we use a utility starter
program analogous to cobrun. It is an executable, the applications are
dynamically callable. The starter parses the command line, connects to the
database, does housekeeping such as setting nls_date_format, WRITES THE PROGRAM
NAME AND START TIME TO LOG FILES SYSOUT AND SYSERR, then calls the program.
Any messages from the program do not need a program id because it's already in
the log file.
The starter program could pass the program name as parameter 1, but we don't do
that. Structurally, the starter program *should* be the one to abort() if the
return code is non-zero. We can't do that because of a deficiency in 'anim',
which refuses to show called programs even though they are in the 'core' image.
>
>Then obviously, to me at least, this would _not_ be the 'best' if the
>result would be completely useless. So why did you put 'best' ?
I meant that if the called program getmyname got its own name, its output would
be uninformative. It should return the name of Main or Caller or, preferably, it
should walk back the whole call stack.
>The way that I get the program name available in each program in many
>systems is to pass a parameter block around on each CALL that includes
>the name used by the CALL. This, of course, is not a simple solution
>for a system that doesn't do that.
Our programs, developed on AS/400, keep an internal 'perform stack'. On entry to
every paragraph, they bump an index and insert the paragraph's name; on exit,
they set the index down by 1. A standard abend process in a copybook dumps the
'perform stack' to syserr. I was told by an AS/400 pro that the reason for this
is "The AS/400 debugger is so bad that programmers will do anything to avoid
using it." Out of curiosity, I looked at the debugger. It looks very much like
Micro Focus' anim. One can set breakpoints on lines of code, but not a data
elements, telling to stop when the element is touched or changed. Our most
common question is 'Show me when this field is changed to spaces'. Good
debuggers (possible oxymoron) such as MS DevStudio have it; bad ones don't.
[flame-bait alert] I don't use debuggers except as a last resort. They waste
more time than they save. If you can't read code and see what it does, you
shouldn't call yourself a programmer. Maybe you'd be happier as a tester. [end
of alert]
>The easiest way is probably to process all the source code to pick up
>the word after Program-id (or use the file name) and add a W-S item
>for all source files.
That's what he's gonna do, evinced by subsequent postings.
| |
| Chuck Stevens 2004-06-10, 8:55 pm |
|
"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
news:40c8d8c2.552461456@news.optonline.net...
> Just a guess. Besides, there's no easy way to get the name of a called
program.
I wouldn't think this would be difficult for implementors to provide, and
would suggest you propose that a future standard provide an Intrinsic
Function to provide the program-name, function-name, class-name or
method-name of wherever you are at the moment. Whether it'd be
unconditionally meaningful or not is another question!
I'd also suggest that, if you called a program, the *caller* (so far as I
know always) knows its name, and if you need the called routine to know the
name by which it was called, I'd say passing the name using a by-value
parameter shouldn't take *that* many hours of head-scratching to figure out.
I mean, how difficult is CALL 'a-program' USING BY VALUE 'a-program' ... "?
-Chuck Stevens
| |
| docdwarf@panix.com 2004-06-10, 8:55 pm |
| In article <40c8d8c2.552461456@news.optonline.net>,
Robert Wagner <robert.deletethis@wagner.net> wrote:
>docdwarf@panix.com wrote:
>
>
>
>Just a guess.
I... see.
DD
| |
| Joe Zitzelberger 2004-06-11, 3:55 am |
| Just a thought.
On z/OS you could find this information by looking at the PPA1 and PPA2
parts of the loaded program (offset 168 in one of those).
Whatever platform you are on must have a well defined object file format
(PEF, XCOFF, ELF, whatever). The docs for that format ought to tell you
how to find the executable name.
This method just begs for someone to reply with a "Cobol programmers
should never have to know load module format or use pointers or anything
that smells of programming..." post. But it really is easy to do...
| |
| William M. Klein 2004-06-11, 3:55 am |
| Joe,
I won't reply the way you suggested, but rather by saying that *IF* one is in
an IBM mainframe environment, what this thread actually reminds me of is the
existing SHARE requriement,
"SSLNGC0313587 New LE Callable Service to get (various) Program Names
...
A new LE callable service (with capabilities well beyond CEE3GRN) should be
created to obtain various program names. This should include options to obtain:
- The currently executing program's name
- The name of the program that "activated" (Called, Invoked, whatever) the
currently executing program
- The name of the program at the "top" of the current LE "enclave"
- The name of the program at the "top" of the current LE "thread"
For each of these, sub-options may be required to provide information such as
- Any "alias" by which the program was entered
- Any "long-name" (with mixed characters) as supported by the Binder
- Any Entry-point name when other than the modules name
Finally, although not necessarily a part of this callable service, it would also
be desirable to be able to obtain the "data set name" (HFS, PDS, PDSE, LPA
member, or whatever) from which each of these entities was obtained."
--
Bill Klein
wmklein <at> ix.netcom.com
"Joe Zitzelberger" <joe_zitzelberger@nospam.com> wrote in message
news:joe_zitzelberger-BF8C66.21441110062004@corp.supernews.com...
> Just a thought.
>
> On z/OS you could find this information by looking at the PPA1 and PPA2
> parts of the loaded program (offset 168 in one of those).
>
> Whatever platform you are on must have a well defined object file format
> (PEF, XCOFF, ELF, whatever). The docs for that format ought to tell you
> how to find the executable name.
>
> This method just begs for someone to reply with a "Cobol programmers
> should never have to know load module format or use pointers or anything
> that smells of programming..." post. But it really is easy to do...
| |
| Robert Wagner 2004-06-11, 8:55 am |
| "Chuck Stevens" <charles.stevens@unisys.com> wrote:
>
>"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
>news:40c8d8c2.552461456@news.optonline.net...
>
>program.
>
>I wouldn't think this would be difficult for implementors to provide, and
>would suggest you propose that a future standard provide an Intrinsic
>Function to provide the program-name, function-name, class-name or
>method-name of wherever you are at the moment. Whether it'd be
>unconditionally meaningful or not is another question!
A general-purpose solution would be to walk back the call stack returning the
names of all programs from the program of interest back to Main.
>I'd also suggest that, if you called a program, the *caller* (so far as I
>know always) knows its name,
Not necessarily. A certain breed likes to 'clone' programs by copying them to a
slightly different name, then changing a few lines of code. I've seen 15
'versions' of the same program.
> and if you need the called routine to know the
>name by which it was called, I'd say passing the name using a by-value
>parameter shouldn't take *that* many hours of head-scratching to figure out.
>I mean, how difficult is CALL 'a-program' USING BY VALUE 'a-program' ... "?
Generally, you can't pass strings on the stack. You can only pass words, such as
a pointer to the string. Make that 'CALL a-program USING (default BY REFERENCE)
a-program'.
| |
| Joe Zitzelberger 2004-06-11, 3:55 pm |
| In article <Pf8yc.9773$uX2.6404@newsread2.news.pas.earthlink.net>,
"William M. Klein" <wmklein@nospam.netcom.com> wrote:
> Joe,
> I won't reply the way you suggested, but rather by saying that *IF* one is
> in
> an IBM mainframe environment, what this thread actually reminds me of is the
> existing SHARE requriement,
>
> "SSLNGC0313587 New LE Callable Service to get (various) Program Names
> ...
> A new LE callable service (with capabilities well beyond CEE3GRN) should be
> created to obtain various program names. This should include options to
> obtain:
>
> - The currently executing program's name
This can be done via the prefix area.
> - The name of the program that "activated" (Called, Invoked, whatever) the
> currently executing program
The entire call chain can be observed using a tiny assembler program
that will dereference save areas and do a CSVQUERY on the owner of the
save area location.
> - The name of the program at the "top" of the current LE "enclave"
This can be done in Cobol by looking at the SWA.
> - The name of the program at the "top" of the current LE "thread"
I'm not sure how to do this one.
> For each of these, sub-options may be required to provide information such as
> - Any "alias" by which the program was entered
> - Any "long-name" (with mixed characters) as supported by the Binder
> - Any Entry-point name when other than the modules name
>
> Finally, although not necessarily a part of this callable service, it would
> also
> be desirable to be able to obtain the "data set name" (HFS, PDS, PDSE, LPA
> member, or whatever) from which each of these entities was obtained."
I'll post some code soon...
| |
| Chuck Stevens 2004-06-11, 3:55 pm |
|
"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
news:40c9685a.589226654@news.optonline.net...
> A general-purpose solution would be to walk back the call stack returning
the
> names of all programs from the program of interest back to Main.
That is presuming that the implementation has an accessible structure such
as a "call stack".
> Not necessarily. A certain breed likes to 'clone' programs by copying them
to a
> slightly different name, then changing a few lines of code. I've seen 15
> 'versions' of the same program.
Yes, you could have any number of programs with the same PROGRAM-ID, even in
the same multiple-program structure. If these programs are all
separately-compiled, the PROGRAM-ID becomes less interesting as seen from
outside the program, and what is important is how the calling program refers
to the separately-compiled called program.
> Generally, you can't pass strings on the stack. You can only pass words,
such as
> a pointer to the string. Make that 'CALL a-program USING (default BY
REFERENCE)
> a-program'.
Last sentence first: "CALL a-program USING BY CONTENT a-program" would I
think be preferable. The objective here is to ensure that a-program cannot
step on this particular parameter.
In our implementation, there is no pre-execution-time linking phase; the
determination as to whether the target procedure is nested or
separately-compiled has to be made at execution time and is a rather
expensive process. Thus, while "CALL <dataname>" works it is almost
invariably much more costly than "CALL <literal>".
And I was indeed mistaken; I was looking at the wrong format in ISO/IEC
1989:2002. By-value and by-content literal parameters are only allowed in
program-prototype calls.
But where does the standard require that the implementor keep track of
information about calling history in some sort of hardware stack? Where
does the standard prohibit putting strings (do you mean strictly
"alphanumeric literals" or do you include "alphanumeric data items"?) on
that stack?
BY CONTENT non-numeric parameters of arbitrary length are allowed.
How the implementation *accomplishes* passing, say, a 30,000-byte record as
a parameter BY CONTENT is none of the end user's business; the only concern
is how the caller sees it if the called program happens to step on its
contents (and the correct expectation is that it be unchanged).
So far as I know there's nothing wrong with
MOVE "a-program" TO program-to-call.
CALL "a-program" USING BY CONTENT program-to-call ...
or even
MOVE "a-program" TO program-to-call.
CALL program-to-call USING BY CONTENT program-to-call ...
if one is so inclined.
What's this about words? It may be *common* to use some sort of fixed
structure to describe a parameter passed by content -- but there is
absolutely no requirement that that structure be inherently different from
the structure that would be used for parameters passed by reference, or that
the structure be related in any way to any other structure that might be
used in the operating environment.
Moreover, there is nothing except resources and incentive preventing an
obsolete-computer buff from implementing a fully-2002-compliant COBOL
implementation on a Burroughs B3500, or even an IBM 1401, for which
architectures the concept of "fixed-length words" as I understand the
concept does not exist.
-Chuck Stevens
| |
| Richard 2004-06-11, 8:55 pm |
| robert.deletethis@wagner.net (Robert Wagner) wrote
> A general-purpose solution would be to walk back the call stack returning the
> names of all programs from the program of interest back to Main.
That doesn't solve anything. It is unlikely that the name of the
calling program, nor even that of the called program is actually on
the stack (presuming that it soes actually do this using a stack in
the first place). When a program does a 'CALL progname USING
parameters', you will notice that progname is _not_ one of the
parameters.
But also the CALL does not necessarily go to the called program
directly. It most likely goes to the run-time resolver, so going one
up the stack does not necessarily go to the caller.
So even if one could work out the stack frames to access the calling
program there is still _nothing_ as a 'general-purpose' in that
program that would give that name. If there was then it would also be
in the called program, so walking the stack is unrequired.
[color=darkred]
> Not necessarily. A certain breed likes to 'clone' programs by copying them to a
> slightly different name, then changing a few lines of code. I've seen 15
> 'versions' of the same program.
I am not sure why you think that this means that the caller does not
know its own name ? Are you saying that the programmer copies the
code to a new file and does not change the program-id, or other
references ?
This can become a problem with, say, Microfocus, where a dynamic
loading for a CALL is by file name and a CANCEL is by Program-Id. If
they don't match there can be unrequired results.
| |
| Robert Wagner 2004-06-11, 8:55 pm |
| "Chuck Stevens" <charles.stevens@unisys.com> wrote:
>"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
>news:40c9685a.589226654@news.optonline.net...
>
>the
>
>That is presuming that the implementation has an accessible structure such
>as a "call stack".
Every called program has a way of returning to its caller.
>such as
>REFERENCE)
>
>Last sentence first: "CALL a-program USING BY CONTENT a-program" would I
>think be preferable. The objective here is to ensure that a-program cannot
>step on this particular parameter.
But it can. It just cannot modify it back in the caller's memory.
I don't think this is a realistic concern. Programs generally don't recklessly
modify parameters.
>In our implementation, there is no pre-execution-time linking phase; the
>determination as to whether the target procedure is nested or
>separately-compiled has to be made at execution time and is a rather
>expensive process. Thus, while "CALL <dataname>" works it is almost
>invariably much more costly than "CALL <literal>".
It is in nearly all environments. It need not be. Sure, dataname can change, but
99.99 percent of the time it doesn't. INLINE code could (should) check that it's
the same and then call directly, with little more overhead than a static link. I
used to write enhancers that reached back and modified generated code to do
exactly that.
> where does the standard require that the implementor keep track of
>information about calling history in some sort of hardware stack? Where
>does the standard prohibit putting strings (do you mean strictly
>"alphanumeric literals" or do you include "alphanumeric data items"?) on
>that stack?
>
>BY CONTENT non-numeric parameters of arbitrary length are allowed.
>
>How the implementation *accomplishes* passing, say, a 30,000-byte record as
>a parameter BY CONTENT is none of the end user's business; the only concern
>is how the caller sees it if the called program happens to step on its
>contents (and the correct expectation is that it be unchanged).
True but discordant with the culture of operating systems and other languages.
Micro Focus says:
"If the program being called is not COBOL, the size of the additional data item
should not exceed the maximum size of the system area (typically the size of a
POINTER on the system); otherwise the system might become catastrophically
corrupt."
You wouldn't want to be the one found to have "catastrophically corrupted" the
system. I know .. FUD.
>What's this about words? It may be *common* to use some sort of fixed
>structure to describe a parameter passed by content -- but there is
>absolutely no requirement that that structure be inherently different from
>the structure that would be used for parameters passed by reference, or that
>the structure be related in any way to any other structure that might be
>used in the operating environment.
The idea of BY CONTENT and BY VALUE is based on paranoia and disrespect. Its
premise is that called programs may irrationally corrupt parameter values. In
the real world, that's not a realistic concern.
>Moreover, there is nothing except resources and incentive preventing an
>obsolete-computer buff from implementing a fully-2002-compliant COBOL
>implementation on a Burroughs B3500, or even an IBM 1401, for which
>architectures the concept of "fixed-length words" as I understand the
>concept does not exist.
On the 1401 I wrote a rudimentary operating system because the machine didn't
come with one. On the B3500/4700 I completely rewrite the communications
software and print spooler in Cobol and contributed to the design of MCPV.
You're correct: they didn't have words nor stacks, but they did have a pointer
back to the caller.
| |
| Robert Wagner 2004-06-12, 3:55 pm |
| riplin@Azonic.co.nz (Richard) wrote:
>robert.deletethis@wagner.net (Robert Wagner) wrote
>
>
>That doesn't solve anything. It is unlikely that the name of the
>calling program, nor even that of the called program is actually on
>the stack (presuming that it soes actually do this using a stack in
>the first place). When a program does a 'CALL progname USING
>parameters', you will notice that progname is _not_ one of the
>parameters.
The stack contains a return address. Using that, the program name can usually be
found near the beginning of its segment or in a public symbol table.
>But also the CALL does not necessarily go to the called program
>directly. It most likely goes to the run-time resolver, so going one
>up the stack does not necessarily go to the caller.
Let's try to stay in focus. We're interested in the RETURN address, not the call
address.
>So even if one could work out the stack frames to access the calling
>program there is still _nothing_ as a 'general-purpose' in that
>program that would give that name. If there was then it would also be
>in the called program, so walking the stack is unrequired.
Heap walkers are a very common diagnostic tool. I'm disappointed to read you're
unfamiliar with the concept.
>
>
>I am not sure why you think that this means that the caller does not
>know its own name ? Are you saying that the programmer copies the
>code to a new file and does not change the program-id, or other
>references ?
Yes, it is common practice. Then I'm asked to 'find every place where a program
does A and change it to B.' I find 15 copies of the same program doing A. Nobody
knows which is the production version. The files' 'last touched' timestamps are
all the same, the last time someone ran a GREP.
Thinking ahead, I'd developed a tool to track program executions. It shows one
of the 15 running every day, the others seldom or never. I change that one.
Months later the file gets broken. Hours of research leads to 'we run that
program when someone asks for special handling.' Why didn't you put special
handling logic in the production program? The answer: 'I believe in the KISS
principle.'
This kind of abuse is WHY big shops are burdened with Change Management software
and programmers locked out of the production box.
>This can become a problem with, say, Microfocus, where a dynamic
>loading for a CALL is by file name and a CANCEL is by Program-Id. If
>they don't match there can be unrequired results.
Cancel? Let the operating system worry about cleanup.
| |
| Richard 2004-06-12, 8:55 pm |
| robert.deletethis@wagner.net (Robert Wagner) wrote
> The stack contains a return address. Using that, the program name can usually
The 'return address' need not be to the actual CALLing program. It
may be to the run-time so that the run-time can decrement the 'active'
counter or somesuch. The run-time does know which programs are
active, which is why it can give an error when a re-entry is tried.
> found near the beginning of its segment or in a public symbol table.
I just looked as some object code. Yes the program name is there, so
are a lot of other names, and in no particular order. This is also
_not_ a general solution as you claimed and may be entirely specific
to particualr compilers and environments, each one requiring a
different solution.
>
> Let's try to stay in focus. We're interested in the RETURN address, not the
> call address.
And the return address may be back to the run-time which is where the
actual entry to the called program came from.
>
> Heap walkers are a very common diagnostic tool. I'm disappointed to read
> you're unfamiliar with the concept.
You are now between the stack and the heap. They are
different things you know.
As I said there is still _nothing_ that make this a general solution.
> Yes, it is common practice. ...
> Thinking ahead, I'd developed a tool to track program executions. It shows one
> of the 15 running every day, the others seldom or never. I change that one.
So, how did you know which one ran ? Obviously not from the
Program-Id if they were all the same.
How did the program get executed ? Something must have specified its
name, presumably its file name. Surely you should have been able to
find which one was run by looking at what CALLed it, or the job cards.
> Months later the file gets broken. Hours of research leads to 'we run that
> program when someone asks for special handling.'
That shows you have a complete lack of 'thinking ahead'. Either you
should have changed all 15 or should have 'archived' the other 14 so
they could be used.
> Yes, it is common practice. ...
> This kind of abuse is WHY big shops are burdened with Change Management
> software and programmers locked out of the production box.
The 'common practice' and 'burdened by CMS' seem to be incompatible.
| |
| Richard 2004-06-12, 8:55 pm |
| robert.deletethis@wagner.net (Robert Wagner) wrote
>
> Every called program has a way of returning to its caller.
But that not not imply that the called program has _access_ to the
caller's memory nor to anything above that.
| |
| JerryMouse 2004-06-12, 8:55 pm |
| David Latimer wrote:
> I'm using MicroFocus COBOL 4.0 on UnixWare 2.1.3.
>
> I'd quite like to be able to use the Program Id in every program using
> the same phrase (e.g. MOVE prog id TO XYZ).
>
> There are other ways of getting the same result but I just wondered if
> this was possible.
>
> David L.
Inasmuch as this thread has wandered over all creation, let's start another:
Why do you want to do this? What do you want to accomplish?
In olden days, programmers used to mark the start of Working-Storage with:
01 FILLER PIC X(24) VALUE 'START OF WORKING-STORAGE.
We use the same technique. All our COBOL programs start with:
01 FILLER PIC X(24) VALUE 'Microsoft C++ (c) 1997'.
| |
| Robert Wagner 2004-06-13, 3:55 am |
| riplin@Azonic.co.nz (Richard) wrote:
>robert.deletethis@wagner.net (Robert Wagner) wrote
>
[color=darkred]
>
>The 'return address' need not be to the actual CALLing program. It
>may be to the run-time so that the run-time can decrement the 'active'
>counter or somesuch. The run-time does know which programs are
>active, which is why it can give an error when a re-entry is tried.
Even if the program does return to a run-time, the return address will be below
it on a stack. It has to be in order for recursion to work.
>
>I just looked as some object code. Yes the program name is there, so
>are a lot of other names, and in no particular order. This is also
>_not_ a general solution as you claimed and may be entirely specific
>to particualr compilers and environments, each one requiring a
>different solution.
The location of the name is defined by the file format, which is defined by the
operating system. It has to be so Task Viewers can show what's running,
including called programs.
>
>You are now between the stack and the heap. They are
>different things you know.
Heap walkers and Task viewers follow the same concept, and are often integrated.
The concept is walking up and down a tree structure.
one[color=darkred]
>
>So, how did you know which one ran ? Obviously not from the
>Program-Id if they were all the same.
From the file name. Logging executions is especially easy when they use 'cobrun'
to start programs. Write a script named 'cobrun' and put it ahead of Micro Focus
in the PATH.
>How did the program get executed ? Something must have specified its
>name, presumably its file name. Surely you should have been able to
>find which one was run by looking at what CALLed it, or the job cards.
That just moves the problem up a level without solving it. There may be obsolete
scripts running obsolete programs. Some programs were run by a human typing the
name on a command line. Some are called by dead code hooked to a menu item that
no longer displays.
Analysis of the thousands of programs showed the same happening at the file
level. There were thousands of FDs that were never opened, or opened but not
read or written, or opened for update but not updated. I posted the analysis
program here last year.
This is what happens when programs are 'written' by copy-and-paste.
>
>That shows you have a complete lack of 'thinking ahead'. Either you
>should have changed all 15 or should have 'archived' the other 14 so
>they could be used.
If I changed all 15, the forces of darkness would say I was wasting time
changing obsolete programs. If I'd archived the unused ones, they'd wait for (or
create) a crisis, then point the finger at me for removing an 'essential'
program. Or they'd run it unmodified, thereby breaking the file.
What SHOULD have been done was complete elimination of duplicate code. OO makes
it easier to do that. If one needs 'special handling' for one run, he or she
overloads a method for that run only.
>
>The 'common practice' and 'burdened by CMS' seem to be incompatible.
Undisciplined redundant code is found in small shops lacking Change Management.
Big shops make a clear distinction between production code and everything else.
Obfuscators still find ways to ply their trade. ODBC is one of their best
friends, enabling them to write applications in Access without the inconvenience
of controls. Access feels like a programming environment designed by Walmart.
The more things change, the more they stay the same.
| |
| Robert Wagner 2004-06-13, 3:55 am |
| riplin@Azonic.co.nz (Richard) wrote:
>robert.deletethis@wagner.net (Robert Wagner) wrote
>
>
>But that not not imply that the called program has _access_ to the
>caller's memory nor to anything above that.
The language requires this to work:
Program A: call 'B' using BY REFERENCE a-1
Program B: call 'C' using BY REFERENCE a-1, b-2
Program C: display 'I have access to ' a-1 ' and ' b-2
Operating systems protect memory at the Process level. Can you cite one that
works at the called program level? I thought not.
| |
| Richard 2004-06-13, 3:55 am |
| robert.deletethis@wagner.net (Robert Wagner) wrote
>
> The language requires this to work:
>
> Program A: call 'B' using BY REFERENCE a-1
> Program B: call 'C' using BY REFERENCE a-1, b-2
> Program C: display 'I have access to ' a-1 ' and ' b-2
>
> Operating systems protect memory at the Process level. Can you cite one that
> works at the called program level? I thought not.
It doesn't need to be protected by the OS to not have access to
something, just because you have a return address to the code segemnt
(presuming it is not just the run-time's) does not mean that you can
usefully find the data segement.
The LINKAGE areas may be of little use as these, as you show, may be
areas in some other program entirely.
| |
| Richard 2004-06-13, 3:55 am |
| robert.deletethis@wagner.net (Robert Wagner) wrote
> Even if the program does return to a run-time, the return address will be below
> it on a stack. It has to be in order for recursion to work.
It may be _somewhere_ on the stack. Of course if it is .int code then
it isn't a real return address but an address in the byte code that
the interpreter will use.
> The location of the name is defined by the file format, which is defined by the
> operating system. It has to be so Task Viewers can show what's running,
> including called programs.
What is in memory is entirely what the run-time wants it to be. For
example .int and .gnt aren't loaded as executables. The 'task' is the
run-time byte interpreter.
> Heap walkers and Task viewers follow the same concept, and are often
> integrated.
> The concept is walking up and down a tree structure.
What stack is a 'tree structure' ?
| |
| Robert Wagner 2004-06-13, 8:55 am |
| riplin@Azonic.co.nz (Richard) wrote:
>robert.deletethis@wagner.net (Robert Wagner) wrote
>What is in memory is entirely what the run-time wants it to be. For
>example .int and .gnt aren't loaded as executables. The 'task' is the
>run-time byte interpreter.
Micro Focus says those formats are retained only for backward compatibility.
They recommend OS standard formats: executable, .so and .dll.
>
>What stack is a 'tree structure' ?
The calling and called programs form a tree structure.
| |
| JerryMouse 2004-06-13, 8:55 am |
| LX-i wrote:
> JerryMouse wrote:
>
> Wow! In olden days, you used to be able to omit the closing quote?
> ;)
No, there's a continuation line. Remember those?
| |
| Paul Raulersonv 2004-06-13, 3:55 pm |
| Isn't this getting a little bit out of hand?
Some compilers use entry logic that stores the program name in the stack frame for
just this purpose.
On some platforms you can compile with debugging enabled, which will set STABS
information in the link-edited file, accomplishing the same thing
Most shops that really want to do this define standard entry-logic for their programs
which includes a step to store the program name in WS or some other well known space.
On the mainframe, you have ADATA records that can help you out.
-Paul
"Richard" <riplin@Azonic.co.nz> wrote in message news:217e491a.0406121410.5ac81559@posting.google.com...
> robert.deletethis@wagner.net (Robert Wagner) wrote
>
>
> The 'return address' need not be to the actual CALLing program. It
> may be to the run-time so that the run-time can decrement the 'active'
> counter or somesuch. The run-time does know which programs are
> active, which is why it can give an error when a re-entry is tried.
>
>
> I just looked as some object code. Yes the program name is there, so
> are a lot of other names, and in no particular order. This is also
> _not_ a general solution as you claimed and may be entirely specific
> to particualr compilers and environments, each one requiring a
> different solution.
>
>
> And the return address may be back to the run-time which is where the
> actual entry to the called program came from.
>
>
> You are now between the stack and the heap. They are
> different things you know.
>
> As I said there is still _nothing_ that make this a general solution.
>
>
>
> So, how did you know which one ran ? Obviously not from the
> Program-Id if they were all the same.
>
> How did the program get executed ? Something must have specified its
> name, presumably its file name. Surely you should have been able to
> find which one was run by looking at what CALLed it, or the job cards.
>
>
> That shows you have a complete lack of 'thinking ahead'. Either you
> should have changed all 15 or should have 'archived' the other 14 so
> they could be used.
>
>
>
> The 'common practice' and 'burdened by CMS' seem to be incompatible.
| |
| Richard 2004-06-13, 3:55 pm |
| robert.deletethis@wagner.net (Robert Wagner) wrote
>
> The calling and called programs form a tree structure.
No they don't, the structure of 'the stack' is 'a stack', like a stack
of plates it grows and shrinks along a single axis.
A 'tree structure', like an actual tree, has branches. A binary tree,
for example, has left and right pointers.
Sometimes I don't know whether you are just of whether you
are trolling.
| |
| Robert Wagner 2004-06-14, 3:55 am |
| riplin@Azonic.co.nz (Richard) wrote:
>Sometimes I don't know whether you are just of whether you
>are trolling.
I'm not trolling. You don't understand the points I try to make.
| |
| Joe Zitzelberger 2004-06-14, 3:55 pm |
| In article <40cbb7c3.101370979@news.optonline.net>,
robert.deletethis@wagner.net (Robert Wagner) wrote:
> riplin@Azonic.co.nz (Richard) wrote:
>
>
> The language requires this to work:
>
> Program A: call 'B' using BY REFERENCE a-1
> Program B: call 'C' using BY REFERENCE a-1, b-2
> Program C: display 'I have access to ' a-1 ' and ' b-2
>
> Operating systems protect memory at the Process level. Can you cite one that
> works at the called program level? I thought not.
MVS, OS/390, z/OS.
While it does not protect memory at the program level. It does limit
switches to supervisor state (e.g. free access to all system memory) at
the program level.
Thus, a process with its own protected memory can call an 'authorized'
program, which can then read any memory in the system regardless of
protection level or owner.
| |
| Robert Wagner 2004-06-14, 3:55 pm |
| Joe Zitzelberger <joe_zitzelberger@nospam.com> wrote:
>In article <40cbb7c3.101370979@news.optonline.net>,
> robert.deletethis@wagner.net (Robert Wagner) wrote:
>
such[color=darkred]
>
>MVS, OS/390, z/OS.
>
>While it does not protect memory at the program level. It does limit
>switches to supervisor state (e.g. free access to all system memory) at
>the program level.
Every operating system does that. The issue was limiting access within a
Process.
>Thus, a process with its own protected memory can call an 'authorized'
>program, which can then read any memory in the system regardless of
>protection level or owner.
Sounds like a hole in security. Another process might have cleartext of an
encrypted document.
| |
| Chuck Stevens 2004-06-14, 3:55 pm |
|
"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
news:40cb1626.59991723@news.optonline.net...
>
> The stack contains a return address. Using that, the program name can
usually be
> found near the beginning of its segment or in a public symbol table.
Define "usually". Definitely *not* the case for Unisys MCP systems; the
only place the name of the called program appears at execution time is in
the execution-time library template for external programs and not at all for
unambiguously nested ones (for which the name is resolved at compile time)!
> Let's try to stay in focus. We're interested in the RETURN address, not
the call
> address.
What does a PCW have to do with a name?
> Heap walkers are a very common diagnostic tool. I'm disappointed to read
you're
> unfamiliar with the concept.
I'm familiar enough with the concept; it escapes me why you feel walking a
heap (or a stack, for that matter) is universally applicable to standard
COBOL in all, or even most, implementations.
-Chuck Stevens
| |
| Chuck Stevens 2004-06-14, 3:55 pm |
| "Robert Wagner" <robert.deletethis@wagner.net> wrote in message
news:40cce67e.178881558@news.optonline.net...
> riplin@Azonic.co.nz (Richard) wrote:
>
>
> I'm not trolling. You don't understand the points I try to make.
The job of communicating to an audience lies to significant degree with the
person trying to make the points. That you are not succeeding with Richard
(or, for that matter, frequently with me) is not necessarily his, or my,
fault.
Often I do understand the points you make. You've indicated that a user
program can access its own stack at execution time, or alternatively that a
user-written program can access another program's stack. On machines where
the hardware design prohibits such access as a security measure, your
assertion is ... ummm ... unlikely.
-Chuck Stevens
| |
| Chuck Stevens 2004-06-14, 3:55 pm |
|
"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
news:40ca30db.1284627@news.optonline.net...
> Every called program has a way of returning to its caller.
That does not mean that mechanism is necessarily visible to the caller, the
called program, or to an outside process.
[color=darkred]
> But it can. It just cannot modify it back in the caller's memory.
True; that's precisely the point of the difference between BY CONTENT and BY
REFERENCE. A called program *can* step on the parameter in the caller's
memory if it's BY REFERENCE.
> I don't think this is a realistic concern. Programs generally don't
recklessly
> modify parameters.
It was a realistic enough problem in a Fortran environment I worked on back
in about 1970, in which the constant integer 1 was passed to a subroutine
that modified its value. And it was a realistic enough problem during the
development of the '85 standard to stimulate the framers of that standard
into adding "by content" to the parameter descriptions in CALL and "by
value" to the Procedure Division header. Programs may not generally
*recklessly* modify parameters, but it is not uncommon for them
*inadvertently* to do so!
> It is in nearly all environments. It need not be. Sure, dataname can
change, but
> 99.99 percent of the time it doesn't. INLINE code could (should) check
that it's
> the same and then call directly, with little more overhead than a static
link. I
> used to write enhancers that reached back and modified generated code to
do
> exactly that.
In our environment, if you use CALL <dataname> it is precisely because you
expect the contents of <dataname> to change from one execution to the next.
as[color=darkred]
concern[color=darkred]
>
> True but discordant with the culture of operating systems and other
languages.
I'm not sure what you're responding to here. I have been actively
supporting compilers for four dialects of ALGOL, two of Pascal, three of
COBOL, and miscellaneous other language compilers *and* their operating
environments for quite some time now, and I don't see the discordance you
assert.
> Micro Focus says:
>
> "If the program being called is not COBOL, the size of the additional data
item
> should not exceed the maximum size of the system area (typically the size
of a
> POINTER on the system); otherwise the system might become catastrophically
> corrupt."
Unlikely on our system because of memory protection hardware. A fatal
termination of the offending program would almost certainly result. Can be
done, but you have to go *way* out of your way (like, call an ALGOL
subprogram that changes the size of a data item) to do it, and the manual
already says it's the user's responsibility to ensure that parameter. The
standard already says that the parameter in a Procedure Division USING
phrase must be the same size *or smaller* than in the program that calls it
if the caller passes it by reference, so that means the called program can't
get outside the bounds of what it's passed. Wouldn't the same thing
reasonably apply when what's being called isn't in COBOL? Aren't the
consequences of violating the rules of the standard undefined? What's your
point?
> The idea of BY CONTENT and BY VALUE is based on paranoia and disrespect.
Its
> premise is that called programs may irrationally corrupt parameter values.
In
> the real world, that's not a realistic concern.
No, it is based on the premise of *safeguarding* parameter values. It is
not merely "irrational" corruption that it guards against, it is also
"inadvertent" corruption as well as "malevolent" corruption. A called
routine can protect itself and its data from a malevolent caller, and a
calling program can protect itself and its data from a
malevolently-substituted called routine. And, however silly you might find
the idea, it's been part of COBOL for nigh onto twenty years now, and it
ain't going anywhere soon!
> You're correct: they didn't have words nor stacks, but they did have a
pointer
> back to the caller.
Didn't say they didn't. What I did say was that it wasn't a *word*, nor did
it necessarily bear any relationship to any other hardware or software
structure in the system.
-Chuck Stevens
| |
| Chuck Stevens 2004-06-14, 3:55 pm |
|
"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
news:40cbb7c3.101370979@news.optonline.net...
> The language requires this to work:
>
> Program A: call 'B' using BY REFERENCE a-1
> Program B: call 'C' using BY REFERENCE a-1, b-2
> Program C: display 'I have access to ' a-1 ' and ' b-2
True enough. It also requires that if you change a-1 that change is visible
in Program A, and if you change b-2, that change is visible in Program B.
The language also requires that if Program A contains data items a-3 and
a-4, and Program B has data items b-3 and b-4, B cannot "see" a-1 or a-2
(unless, of course, they're declared global and B is nested in A), nor can C
see b-3 or b-4 (unless they're global and C is nested in B) or a3 or a-4
(unless they're global and C is nested within B which is nested within A).
Moreover, given
Program A: call 'B' using BY CONTENT a-1
Program B: call 'C' using BY CONTENT a-1, b-2
Program C: display 'I have access to ' a-1 ' and ' b-2 '
will execute, but any changes B or C make to a-1 or b-2 will *not* be
visible in their "owning" programs.
> Operating systems protect memory at the Process level. Can you cite one
that
> works at the called program level?
Depends on what you mean by "memory", "protect", and "process", to say
nothing of the blanket "operating systems". Protection of the "local"
memory of a called program is a function of the operating environment as it
relates to the characteristics of the *program*. It's not so much the
"operating system" as it is the "hardware" in our case, but the operating
system does participate. Parameters are protected, or not protected, as
specified by the authors of both the called and calling programs. If the
memory is shared between them (by reference in the calling and called
programs), then it's shared; if it's any other combination (by reference in
the calling program, by value in the called or vice versa, or by value in
both), the rules require that the formal and actual parameters be "treated
as if" they were separate memory areas.
In the case of Unisys MCP, it's the *compiler* that handles these
distinctions, not the operating system. So, yes, I can cite one that works
at the called program level rather than at the operating system level.
> I thought not.
I'm afraid you thought wrong.
-Chuck Stevens
| |
| Robert Wagner 2004-06-15, 3:55 am |
| "Chuck Stevens" <charles.stevens@unisys.com> wrote:
>"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
>news:40cb1626.59991723@news.optonline.net...
>
>usually be
>
>Define "usually". Definitely *not* the case for Unisys MCP systems; the
>only place the name of the called program appears at execution time is in
>the execution-time library template for external programs and not at all for
>unambiguously nested ones (for which the name is resolved at compile time)!
When a runtime error occurs and the program isn't handling it, doesn't Cobol
issue a message containing the program name and a description of the error?
Isn't there a debug compiler option, which preserves names?
>you're
>
>I'm familiar enough with the concept; it escapes me why you feel walking a
>heap (or a stack, for that matter) is universally applicable to standard
>COBOL in all, or even most, implementations.
Near the beginning of this thread, we discussed identifying programs in error
messages. I opined that the error reporting mechanism should walk back the stack
reporting the names of all programs leading to one of interest.
| |
| Robert Wagner 2004-06-15, 3:55 am |
| "Chuck Stevens" <charles.stevens@unisys.com> wrote:
>"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
>news:40ca30db.1284627@news.optonline.net...
>recklessly
>
>It was a realistic enough problem in a Fortran environment I worked on back
>in about 1970, in which the constant integer 1 was passed to a subroutine
>that modified its value. And it was a realistic enough problem during the
>development of the '85 standard to stimulate the framers of that standard
>into adding "by content" to the parameter descriptions in CALL and "by
>value" to the Procedure Division header. Programs may not generally
>*recklessly* modify parameters, but it is not uncommon for them
>*inadvertently* to do so!
In 40+ years Cobol programming, I've never used BY CONTENT (unless the called
program required it).
>change, but
>that it's
>link. I
>do
>
>In our environment, if you use CALL <dataname> it is precisely because you
>expect the contents of <dataname> to change from one execution to the next.
I dispute that. You use it because you want to force dynamic links and the
compiler doesn't provide a suitable option such as DYNAM, which makes all calls
dynamic.
In the Unix world, late binding is the default.
>languages.
>
>I'm not sure what you're responding to here. I have been actively
>supporting compilers for four dialects of ALGOL, two of Pascal, three of
>COBOL, and miscellaneous other language compilers *and* their operating
>environments for quite some time now, and I don't see the discordance you
>assert.
Other languages discourage or outright prohibit passing large structures on the
stack. That's the provenance of malloc (intra-process) or Shared Memory (across
processes). The caller is expected to allocate a chunk and pass a pointer to it.
| |
| Robert Wagner 2004-06-15, 3:55 am |
| "Chuck Stevens" <charles.stevens@unisys.com> wrote:
>Often I do understand the points you make. You've indicated that a user
>program can access its own stack at execution time, or alternatively that a
>user-written program can access another program's stack. On machines where
>the hardware design prohibits such access as a security measure, your
>assertion is ... ummm ... unlikely.
If a program couldn't access its own stack, it wouldn't be able to return from a
call.
If it couldn't access the caller's stack, this wouldn't work:
Program A: call 'B' using by content a1
Program B: display "A's stack is at " address of a1
| |
| Robert Wagner 2004-06-15, 3:55 am |
| "Chuck Stevens" <charles.stevens@unisys.com> wrote:
>
>"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
>news:40cbb7c3.101370979@news.optonline.net...
>that
>
>Depends on what you mean by "memory", "protect", and "process", to say
>nothing of the blanket "operating systems". Protection of the "local"
>memory of a called program is a function of the operating environment as it
>relates to the characteristics of the *program*. It's not so much the
>"operating system" as it is the "hardware" in our case, but the operating
>system does participate.
Every platform I've worked on also uses hardware. But the operating system tells
the hardware about zones of memory and ids of authorized users. Typically, the
zones are "segments" and the user is a "process id". Thus, every called program
has access to the memory of all other programs within the process .. as far as
the hardware is concerned.
Does Unisys MCP setup user ids smaller than a 'process'?
>Parameters are protected, or not protected, as
>specified by the authors of both the called and calling programs. If the
>memory is shared between them (by reference in the calling and called
>programs), then it's shared; if it's any other combination (by reference in
>the calling program, by value in the called or vice versa, or by value in
>both), the rules require that the formal and actual parameters be "treated
>as if" they were separate memory areas.
>
>In the case of Unisys MCP, it's the *compiler* that handles these
>distinctions, not the operating system. So, yes, I can cite one that works
>at the called program level rather than at the operating system level.
Would Unisys MCP or compiler stop this:
Program A:
01 bunch-of-pointers.
05 pointer-to-a4 pointer.
05 pointer-to-a5 pointer.
set pointer-to-a4 to address of a4
set pointer-to-a5 to address of a5
call 'B' using bunch-of-pointers
Program B:
linkage section.
01 bunch-of-pointers.
05 pointer-to-a4 pointer.
05 pointer-to-a5 pointer.
01 a4 pic x.
01 a5 pic x.
procedure division using bunch-of-pointers.
set address of a4 to pointer-to-a4
set address of a5 to pointer-to-a5
display 'I can see ' a4 ' and ' a5
| |
| Jim Morcombe 2004-06-15, 3:55 am |
| Obviously it depends on just what you want to do wit hthe Program Name and
why.
I use this type of thing to identify the actual program being run. But I am
not interested in just the name of the program, but the version as well.
The PROGRAM-ID doesn't give you the version so it is useless for my
purposes.
Instead, I define a Working Storage variable (with the inovative name of
PROG-NAME) and I use CVS commands to define the value. This means that when
some idiot copies the program and doesn't change "PROGRAM-ID", I still pick
up the real name of the program. It also gives me the version number as
well.
I would imagine that most systems have some kind of Source Code Control
System capable of doing this.
Jim Morcombe
Robert Wagner <robert.deletethis@wagner.net> wrote in message
news:40c800ce.497169106@news.optonline.net...
> riplin@Azonic.co.nz (Richard) wrote:
>
ps so[color=darkred]
> it
>
> No, he wants the name of the Main program, probably to print in a log file
or
> report header. The logic getting the name would best be in a called
program.
> Printing 'getmyname' on every report would not be informative.
>
> If programs are compiled to .gnt, the gnt _is_ a called program .. called
by
> cobrun, which would appear in column 8.
>
| |
| Richard 2004-06-15, 8:55 am |
| robert.deletethis@wagner.net (Robert Wagner) wrote
> In 40+ years Cobol programming, I've never used BY CONTENT (unless the called
> program required it).
How would a CALLed program specify that it _requires_ a parameter to
be passed BY CONTENT ?
>
> I dispute that. You use it because you want to force dynamic links and the
> compiler doesn't provide a suitable option such as DYNAM, which makes all
> calls dynamic.
Why do you assume that in his environment he does not have a way to
make calls using literals as being dynamic ? On some COBOL systems
_all_ CALLs are dynamic, even when using literals.
Disputing and contradicting people about environments you seem to know
little about may sometimes be the sign of trolling.
> In the Unix world, late binding is the default.
Which may be irrelevant to what any particualr COBOL system does. For
example using .int does not need to use what the 'Unix world' uses.
| |
| Chuck Stevens 2004-06-15, 3:55 pm |
|
"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
news:40ce1792.256994029@news.optonline.net...
> Every platform I've worked on also uses hardware. But the operating system
tells
> the hardware about zones of memory and ids of authorized users.
In the case of Unisys MCP, programs request memory during their initiation.
The descriptors pointing to that memory are contained within the program's
stack, and the only processes that can see those descriptors, or the memory
they point to, are the programs themselves and the MCP. Even the
descriptors are indirect, as they reference a MCP table that contain the
*actual* descriptors of the code segments. The only authorized user of a
space of memory is the process that created it, unless that process
explicitly provides a path to it (for example, as a parameter to a task or
library).
> Typically, the
> zones are "segments" and the user is a "process id". Thus, every called
program
> has access to the memory of all other programs within the process .. as
far as
> the hardware is concerned.
Nope. Not even close.
> Does Unisys MCP setup user ids smaller than a 'process'?
"User id's" arent germane to Unisys MCP memory management, as I see it. You
want memory? You build a descriptor template; first time you touch that
template, the MCP allocates the memory. The descriptor to that memory is in
*your* stack; nobody else but the MCP can see it, or the memory it
addresses, unless you pass them the descriptor. You go away? The MCP
deallocates the memory as part of the process of tearing the stack down.
> Would Unisys MCP or compiler stop this:
>
> Program A:
> 01 bunch-of-pointers.
> 05 pointer-to-a4 pointer.
> ...
Umm... Yeah, sure would, at "pointer-to-A4 pointer". I think you're
laboring under at least one mistaken assumption here.
The Unisys MCP environment currently supports two dialects of COBOL:
COBOL74, which follows ANSI X3.23-1974, and COBOL85, which follows ANSI
X3.23-1985 plus the two amendments.
USAGE POINTER was introduced in ISO/IEC 1989:2002 and is an *extension* to
any implementation of COBOL that conforms to any *prior* standard.
Thus, Unisys MCP software does not recognize the above code as meaningful
simply because USAGE POINTER isn't in either ANSI X3.23-1974 or ANSI
X3.23-1985, nor is it implemented as a Unisys extension to either of those
standards in either of the Unisys MCP COBOL compilers.
Unisys might consider adding USAGE POINTER to the list of 2002-standard
features for consideration for inclusion in our ANSI-85 compiler, but before
we could do so we would need at least one Unisys MCP user to let it be known
to us that they found it a desirable enhancement, and we have not as yet
been notified of such a request. The enhancements that people have actually
asked for have to take precedence (for example, INITIALIZE WITH FILLER has
been requested as a means of improving performance of INITIALIZE).
The current memory management scheme, and the security it affords our users,
is a well-liked feature of the Unisys MCP environment that our users have
liked since our introduction of it in the Burroughs B5000 and through its
refinement over a number of generations of hardware design. It is not clear
to us that providing a mechanism whereby users could pretty much arbitrarily
get to any memory of any component of a run unit without the most local
"owner" of that memory having any say in the matter would represent an
improvement in either security or functionality to our existing customers.
-Chuck Stevens
| |
| Chuck Stevens 2004-06-15, 3:55 pm |
| "Robert Wagner" <robert.deletethis@wagner.net> wrote in message
news:40ce1f14.258916099@news.optonline.net...
> If a program couldn't access its own stack, it wouldn't be able to return
from a
> call.
Silly me. I was under the impression that the EXIT (or RETN) hardware
operators, with a RCW on the stack placed there by the caller and invisible
to the called routine, handled that. Must've been wrong all these years.
> If it couldn't access the caller's stack, this wouldn't work:
>
> Program A: call 'B' using by content a1
> Program B: display "A's stack is at " address of a1
Could you point out to me once again where "address of" appears in ANSI
X3.23-1985 (or, for that matter ANSI X3.23-1974)?
-Chuck Stevens
| |
| Chuck Stevens 2004-06-15, 3:55 pm |
|
"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
news:40ce2169.259513248@news.optonline.net...
> When a runtime error occurs and the program isn't handling it, doesn't
Cobol
> issue a message containing the program name and a description of the
error?
The outermost object code file name is reflected in the basic error message.
The stack history is reflected by sequence number in the log; the program
dump provides more details for separately-compiled programs.
> Isn't there a debug compiler option, which preserves names?
What's to preserve?
> Near the beginning of this thread, we discussed identifying programs in
error
> messages. I opined that the error reporting mechanism should walk back the
stack
> reporting the names of all programs leading to one of interest.
No, perhaps *you* discussed identifying programs in error messages; I don't
recall having participated in that part of the discussion.
In our case, because the fundamental architecture of the system is
stack-based to begin with, identifying the history from the point of failure
all the way through all the nested calls is handled. Names are available
for separately-compiled programs, but COBOL programs in the Unisys MCP
environment typically have unique sequence numbers for each source line, a
nested program forms part of a compilation unit, and the sequence numbers
(together, sometimes, with the code address in the RCW) provides enough
information for the user to figure out the calling sequence that led to the
failure. The program-id of a nested program may show up, but that's not
what people used to working with Unisys MCP COBOL85 use as a primary
debugging tool.
-Chuck Stevens
| |
| Chuck Stevens 2004-06-15, 3:55 pm |
|
"Jim Morcombe" <jim@byronics.com.au> wrote in message
news:caltrm$ft9$1@yeppa.connect.com.au...
> The PROGRAM-ID doesn't give you the version so it is useless for my
> purposes.
>
> Instead, I define a Working Storage variable (with the inovative name of
> PROG-NAME) and I use CVS commands to define the value. This means that
when
> some idiot copies the program and doesn't change "PROGRAM-ID", I still
pick
> up the real name of the program. It also gives me the version number as
> well.
Note that the Intrinsic Function amendment (ANSI X3.23a-1989) included
WHEN-COMPILED alongside CURRENT-DATE, both of which provide their respective
information in the same format. This doesn't speak to a source-code
version number as such, but this function should help provide *some* sort of
unique identification for the compiled object code.
-Chuck Stevens
| |
| Richard 2004-06-15, 3:55 pm |
| robert.deletethis@wagner.net (Robert Wagner) wrote
> Would Unisys MCP or compiler stop this:
> [...]
> set pointer-to-a4 to address of a4
> set pointer-to-a5 to address of a5
> call 'B' using bunch-of-pointers
> [...]
> display 'I can see ' a4 ' and ' a5
You seem to assume that just because you can see some parts of the
memory of the calling program as passed by parameters in a stack frame
that therefore you would be able to access every other part of that
program.
In some cases the Working-Storage of a program is not all one
contiguous segement. The compiler cannot split 01 levels or 77 levels
(actually it could as long as the result was logically identical), but
there is no reason to assume that any or all 01s or 77s are in the
same segment or have an address that is determinable from the address
of another, or from a code address such as the return in the stack.
In fact you may not even be able to determine the address of the stack
frame of the calling program, there is no guarantee that the run-time
has not created a new stack to pass parameters and return address to
the program while keeping the caller's stack private.
| |
| Chuck Stevens 2004-06-15, 3:55 pm |
|
"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
news:40ce3a88.265945256@news.optonline.net...
> In 40+ years Cobol programming, I've never used BY CONTENT (unless the
called
> program required it).
Using standard COBOL you couldn't do so until the introduction of the syntax
in the '85 standard, less than twenty years ago. I never used Function
CURRENT-DATE in COBOL68, either, but I'm not sure that says anything about
whether anyone might find it useful or efficacious!
Certainly I've used the equivalents in ALGOL and Pascal many a time, and the
absence of CONTENT / VALUE from ANSI X3.23-1974 was a restriction that
"bilingual" (ALGOL/COBOL) programmers found decidedly limiting.
you[color=darkred]
next.
[color=darkred]
> I dispute that. You use it because you want to force dynamic links and the
> compiler doesn't provide a suitable option such as DYNAM, which makes all
calls
> dynamic.
If I understand your definition of "dynamic links", under the Unisys MCP
implementation of COBOL IPC to separately-compiled programs, *all* such
CALLs *are* dynamic. Some implementations resolve such things using a
"linkage editor", as I understand it; the Unisys MCP analog to this is a
product called "BINDER". For standard COBOL programs, the compilers produce
*executable code*, directly, period. There is no "post-compilation" step
other than execution in such a case; BINDER is not involved in ANSI IPC
calls. At all. Ever.
I would guess that *both* CALL <literal> *and* CALL <dataname> generate
"dynamic calls" in this environment by your definition. While it's true
that the first such CALL is more costly than a call to, say, a
separately-compiled procedure (which requires non-standard syntax and a
post-compilation step), once the MCP has initiated the called program and
established the linkage, the performance is essentially the same, because
the object code's essentially the same.
What's different about CALL <literal> and CALL <dataname>? In CALL
<literal> the library template is constructed at compilation time. In CALL
<dataname> the library template must be constructed as part of the object
code associated with the CALL itself, and destroyed immediately upon return
from the procedure. That means an InitialPBIT for the library template on
each CALL and a BLOCKEXIT call to the MCP on each return. That's expensive.
On Unisys MCP systems, if you want to be able to call a separately-compiled
procedure that has somehow been incorporated into your COBOL object program,
you don't do it using ANSI IPC calls, you do it through Unisys extensions
associated with calling procedures that have been incorporated using BINDER.
This syntax is somewhat similar to the IPC syntax, but not identical. That
appears to me to be the sense of what I think you'd refer to as a "static
link" -- a link established after compilation but before execution. You can
do it on our system, but it's not part of the ANSI IPC implementation.
> In the Unix world, late binding is the default.
In the Unisys MCP world as it relates to ANSI IPC to separately-compiled
programs, binding occurs on first CALL, period. There is no "early" or
"late" in the ANSI IPC context, there is only the linkage established by the
MCP at execution time. If you want "early" binding, then don't use ANSI IPC
syntax, use declaratives with USE EXTERNAL, bind the procedure in, and use
CALL <section-name>.
> Other languages discourage or outright prohibit passing large structures
on the
> stack. That's the provenance of malloc (intra-process) or Shared Memory
(across
> processes). The caller is expected to allocate a chunk and pass a pointer
to it.
What other languages -- from ALTAC to C# -- do or did and how and why they
did it is not necessarily germane to the design and history of, or
requirements for, COBOL. Pascal allows all sorts of stuff that neither
Fortran66 nor RPG allow, and prohibits stuff that even COBOL(68) thought was
the bee's knees. What's your point?
If your expectation is that all implementations "allocate a chunk and pass a
pointer to it", all I can say is the advice some wise friends gave me: "an
expectation is a premeditated resentment". The code generated for the call
may be expected *by you* to look the way you want it to and to make the data
available to the called routine in a particular fashion, but that's your
expectation, to which you are welcome, and that expectation does not
necessarily have anything to do with general reality.
Even if the implementor does decide to pass some sort of description of the
data, rather than the data itself, to the called program, there's no
guarantee that that description would bear any relationship or similarity to
what might pass for a "USAGE POINTER" data item in that implementor's
implementation (real, planned, or hypothetical) of ISO/IEC 1989:2002 COBOL,
or anything else, for that matter.
The decision as to what the code to pass a parameter BY CONTENT actually
*does* is up to the implementor; the standard offers guidelines as to what
the *overall effect* of that code should be.
-Chuck Stevens
| |
| Chuck Stevens 2004-06-15, 8:55 pm |
|
"Richard" <riplin@Azonic.co.nz> wrote in message
news:217e491a.0406151101.527e4e03@posting.google.com...
> You seem to assume that just because you can see some parts of the
> memory of the calling program as passed by parameters in a stack frame
> that therefore you would be able to access every other part of that
> program.
That is certainly not the case in Unisys MCP COBOLs.
> In some cases the Working-Storage of a program is not all one
> contiguous segement. The compiler cannot split 01 levels or 77 levels
> (actually it could as long as the result was logically identical), but
> there is no reason to assume that any or all 01s or 77s are in the
> same segment or have an address that is determinable from the address
> of another, or from a code address such as the return in the stack.
Most definitely.
In Unisys MCP COBOL74, *each* 01-level item and *each* 77-level item has a
separate structure in memory, each allocated when it is first "touched" by
the program. And although COBOL74 doesn't split 01-level items into
separate blocks of memory, COBOL(68) allowed the user to do so. In COBOL74
there is no possibility of accessing beyond the bounds of an 01-level item;
the *hardware* prohibits it, whether the access is as a source or a
destination.
In Unisys MCP COBOL85, to cut down on the stack cell requirements, data is
"pooled", so it is at least theoretically possible to get outside one's
"own" 01-level item within a program; otherwise, those "pools" are again
local to the program. I can also demonstrate that 01-level items used as
parameters are allocated their own locations, whether passed by value or by
reference, so the same rule applies as is true for COBOL74: just because
you can get to an 01-level record (for access or for update) from the called
program does not mean you can get to the one declared before or after it, or
any other record not passed as a parameter, in the calling program. The
COBOL compiler *and* the hardware conspire to prevent such access from
anyone but the MCP.
-Chuck Stevens
| |
| Robert Wagner 2004-06-17, 3:55 am |
| "Chuck Stevens" <charles.stevens@unisys.com> wrote:
>
>"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
>news:40ce1792.256994029@news.optonline.net...
>
>tells
>
>In the case of Unisys MCP, programs request memory during their initiation.
>The descriptors pointing to that memory are contained within the program's
>stack, and the only processes that can see those descriptors, or the memory
>they point to, are the programs themselves and the MCP. Even the
>descriptors are indirect, as they reference a MCP table that contain the
>*actual* descriptors of the code segments. The only authorized user of a
>space of memory is the process that created it, unless that process
>explicitly provides a path to it (for example, as a parameter to a task or
>library).
>
>program
>far as
>
>Nope. Not even close.
I'll take that as a yes. You said the hardware permits a called program to
access its parent's memory. How it gets the address was not in the question.
>
>"User id's" arent germane to Unisys MCP memory management, as I see it. You
>want memory? You build a descriptor template; first time you touch that
>template, the MCP allocates the memory. The descriptor to that memory is in
>*your* stack; nobody else but the MCP can see it, or the memory it
>addresses, unless you pass them the descriptor. You go away? The MCP
>deallocates the memory as part of the process of tearing the stack down.
All operating systems offer a way to dynamically allocate memory, but MCP's way
sounds OOish.
>
>Umm... Yeah, sure would, at "pointer-to-A4 pointer". I think you're
>laboring under at least one mistaken assumption here.
>
>The Unisys MCP environment currently supports two dialects of COBOL:
>COBOL74, which follows ANSI X3.23-1974, and COBOL85, which follows ANSI
>X3.23-1985 plus the two amendments.
>
>USAGE POINTER was introduced in ISO/IEC 1989:2002 and is an *extension* to
>any implementation of COBOL that conforms to any *prior* standard.
>
>Thus, Unisys MCP software does not recognize the above code as meaningful
>simply because USAGE POINTER isn't in either ANSI X3.23-1974 or ANSI
>X3.23-1985, nor is it implemented as a Unisys extension to either of those
>standards in either of the Unisys MCP COBOL compilers.
So MCP doesn't prevent access, they compiler does by 'hiding' the address.
>Unisys might consider adding USAGE POINTER to the list of 2002-standard
>features for consideration for inclusion in our ANSI-85 compiler, but before
>we could do so we would need at least one Unisys MCP user to let it be known
>to us that they found it a desirable enhancement, and we have not as yet
>been notified of such a request. The enhancements that people have actually
>asked for have to take precedence (for example, INITIALIZE WITH FILLER has
>been requested as a means of improving performance of INITIALIZE).
I wasn't aware the 2002-standard was a Chinese menu .. nor a popular opinion
poll. I thought it was all or nothing.
>The current memory management scheme, and the security it affords our users,
>is a well-liked feature of the Unisys MCP environment that our users have
>liked since our introduction of it in the Burroughs B5000 and through its
>refinement over a number of generations of hardware design. It is not clear
>to us that providing a mechanism whereby users could pretty much arbitrarily
>get to any memory of any component of a run unit without the most local
>"owner" of that memory having any say in the matter would represent an
>improvement in either security or functionality to our existing customers.
I concur that it wouldn't be an improvement for general applications programs,
but contend it would be for systems software charged with diagnosing a failure.
| |
| Robert Wagner 2004-06-17, 3:55 am |
| riplin@Azonic.co.nz (Richard) wrote:
>robert.deletethis@wagner.net (Robert Wagner) wrote
>
>
>You seem to assume that just because you can see some parts of the
>memory of the calling program as passed by parameters in a stack frame
>that therefore you would be able to access every other part of that
>program.
That was the question -- whether the hardware prevents access.
>In some cases the Working-Storage of a program is not all one
>contiguous segement. The compiler cannot split 01 levels or 77 levels
>(actually it could as long as the result was logically identical), but
>there is no reason to assume that any or all 01s or 77s are in the
>same segment or have an address that is determinable from the address
>of another, or from a code address such as the return in the stack.
>
>In fact you may not even be able to determine the address of the stack
>frame of the calling program, there is no guarantee that the run-time
>has not created a new stack to pass parameters and return address to
>the program while keeping the caller's stack private.
So protection is afforded by 'information hiding' rather than being
hardware-based.
A widely accepted tenet of computer security is that 'information hiding' and
'secret algorithms' are inadequate and doomed to ultimate failure. The most
robust security systems, such as DES, make their algorithms public.
| |
| Robert Wagner 2004-06-17, 3:55 am |
| "Chuck Stevens" <charles.stevens@unisys.com> wrote:
>"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
>news:40ce3a88.265945256@news.optonline.net...
>
>called
>
>Certainly I've used the equivalents in ALGOL and Pascal many a time, and the
>absence of CONTENT / VALUE from ANSI X3.23-1974 was a restriction that
>"bilingual" (ALGOL/COBOL) programmers found decidedly limiting.
You offered nothing supporting or explaining WHY this was a "restriction".
>you
>next.
>
>calls
>
>If I understand your definition of "dynamic links", under the Unisys MCP
>implementation of COBOL IPC to separately-compiled programs, *all* such
>CALLs *are* dynamic. Some implementations resolve such things using a
>"linkage editor", as I understand it; the Unisys MCP analog to this is a
>product called "BINDER". For standard COBOL programs, the compilers produce
>*executable code*, directly, period. There is no "post-compilation" step
>other than execution in such a case; BINDER is not involved in ANSI IPC
>calls. At all. Ever.
The Unix analog is 'ld', which is both the static 'linker' and dynamic 'binder'.
In normal default use, all binding is dynamic. Called programs are compiled to
.so, which are dynamically bound.
>I would guess that *both* CALL <literal> *and* CALL <dataname> generate
>"dynamic calls" in this environment by your definition. While it's true
>that the first such CALL is more costly than a call to, say, a
>separately-compiled procedure (which requires non-standard syntax and a
>post-compilation step), once the MCP has initiated the called program and
>established the linkage, the performance is essentially the same, because
>the object code's essentially the same.
Unix works the same way.
>What's different about CALL <literal> and CALL <dataname>? In CALL
><literal> the library template is constructed at compilation time. In CALL
><dataname> the library template must be constructed as part of the object
>code associated with the CALL itself, and destroyed immediately upon return
>from the procedure. That means an InitialPBIT for the library template on
>each CALL and a BLOCKEXIT call to the MCP on each return. That's expensive.
If the systems software was smart, it would cache the previous CALL <dataname>.
If dataname is the same on the next CALL, as it is 99% of the time, the call
would be faster than the first.
>On Unisys MCP systems, if you want to be able to call a separately-compiled
>procedure that has somehow been incorporated into your COBOL object program,
>you don't do it using ANSI IPC calls, you do it through Unisys extensions
>associated with calling procedures that have been incorporated using BINDER.
>This syntax is somewhat similar to the IPC syntax, but not identical. That
>appears to me to be the sense of what I think you'd refer to as a "static
>link" -- a link established after compilation but before execution. You can
>do it on our system, but it's not part of the ANSI IPC implementation.
I can't tell from your response whether ANSI IPC favors dynamic or static links.
I would guess dynamic because that's favored by Unix, NT and most other modern
operating systems.
>
>In the Unisys MCP world as it relates to ANSI IPC to separately-compiled
>programs, binding occurs on first CALL, period. There is no "early" or
>"late" in the ANSI IPC context, there is only the linkage established by the
>MCP at execution time. If you want "early" binding, then don't use ANSI IPC
>syntax, use declaratives with USE EXTERNAL, bind the procedure in, and use
>CALL <section-name>.
Ok, ANSI IPC and MCP are both late binding, despite your protestations.
>on the
>(across
>to it.
>
>What other languages -- from ALTAC to C# -- do or did and how and why they
>did it is not necessarily germane to the design and history of, or
>requirements for, COBOL. Pascal allows all sorts of stuff that neither
>Fortran66 nor RPG allow, and prohibits stuff that even COBOL(68) thought was
>the bee's knees. What's your point?
My point was modern operating systems, not obsolete languages.
>If your expectation is that all implementations "allocate a chunk and pass a
>pointer to it", all I can say is the advice some wise friends gave me: "an
>expectation is a premeditated resentment". The code generated for the call
>may be expected *by you* to look the way you want it to and to make the data
>available to the called routine in a particular fashion, but that's your
>expectation, to which you are welcome, and that expectation does not
>necessarily have anything to do with general reality.
Too obtruse to reply.
| |
| Robert Wagner 2004-06-17, 3:55 am |
| "Chuck Stevens" <charles.stevens@unisys.com> wrote:
>"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
>news:40ce1f14.258916099@news.optonline.net...
>
>from a
>
>Silly me. I was under the impression that the EXIT (or RETN) hardware
>operators, with a RCW on the stack placed there by the caller and invisible
>to the called routine, handled that. Must've been wrong all these years.
Silly me. I thought the hardware afforded protection independent of language.
Now you claim the language's 'hiding' features make the stack invisible to
'application code'.
Obviously, we'll have to deny application programmers access to languages that
generate an EXIT or RETN, especially assembly language. That would be easy on
Unisys because there is no assembly language.
Tying programmers' hands is even worse security than 'information hiding'.
>
>Could you point out to me once again where "address of" appears in ANSI
>X3.23-1985 (or, for that matter ANSI X3.23-1974)?
It doesn't, but it appears in IBM, Micro Focus, Fujitsu and others. In other
words, 98+% of available Cobol compilers.
| |
| Robert Wagner 2004-06-17, 3:55 am |
| "Chuck Stevens" <charles.stevens@unisys.com> wrote:
>
>"Robert Wagner" <robert.deletethis@wagner.net> wrote in message
>news:40ce2169.259513248@news.optonline.net...
>
>error
>stack
>
>No, perhaps *you* discussed identifying programs in error messages; I don't
>recall having participated in that part of the discussion.
The original poster recently confirmed that my guess was correct, he wanted to
identify the offending program in an error message.
>In our case, because the fundamental architecture of the system is
>stack-based to begin with, identifying the history from the point of failure
>all the way through all the nested calls is handled. Names are available
>for separately-compiled programs, but COBOL programs in the Unisys MCP
>environment typically have unique sequence numbers for each source line, a
>nested program forms part of a compilation unit, and the sequence numbers
>(together, sometimes, with the code address in the RCW) provides enough
>information for the user to figure out the calling sequence that led to the
>failure. The program-id of a nested program may show up, but that's not
>what people used to working with Unisys MCP COBOL85 use as a primary
>debugging tool.
Clear as mud. Just tell me the name of the failed program and line number on
which it failed. Given that, I can figure out why it failed. Do I ask too much?
| |
| Richard 2004-06-17, 3:55 am |
| robert.deletethis@wagner.net (Robert Wagner) wrote
> The original poster recently confirmed that my guess was correct, he wanted to
> identify the offending program in an error message.
Your memory is selective or, possibly, failing:
RP >> >That is not going to show the name of any CALLed programs,
which is
RP >> >probably the point of the request.
RW >> No, he wants the name of the Main program,
If you are not trolling, then your messages are becoming increasingly
indistinguishable from that.
| |
| docdwarf@panix.com 2004-06-17, 8:55 am |
| In article <40d0bf9d.22939564@news.optonline.net>,
Robert Wagner <robert.deletethis@wagner.net> wrote:
>"Chuck Stevens" <charles.stevens@unisys.com> wrote:
>
[snip]
[color=darkred]
>
>I'll take that as a yes.
Mr Wagner, at times you've mentioned how some folks have... difficulties
when discussing things with you. T | | |