Re: FACT was Re: COBOL and C
One processor; 8 virtual processors. Six microsecond memory cycle. That may not sound like much, but it was respectable for a 1960 midrange computer; better than a 7070, not as good as a 7090 FACT had language support for dealing with hierarchical record structures; to bad that never made it into COBOL.. -- Shmuel (Seymour J.) Metz http://mason.gmu.edu/~smetz3 From: IBM Mainframe Discussion List [IBM-MAIN@LISTSERV.UA.EDU] on behalf of Clark Morris [cfmt...@uniserve.com] Sent: Thursday, June 25, 2020 4:48 PM To: IBM-MAIN@LISTSERV.UA.EDU Subject: FACT was Re: COBOL and C [Default] On 27 Apr 2020 04:13:21 -0700, in bit.listserv.ibm-main sme...@gmu.edu (Seymour J Metz) wrote: >> And CPL before that (born in 1963). Yes, COBOL has roots in FLOW-MATIC >(mostly, with a light dusting of COM-TRAN), > >"FACT is fiction"? (Honeywell) The first full-time job I had coming out of school in 1961 was Equitable Life Assurance Society where they were installing a Honeywell 800 and planning to use FACT. The 800 had 8 processors and set of registers, 48 bit words and both decimal and binary arithmetic. A FACT program would use 3 of those sets as I recall. and was segmented at the paragraph level. It had a number of advanced features, some of which I would like in today's COBOL. Unfortunately it probably required a machine that had 10 times the memory and fast disk drives instead of one that was basically a tape drive machine (think rolling in code from tape repeatedly. My Netbook would be far better suited to it than the H800 as would a 4341. I downloaded a copy of the FACT manual before making this post to refresh my memory. Clark Morris > >Did the CODASYL SRC committee get anything from 9PAC? JOVIAL? -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
FACT was Re: COBOL and C
[Default] On 27 Apr 2020 04:13:21 -0700, in bit.listserv.ibm-main sme...@gmu.edu (Seymour J Metz) wrote: >> And CPL before that (born in 1963). Yes, COBOL has roots in FLOW-MATIC >(mostly, with a light dusting of COM-TRAN), > >"FACT is fiction"? (Honeywell) The first full-time job I had coming out of school in 1961 was Equitable Life Assurance Society where they were installing a Honeywell 800 and planning to use FACT. The 800 had 8 processors and set of registers, 48 bit words and both decimal and binary arithmetic. A FACT program would use 3 of those sets as I recall. and was segmented at the paragraph level. It had a number of advanced features, some of which I would like in today's COBOL. Unfortunately it probably required a machine that had 10 times the memory and fast disk drives instead of one that was basically a tape drive machine (think rolling in code from tape repeatedly. My Netbook would be far better suited to it than the H800 as would a 4341. I downloaded a copy of the FACT manual before making this post to refresh my memory. Clark Morris > >Did the CODASYL SRC committee get anything from 9PAC? JOVIAL? -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: COBOL and C
> And CPL before that (born in 1963). Yes, COBOL has roots in FLOW-MATIC (mostly, with a light dusting of COM-TRAN), "FACT is fiction"? (Honeywell) Did the CODASYL SRC committee get anything from 9PAC? JOVIAL? -- Shmuel (Seymour J.) Metz http://mason.gmu.edu/~smetz3 From: IBM Mainframe Discussion List [IBM-MAIN@LISTSERV.UA.EDU] on behalf of Timothy Sipples [sipp...@sg.ibm.com] Sent: Monday, April 27, 2020 4:00 AM To: IBM-MAIN@LISTSERV.UA.EDU Subject: Re: COBOL and C Charles Mills wrote: >Funny, isn’t it? >COBOL (née 1959) is 61 years old. It’s a very old language. >C (née 1972) is 48 years old. It’s a modern language. These dates aren't actually comparable. In 1959 the Short Range Committee first met -- on May 28 and 29, 1959, at the Pentagon -- and did a lot of work over the next few months. However, the COBOL specifications weren't formally approved until January 8, 1960 (with GPO printing thereafter). There was never any "COBOL 59." The first COBOL was "COBOL 60." And it wasn't until August 17, 1960, that the first COBOL program ran (on a RCA 501).(*) In other words, 1959 is the "some people got together and came up with an idea for a new programming language" date, analogous to celebrating your birthday on the date when your parents first met. For sure the first C program ran at least as early as 1972, probably in 1971, and perhaps even earlier. Version 2 Unix was released on June 12, 1972, and included a C compiler. Or, in other words, 1972 is when the first C compiler shipped outside Bell Labs. That's quite a different historical event, not directly comparable to committee meetings. Then there are the complexities associated with the fact that C comes after B, and there was a B programming language -- and BCPL before that. And CPL before that (born in 1963). Yes, COBOL has roots in FLOW-MATIC (mostly, with a light dusting of COM-TRAN), but...it's complicated. And surely we shouldn't be hanging our hat on somebody deciding in circa 1971 to advance to the next letter of the alphabet in what others might have called "B '72"? Anyway, if somebody wants to claim that a time difference is meaningful, isn't it important at least to get the birth dates right? (*) And the compilers remained practically unusable for a couple years thereafter. - - - - - - - - - - Timothy Sipples I.T. Architect Executive Digital Asset & Other Industry Solutions IBM Z & LinuxONE - - - - - - - - - - E-Mail: sipp...@sg.ibm.com -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: COBOL and C
Charles Mills wrote: >Funny, isn’t it? >COBOL (née 1959) is 61 years old. It’s a very old language. >C (née 1972) is 48 years old. It’s a modern language. These dates aren't actually comparable. In 1959 the Short Range Committee first met -- on May 28 and 29, 1959, at the Pentagon -- and did a lot of work over the next few months. However, the COBOL specifications weren't formally approved until January 8, 1960 (with GPO printing thereafter). There was never any "COBOL 59." The first COBOL was "COBOL 60." And it wasn't until August 17, 1960, that the first COBOL program ran (on a RCA 501).(*) In other words, 1959 is the "some people got together and came up with an idea for a new programming language" date, analogous to celebrating your birthday on the date when your parents first met. For sure the first C program ran at least as early as 1972, probably in 1971, and perhaps even earlier. Version 2 Unix was released on June 12, 1972, and included a C compiler. Or, in other words, 1972 is when the first C compiler shipped outside Bell Labs. That's quite a different historical event, not directly comparable to committee meetings. Then there are the complexities associated with the fact that C comes after B, and there was a B programming language -- and BCPL before that. And CPL before that (born in 1963). Yes, COBOL has roots in FLOW-MATIC (mostly, with a light dusting of COM-TRAN), but...it's complicated. And surely we shouldn't be hanging our hat on somebody deciding in circa 1971 to advance to the next letter of the alphabet in what others might have called "B '72"? Anyway, if somebody wants to claim that a time difference is meaningful, isn't it important at least to get the birth dates right? (*) And the compilers remained practically unusable for a couple years thereafter. - - - - - - - - - - Timothy Sipples I.T. Architect Executive Digital Asset & Other Industry Solutions IBM Z & LinuxONE - - - - - - - - - - E-Mail: sipp...@sg.ibm.com -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
AW: Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
>> Interesting. A reference to _gtca() also in LE Vendor Interfaces. Hints here >> and there in the C/C++ docs. > I suspect _gtca() does something similar to what is described in "Chapter 14. > Anchor support" in the LE Vendor Interfaces manual. Out of curiosity, I had a look at CEEARLU. The instruction sequence matches what is documented in the above mentioned chapter, except for the checking of R12 before continuing with it. 58C0 0010 | L R12,X'10'58CC | L R12,X'0'(R12)58CC 0004 | L R12,X'4'(R12)58CC 0144 | L R12,X'144'(R12)BFCF C000 | ICM R12,X'F',X'0'(R12)4780 F022 | BC X'8',X'22'(,R15)BFCF C000 | ICM R12,X'F',X'0'(R12)4780 F022 | BC X'8',X'22'(,R15)07FC | BCR X'F',R121BCC | SR R12,R1207FE | BCR X'F',R14 -- Peter Hunkeler -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
On Thu, 11 May 2017 17:08:41 -0500, John McKown wrote: > STM R0,RF,12(RD) SAVE ALL REGS. > L R3,0(,R1) POINT TO RETURN AREA > MVC 0(64,R3),12(RD) MOVE REGS AT ENTRY > SLR RF,RF > BR RE > >This does not use standard linkage, but is that really necessary? You are going to store 16 registers (64 bytes) at offset 12 in a 72-byte save area? What is in the word that you will clobber? -- Tom Marchant -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
AW: Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
> Interesting. A reference to _gtca() also in LE Vendor Interfaces. Hints here > and there in the C/C++ docs. I suspect _gtca() does something similar to what is described in "Chapter 14. Anchor support" in the LE Vendor Interfaces manual. -- Peter Hunkeler -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
Interesting. A reference to _gtca() also in LE Vendor Interfaces. Hints here and there in the C/C++ docs. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:IBM-MAIN@LISTSERV.UA.EDU] On Behalf Of Allan Kielstra Sent: Thursday, May 11, 2017 4:37 PM To: IBM-MAIN@LISTSERV.UA.EDU Subject: Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP Bernd's assembler technique will work. I have no idea why I can't find a description of this (taken from /usr/include/stdio.h) #ifndef __gtca #define __gtca() _gtca() #ifdef __cplusplus extern "builtin" #else #pragma linkage(_gtca,builtin) #endif const void *_gtca(void); #endif online. It is mentioned in the XL C/C++ Runtime Library Reference Since it's not really described, I'm not sure you are allowed to count on it existing in the future. But in the past, that is the function that I have used (in 31-bit anyway) to get the CAA directly in C++. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
Bernd's assembler technique will work. I have no idea why I can't find a description of this (taken from /usr/include/stdio.h) #ifndef __gtca #define __gtca() _gtca() #ifdef __cplusplus extern "builtin" #else #pragma linkage(_gtca,builtin) #endif const void *_gtca(void); #endif online. It is mentioned in the XL C/C++ Runtime Library Reference Since it's not really described, I'm not sure you are allowed to count on it existing in the future. But in the past, that is the function that I have used (in 31-bit anyway) to get the CAA directly in C++. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
> I know of people using SR RF,RF - but I never saw SLR RF,RF up until now This issue has been beat to death here but on recent processors SR, SLR and XR to clear a register are all equally fast. Use whichever one you find most aesthetic. At one time LHI r,0 was generally faster because SR/SLR/XR r,r tied up a fixed point arithmetic unit (albeit LHI uses 2 additional bytes of i-cache). Modern processors all recognize SR/SLR/XR r,r and treat it as a non-arithmetic "slam a zero into r." LHI may still have a slight advantage in some situations because it does not set the condition code, possibly making things easier on the branch prediction logic. That aspect is also advantageous for compilers which now do things like a compare, followed by a bunch of unrelated instructions, followed by a branch on the results of the compare -- to take advantage of pipelining. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:IBM-MAIN@LISTSERV.UA.EDU] On Behalf Of Bernd Oppolzer Sent: Thursday, May 11, 2017 3:24 PM To: IBM-MAIN@LISTSERV.UA.EDU Subject: Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP Am 12.05.2017 um 00:08 schrieb John McKown: > On Thu, May 11, 2017 at 4:55 PM, Bernd Oppolzer > <bernd.oppol...@t-online.de> > wrote: > >> Yes, of course. I detected the error when I looked at my piece of >> software from last year which examined the different LE heaps. >> >> and: thank you, Allan Kielstra, for the clarification regarding Reg >> 12; so my call to the ASSEMBLER function to get the address of the >> CEECAA will work? >> >> Here is the ASSEMBLER program which returns the registers (especially >> reg >> 12) >> to the C program: >> >> MDV9970 CSECT >> MDV9970 AMODE 31 >> MDV9970 RMODE ANY >> * >> *** >> *UNTERPROGRAMM ZUR ERMITTLUNG DER >> *AKTUELLEN REGISTERSTAENDE UND ABLAGE >> *IN EINEN C-BUFFER (DER ALS PARAMETER >> *UEBERGEBEN WIRD). ZWECK DER UEBUNG: >> *ZUGRIFF AUF CEECAA (COMMON ANCHOR AREA VOM LE) >> *UND DAMIT AUF ANYHEAP UND BELOWHEAP >> *BERND OPPOLZER / AUGUST 2016 >> *** >> * >> R0 EQU 0 >> R1 EQU 1 >> R2 EQU 2 >> R3 EQU 3 >> R4 EQU 4 >> R5 EQU 5 >> R6 EQU 6 >> R7 EQU 7 >> R8 EQU 8 >> R9 EQU 9 >> RA EQU 10 >> RB EQU 11 >> RC EQU 12 >> RD EQU 13 >> RE EQU 14 >> RF EQU 15 >> * >> STM RE,RC,12(RD)REGISTER SICHERN >> USING MDV9970,RF ADRESSIERUNG HERSTELLEN >> L R3,0(R1)ADRESSE VOM BUFFER = 1. PARAMETER >> MVC 0(52,R3),20(RD) REGISTER 0 BIS 12 AUS SA UEBERTR. >> STRD,52(R3) REGISTER 13 ABSPEICHERN >> MVC 56(8,R3),12(RD) REGISTER 14 UND 15 AUS SA UEBERTR. >> LMRE,RC,12(RD)REGISTER ZURUECKLADEN >> BRRE UND RUECKSPRUNG >> * >> END MDV9970 >> > Looks fairly good to me. For returning the 32 bit registers, that is. > But it seems to be "overkill" to me. The "guts" of the routine could be just: > > STM R0,RF,12(RD) SAVE ALL REGS. > L R3,0(,R1) POINT TO RETURN AREA > MVC 0(64,R3),12(RD) MOVE REGS AT ENTRY > SLR RF,RF > BR RE > > This does not use standard linkage, but is that really necessary? The > only possible abend would be on the MVC, if the routine is not called > properly. > I included the SLR just to "zero" the return code. If the C code is > declared as returning "void" (e.g. "void MDV9970(regs) ;" where regs > is defined as "uint regs[16];" ) then R15 on exit is ignored. > > But you should add a LM instruction to restore the registers, for example R3. The original program is called inside a C function, and I thought that the registers should be restored on exit in a (sort of) standard way. This is expected by the surrounding C routine, IMO. What I find most interesting: if I set RF (or any other register) to zero, I always would code XR RF,RF you use SLR RF,RF it's a matter of style, or maybe what you learned first. I know of people using SR RF,RF - but I never saw SLR RF,RF up until now. Nice :-) There was once a discussion that you can tell the author of a piece of software from such style attributes ... not only with ASSEMBLER, but
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
Am 12.05.2017 um 00:08 schrieb John McKown: On Thu, May 11, 2017 at 4:55 PM, Bernd Oppolzerwrote: Yes, of course. I detected the error when I looked at my piece of software from last year which examined the different LE heaps. and: thank you, Allan Kielstra, for the clarification regarding Reg 12; so my call to the ASSEMBLER function to get the address of the CEECAA will work? Here is the ASSEMBLER program which returns the registers (especially reg 12) to the C program: MDV9970 CSECT MDV9970 AMODE 31 MDV9970 RMODE ANY * *** *UNTERPROGRAMM ZUR ERMITTLUNG DER *AKTUELLEN REGISTERSTAENDE UND ABLAGE *IN EINEN C-BUFFER (DER ALS PARAMETER *UEBERGEBEN WIRD). ZWECK DER UEBUNG: *ZUGRIFF AUF CEECAA (COMMON ANCHOR AREA VOM LE) *UND DAMIT AUF ANYHEAP UND BELOWHEAP *BERND OPPOLZER / AUGUST 2016 *** * R0 EQU 0 R1 EQU 1 R2 EQU 2 R3 EQU 3 R4 EQU 4 R5 EQU 5 R6 EQU 6 R7 EQU 7 R8 EQU 8 R9 EQU 9 RA EQU 10 RB EQU 11 RC EQU 12 RD EQU 13 RE EQU 14 RF EQU 15 * STM RE,RC,12(RD)REGISTER SICHERN USING MDV9970,RF ADRESSIERUNG HERSTELLEN L R3,0(R1)ADRESSE VOM BUFFER = 1. PARAMETER MVC 0(52,R3),20(RD) REGISTER 0 BIS 12 AUS SA UEBERTR. STRD,52(R3) REGISTER 13 ABSPEICHERN MVC 56(8,R3),12(RD) REGISTER 14 UND 15 AUS SA UEBERTR. LMRE,RC,12(RD)REGISTER ZURUECKLADEN BRRE UND RUECKSPRUNG * END MDV9970 Looks fairly good to me. For returning the 32 bit registers, that is. But it seems to be "overkill" to me. The "guts" of the routine could be just: STM R0,RF,12(RD) SAVE ALL REGS. L R3,0(,R1) POINT TO RETURN AREA MVC 0(64,R3),12(RD) MOVE REGS AT ENTRY SLR RF,RF BR RE This does not use standard linkage, but is that really necessary? The only possible abend would be on the MVC, if the routine is not called properly. I included the SLR just to "zero" the return code. If the C code is declared as returning "void" (e.g. "void MDV9970(regs) ;" where regs is defined as "uint regs[16];" ) then R15 on exit is ignored. But you should add a LM instruction to restore the registers, for example R3. The original program is called inside a C function, and I thought that the registers should be restored on exit in a (sort of) standard way. This is expected by the surrounding C routine, IMO. What I find most interesting: if I set RF (or any other register) to zero, I always would code XR RF,RF you use SLR RF,RF it's a matter of style, or maybe what you learned first. I know of people using SR RF,RF - but I never saw SLR RF,RF up until now. Nice :-) There was once a discussion that you can tell the author of a piece of software from such style attributes ... not only with ASSEMBLER, but with other languages (even C etc.), too. With other languages, it's maybe more the style of writing, layout etc. Kind regards Bernd -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
On Thu, May 11, 2017 at 4:55 PM, Bernd Oppolzerwrote: > Yes, of course. I detected the error when I looked at > my piece of software from last year which examined the different LE heaps. > > and: thank you, Allan Kielstra, for the clarification regarding Reg 12; > so my call to the ASSEMBLER function to get the address of the CEECAA will > work? > > Here is the ASSEMBLER program which returns the registers (especially reg > 12) > to the C program: > > MDV9970 CSECT > MDV9970 AMODE 31 > MDV9970 RMODE ANY > * > *** > *UNTERPROGRAMM ZUR ERMITTLUNG DER > *AKTUELLEN REGISTERSTAENDE UND ABLAGE > *IN EINEN C-BUFFER (DER ALS PARAMETER > *UEBERGEBEN WIRD). ZWECK DER UEBUNG: > *ZUGRIFF AUF CEECAA (COMMON ANCHOR AREA VOM LE) > *UND DAMIT AUF ANYHEAP UND BELOWHEAP > *BERND OPPOLZER / AUGUST 2016 > *** > * > R0 EQU 0 > R1 EQU 1 > R2 EQU 2 > R3 EQU 3 > R4 EQU 4 > R5 EQU 5 > R6 EQU 6 > R7 EQU 7 > R8 EQU 8 > R9 EQU 9 > RA EQU 10 > RB EQU 11 > RC EQU 12 > RD EQU 13 > RE EQU 14 > RF EQU 15 > * > STM RE,RC,12(RD)REGISTER SICHERN > USING MDV9970,RF ADRESSIERUNG HERSTELLEN > L R3,0(R1)ADRESSE VOM BUFFER = 1. PARAMETER > MVC 0(52,R3),20(RD) REGISTER 0 BIS 12 AUS SA UEBERTR. > STRD,52(R3) REGISTER 13 ABSPEICHERN > MVC 56(8,R3),12(RD) REGISTER 14 UND 15 AUS SA UEBERTR. > LMRE,RC,12(RD)REGISTER ZURUECKLADEN > BRRE UND RUECKSPRUNG > * > END MDV9970 > Looks fairly good to me. For returning the 32 bit registers, that is. But it seems to be "overkill" to me. The "guts" of the routine could be just: STM R0,RF,12(RD) SAVE ALL REGS. L R3,0(,R1) POINT TO RETURN AREA MVC 0(64,R3),12(RD) MOVE REGS AT ENTRY SLR RF,RF BR RE This does not use standard linkage, but is that really necessary? The only possible abend would be on the MVC, if the routine is not called properly. I included the SLR just to "zero" the return code. If the C code is declared as returning "void" (e.g. "void MDV9970(regs) ;" where regs is defined as "uint regs[16];" ) then R15 on exit is ignored. > > Kind regards > > Bernd > > > -- Advertising is a valuable economic factor because it is the cheapest way of selling goods, particularly if the goods are worthless. -- Sinclair Lewis Maranatha! <>< John McKown -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
Yes, of course. I detected the error when I looked at my piece of software from last year which examined the different LE heaps. and: thank you, Allan Kielstra, for the clarification regarding Reg 12; so my call to the ASSEMBLER function to get the address of the CEECAA will work? Here is the ASSEMBLER program which returns the registers (especially reg 12) to the C program: MDV9970 CSECT MDV9970 AMODE 31 MDV9970 RMODE ANY * *** *UNTERPROGRAMM ZUR ERMITTLUNG DER *AKTUELLEN REGISTERSTAENDE UND ABLAGE *IN EINEN C-BUFFER (DER ALS PARAMETER *UEBERGEBEN WIRD). ZWECK DER UEBUNG: *ZUGRIFF AUF CEECAA (COMMON ANCHOR AREA VOM LE) *UND DAMIT AUF ANYHEAP UND BELOWHEAP *BERND OPPOLZER / AUGUST 2016 *** * R0 EQU 0 R1 EQU 1 R2 EQU 2 R3 EQU 3 R4 EQU 4 R5 EQU 5 R6 EQU 6 R7 EQU 7 R8 EQU 8 R9 EQU 9 RA EQU 10 RB EQU 11 RC EQU 12 RD EQU 13 RE EQU 14 RF EQU 15 * STM RE,RC,12(RD)REGISTER SICHERN USING MDV9970,RF ADRESSIERUNG HERSTELLEN L R3,0(R1)ADRESSE VOM BUFFER = 1. PARAMETER MVC 0(52,R3),20(RD) REGISTER 0 BIS 12 AUS SA UEBERTR. STRD,52(R3) REGISTER 13 ABSPEICHERN MVC 56(8,R3),12(RD) REGISTER 14 UND 15 AUS SA UEBERTR. LMRE,RC,12(RD)REGISTER ZURUECKLADEN BRRE UND RUECKSPRUNG * END MDV9970 Kind regards Bernd Am 11.05.2017 um 23:07 schrieb Tom Marchant: On Thu, 11 May 2017 15:27:38 -0500, Allan Kielstra wrote: This statement: CEECSA is always address by reg 12, while inside a LE module. is not strictly true. GPR12 is only required to point to CEECSA on entry to and exit from a procedure. Compilers are free to use GPR12 for whatever other purpose they chose at other program points. That means that if you get a crash in the middle of a procedure (COBOL PROGRAM) you should not look at the current value of GPR12. You should go back to the register save area and find what GPR12 was on entry to the procedure. (I mention this because with COBOL V5/6, GPR12 actually is often reused inside COBOL programs.) I think you both mean CEECAA, the Common Anchor Area. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
If a C or PL/I or COBOL (or any LE high level language) program calls an assembler program, it will have set GPR12 to the CEE Anchor correctly before making the call. Assuming that you are completely lost in space in LE and you need the CEE anchor, there is a service called CEEARLU. It is documented here: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.1.0/com.ibm.zos.v2r1.ceev100/ceearlu.htm The compilers don't like using this because it is known to be not very fast. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
On Thu, 11 May 2017 15:27:38 -0500, Allan Kielstra wrote: >This statement: > >>>CEECSA is always address by reg 12, while inside a LE module. > >is not strictly true. GPR12 is only required to point to CEECSA on entry to >and exit from a procedure. Compilers are free to use GPR12 for whatever other >purpose they chose at other program points. > >That means that if you get a crash in the middle of a procedure (COBOL >PROGRAM) you should not look at the current value of GPR12. You should go >back to the register save area and find what GPR12 was on entry to the >procedure. > >(I mention this because with COBOL V5/6, GPR12 actually is often reused inside >COBOL programs.) I think you both mean CEECAA, the Common Anchor Area. -- Tom Marchant -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
oh oh ... I did not take this into account ... I wrote a C program to get the HPCB addresses for Belowheap and Anyheap, and to get them, I needed the CEECAA, and I did this by looking at reg 12 using an ASSEMBLER subprogram: memset (rbuffer, 0x00, sizeof (rbuffer)); MDV9970 (rbuffer); #if 0 for (i = 0; i < 16; i ++) { printf ("Register %d = %p\n", i, rbuffer [i]); } #endif ceecaa = rbuffer [12]; ceeedb = *((char **) (ceecaa + 0x2f0)); if (memcmp (ceeedb, "CEEEDB ", 8) != 0) return; anyp = *((char **) (ceeedb + 0x20)); if (memcmp (anyp, "HPCB", 4) != 0) return; belowp = *((char **) (ceeedb + 0x24)); if (memcmp (belowp, "HPCB", 4) != 0) return; worked without problems, but maybe lucky :-) is there a LE function to get the address of the CEECAA? or will I have to go back to the prior save area using reg 13? the program, BTW, checks all the heap control blocks and does some sort of book keeping at different points in time ... and then it prints the differences ... looking for memory leaks. This helped us a lot to find memory leaks in PL/1 programs ... but it works for every programming language which uses LE. Contact me offline, if you are interested about the details. Thank you, kind regards Bernd Am 11.05.2017 um 22:27 schrieb Allan Kielstra: This statement: CEECSA is always address by reg 12, while inside a LE module. is not strictly true. GPR12 is only required to point to CEECSA on entry to and exit from a procedure. Compilers are free to use GPR12 for whatever other purpose they chose at other program points. That means that if you get a crash in the middle of a procedure (COBOL PROGRAM) you should not look at the current value of GPR12. You should go back to the register save area and find what GPR12 was on entry to the procedure. (I mention this because with COBOL V5/6, GPR12 actually is often reused inside COBOL programs.) -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
This statement: >>CEECSA is always address by reg 12, while inside a LE module. is not strictly true. GPR12 is only required to point to CEECSA on entry to and exit from a procedure. Compilers are free to use GPR12 for whatever other purpose they chose at other program points. That means that if you get a crash in the middle of a procedure (COBOL PROGRAM) you should not look at the current value of GPR12. You should go back to the register save area and find what GPR12 was on entry to the procedure. (I mention this because with COBOL V5/6, GPR12 actually is often reused inside COBOL programs.) -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
AW: Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
> And I forgot to mention: > > CEECSA is always address by reg 12, while inside a LE module. ... and I forgot to thank you as well, Bernd -- Peter Hunkeler -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
AW: Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
Many thanks for the details. Much appreciated. This information might be in the manuals, but it is a bit scattered. -- Peter Hunkeler -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
Bernd has already started the reply, but I would like to add a little bit. (First, I should say that most of this stuff IS documented in the PG and MG, but...) To find a specific W-S variable, you will need a listing. If you start with a dump, you will find a stack frame for your COBOL program and in its register save area, you will find the CAA Anchor in GPR12. Think of the CAA anchor as a thread specific piece of data. Fortunately, most non OO COBOL programs are single threaded so you don't have to worry about that subtlety. Also, if you start with a dump, you'll find the entry point for the COBOL program. From this, you can find the PPA1 (there is one for every sub routine in a compilation unit -- using C terminology): 00 02PROCPGG1 00 47F0 F014 02BC R15,20(,R15) # Skip over constant area 04 01C3 C5C5 02DC X'01C3C5C5' # Eyecatcher: CEE 08 0200 02DC X'0200' # Stack Size 0C 0690 02DC X'0690' # Offset to PPA1 <<-- 10 47F0 F001 02BC R15,1(,R15) # Wrong Entry Point: cause exception from the PPA1, you can find the PPA2 (there is one for the entire compilation unit -- again C terminology): PPA1: Entry Point Constants 000690 1CCEA506 =F'483304710' Flags 000694 0850 =A(PPA2-PGG1) << 000698 07C0 =A(PPA3-PGG1) from the PPA2, you can find the PPA4 (again only one): PPA2: Entry Point Constants 000850 04002203 =F'67117571' Flags 000854 F7B0 =A(CEESTART-PPA2) 000858 0058 =F'88' A(PPA4-PPA2)<<--- 00085C FFB0 =A(TIMESTMP-PPA2) 000860 F7B0 =A(PrimaryEntryPoint-PPA2) 000864 0220 =F'35651584' Flags The C_WSA is actually the combined writeable static area for all of the programs bound into your module (or DLL). To find the entire C_WSA for the module, you need to get the CEECRENT pointer out of the CEE Anchor. That means, getting 500(GPR12). Now you need to find the bit of the C_WSA for this particular program (compilation unit in C terminology). You can get that from the PPA4: PPA4: Entry Point Constants 0008A8 0800 =F'134217728' Flags 1 0008AC 00020100 =F'131328' Flags 2 0008B0 =F'0' A(NORENTstatic) 0008B4 =F'0' Q(RENTstatic)<<- Add that QCON to the CEECRENT -- 500(GPR12) -- and you have the start of the section of the WSA for your program. Now you need to know if WSOPT was used or not. For that you need to go back to the PPA2 and find the timestamp: 000844 FFB0 =A(TIMESTMP-PPA2) The time stamp is a fixed length and immediately following it is : Compiler Options and Program Information Section 000814 0034=X'0034' Size of Compiler Options and Prog Info Section 000816 (+00) 0474=X'0474' UNSIGNED BINARY CODE PAGE CCSID VALUE 000818 (+02) 07 =X'07' ARCHITECTURE LEVEL 000819 (+03) 00 =X'00' OPTIMIZATION LEVEL 00081A (+04) 1406=X'1406' INFO. BYTES 28-29 00081C (+06) =X'' INFO. BYTES 30-31 00081E (+08) A0C8754C2000 =X'A0C8754C2000' INFO. BYTES 1-6 000824 (+14) 00184001 =X'00184001' INFO. BYTES 7-12 The bit you're looking for is bit 3 of byte 15. Compare the output above to the same program with NOWSOPT 00080C (+14) 00084001 =X'00084001' INFO. BYTES 7-12 If you are using NOWSOPT (which is the default for V4) your W-S data items are all in your piece of the module's WSA. To find a specific item, you need to consult the listing looking
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
Bernd and Peter, What Bernd shows you is the way I have found it in COBOL V5.1.1. I am putting up V6 next month and will revisit it again. I also did the ASM map in V5.1.1 and discovered that Working Storage seems to be based on Reg. 8. I do not have V5.2, but I would imagine it would be the same. Cheers, Tom On 5/10/2017 3:29 PM, Bernd Oppolzer wrote: 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
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
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
Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
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
How to find Cobol (and C) Working Storage variables in an SVCDUMP
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. -- Peter Hunkeler -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN