vm370 icon indicating copy to clipboard operation
vm370 copied to clipboard

EXECIO DISKW: DMSFRE160T INVALID DMSFREE CALL FROM 021240.

Open RossPatterson opened this issue 1 year ago • 6 comments

I'm trying to read a large value from a Rexx variable, and write it to disk, using EXECIO DISKW. Looking at DMSXIO, it appears GETREXXV is receiving SHVTRUNC from Rexx (value truncated because buffer is too small), then tries to increase the buffer to REXXBUFL bytes. Unfortunately, REXXBUFL is 0, leading to a DMSFREE DWORDS=0, and then DMSFRE160T.

I assume this is a bug in the Rexx (BRexx?) implementation of the EXECCOMM subcommand.

To reproduce:

/* BOOM EXEC */
Trace I
'ERASE TEMP TEXT A'  
'EXECIO * DISKR DDR MODULE S ( STEM RECORD.'
N = Record.0
'EXECIO 1 DISKW TEMP TEXT A ( VAR Record.'N

Result looks like this:

Ready;
boom
     3 *-* 'ERASE TEMP TEXT A'
       >L>   "ERASE TEMP TEXT A"
File 'TEMP TEXT A' not found.
     4 *-* 'EXECIO * DISKR DDR MODULE S ( STEM RECORD.'
       >L>   "EXECIO * DISKR DDR MODULE S ( STEM RECORD."
     5 *-* N = RECORD.0
       >C>   "RECORD.0"
       >V>   "3"
     6 *-* 'EXECIO 1 DISKW TEMP TEXT A ( VAR RECORD.'N
       >L>   "EXECIO 1 DISKW TEMP TEXT A ( VAR RECORD."
       >V>   "3"
       >O>   "EXECIO 1 DISKW TEMP TEXT A ( VAR RECORD.3"
DMSFRE160T INVALID DMSFREE CALL FROM 021240.
CMS

RossPatterson avatar Feb 19 '24 03:02 RossPatterson

There's a workaround - specifying the LRECL on the DISKW command avoids the problem:

'EXECIO 1 DISKW TEMP TEXT A 0 V 65535 ( VAR RECORD.'N

It works because $DISKW pre-allocates the buffer to the LRECL size if it exceeds 255 bytes between $DISKW30 and $DISKW40.

RossPatterson avatar Feb 19 '24 03:02 RossPatterson

Hey Ross, Glad to see your brain is still hanging in there. /Bob Bolch

BobBolch avatar Feb 19 '24 13:02 BobBolch

After more research, BREXX's EXECCOMM is correct. DMSXIO should be getting the size to obtain from SHVVALL, not SHVBUFFL. This update assembles, but I can't test it yet, because I'm not ready to rebuild the CMS nucleus (I don't want to destabilize diagnosis for Issue #96). But it's right, and it jives with other sources on the web (e.g., the SAS/C cmsshv doc).

File DMSXIO AUXLCL:

RAP002DS ISSUE#95 DMSFRE160T from EXECIO DISKW when recno unspecified.

File DMSXIO RAP002DS:

./ R  20420000 20440000 $
* needed in SHVVALL. Allocate a new buffer and try again.      RAP002DS
*                                                              RAP002DS
         L     R1,SHVVALL         Length of variable value     RAP002DS

RossPatterson avatar Apr 14 '24 03:04 RossPatterson

This update assembles, but I can't test it yet

Tested and confirmed, using BOOM EXEC above.

RossPatterson avatar Apr 14 '24 20:04 RossPatterson

FYI, CMSGEND doesn't know how to build EXECIO. I updated

-$$E     &STACK LIFO GO     GO
         &STACK LIFO EDMAIN EDIT

to

-$$E     &STACK LIFO GO     GO   XIOT
         &STACK LIFO EDMAIN EDIT EXECIO

to build it as a transient module without SYSTEM or STRINIT.

RossPatterson avatar Apr 14 '24 20:04 RossPatterson

Fixing this exposed a latent bug in DMSXIO. The code in GETREXXV that gets a larger buffer never returns one that it had previously gotten. So there's a slow, probably small, memory leak. This update fixes that.

DMSXIO AJXLCL:

RAP003DS ISSUE#95 DMSXIO fails to return replaced dynamic buffers.
RAP002DS ISSUE#95 DMSFRE160T from EXECIO DISKW when recno unspecified

DMSXIO RAP003DS:

./ I  20420200          $
         ICM   R0,B'1111',REXBUFFL Did we already have one?    RAP003DS
         BZ    NOTRUNC0           No, nothing to FRET.         RAP003DS
         SRL   R0,3               Bytes to dwords              RAP003DS
         L     R1,REXBUFF         Get address.                 RAP003DS
         DMSFRET DWORDS=(0),LOC=(1) Return the old buffer.     RAP003DS
NOTRUNC0 DS    0H                                              RAP003DS

RossPatterson avatar Apr 30 '24 02:04 RossPatterson