Two minor errors below:
"addressed by register 13 (aka save area aka dynamic save area aka
dynamic save area)"
should read
"addressed by register 13 (aka save area aka dynamic save area aka
dynamic STORAGE area)"
And I forgot to mention:
CEECSA is always address by reg 12, while inside a LE module.
So you get:
reg 12 + 500 = address of the WSA
take this address
add @(Static) from the compiler or prelinker listing
= address of your static section (which should be in some register ...)
add offset of the desired variable
now you have the address
Kind regards
Bernd
Am 10.05.2017 um 21:25 schrieb Bernd Oppolzer:
I guess that this is the same case as finding C and PL/1 static
variables
when the C and PL/1 procedures or functions are compiled using the RENT
compiler switch.
Because:
a) auto variables are always part of the "stack" which is addressed by
register 13
(aka save area aka dynamic save area aka dynamic save area)
b) in the NORENT case the STATIC variables are part of the STATIC CSECT,
which is located inside the load module ... this is, what classical
COBOL did,
and which is still present in C and PL/1 in the NORENT case ... NORENT is
recommended by IBM for PL/1, today :-)
So, let's go:
the static variables in the RENT case are part of the WSA. To locate
them in
the dump (SYSUDUMP, CEEDUMP, ...), you have several choices:
a) when you are inside the function where the variable is defined,
CEECSA+500 (X'1F4) should point to the WSA, so you have the base
address of the WSA. From the prelinker listing, you can see where the
static section of your particular function starts (Q(@STATIC)), add
this to the
base address, and then add the offset of the variable from the
compiler listing ..
voila the address of the variable
b) to speed up the addressing of the variables at run time, a certain
register
is loaded just after the function prologue with the value CEECSA+500 +
Q(@STATIC).
Look for this register (may be R4, R5, R6, R7, ...). Then add the
offset of the
variable to that register.
Sorry, no easier way. In prior releases, the base register of the
static area
always was register 3 (in PL/1).
The compiler builders could make the jobs of dump readers easier, if they
want, but they normally don't have dump readers in mind.
I'm trying to do it differently with my Stanford Pascal compiler:
http://bernd-oppolzer.de/job9.htm
HTH,
have a nice day
Bernd
Am 10.05.2017 um 21:02 schrieb Peter Hunkeler:
Reposting under a different subject, since the topic has changed
That's actually a trickier question than you might imagine!
I imagine it is! In my current job, I'm getting involved when
standard application debugging techniques don't help anymore. I
usually work with IPCS, so SYSMDUMPs and SVCDUMPs. We moved to Cobol
V5.2 earlier this year, but I still need to find the content of Cobol
variables in those dumps. The changes to how Working Storage is
implemented, and the fact that this is mostly undocumented, makes it
difficult. This is the real reason I'm trying to understand all this.
Your comments are most welcome!
There are a number of cases: the case where your module consists of
COBOL, PL/I and assembler only and all other cases. All other cases
include cases where the COBOL run time support is implemented in a
language other than the above. These cases include OO COBOL, XML
support and a few others.
In the second case (not pure COBOL), the C_WSA is loaded in
exactly the same way as it is for a C program. Basically, first the
program is loaded and then the C run time gets control. It
determines that you want to start new instance of this program
(C_WSA is only used for RENT.) So it calls CEEPPOS which is the
actual routine that gets a WSA and initializes it.
This all happens before main is run. (Or, in the case of C++, before
any file scope statics are constructed.)
Yes, this is well understood.
In the first case, your program starts and the COBOL bootstrap
routine gets control. That routine is called at the start of every
PROGRAM. In most cases, it checks a few things and returns. But
for the first program in the run unit, it does some work including
ensuring that LE is up. Part of that work is getting storage for
the WSA.
All of this happens before the first user statement in the PROCEDURE
DIVISION is executed.
So, no matter how the C_WSA is loaded (by and LE routine or by the
COBOL run time) it is present before the first user written
statement in the program is executed.
Yes, again well understood.
Which means that unless you're getting some sort of a trap during
the COBOL start up, you should always see the C_WSA somewhere in
your storage.
Yep, somewhere. But somewhere is not specific enough if you need
to find the value of a variable at the time of the dump.
By the way, WORKING STORAGE is another area of complexity. In the
case of NOWSOPT (the default for V5) W-S items are directly in the
C_WSA. In the case of WSOPT (V6) W-S is separately allocated and
the WSA contains a pointer to that allocation. (Again, this is all
done before the first user statement is executed.)
I really which there was a document describing all the
variants in detail and how to find variables in a dump in each case.
Lack of that document, I'm trying to find out step by step.
You would seem to be able to be of great help for me on this quest.
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN