Operating System - OpenVMS
1751883 Members
5580 Online
108783 Solutions
New Discussion юеВ

Re: Pascal program crashing with -RMS-F-DME, dynamic memory exhausted

 
Brian Reiter
Valued Contributor

Pascal program crashing with -RMS-F-DME, dynamic memory exhausted

Hi folks,

I have an executable which sometimes terminates with the folowing error:

-RMS-F-DME, dynamic memory exhausted

Are there any particular quotas I should be looking at? The execurable was written in Pascal (6.0-107), running on OpenVMS 7-3-2 (sadly only up to Update 6). The problem is intermittent.

Regards

Brian
39 REPLIES 39
abrsvc
Respected Contributor

Re: Pascal program crashing with -RMS-F-DME, dynamic memory exhausted

Use the $HELP/MESS DME command to get specifics, but a common cause of this is excessive open files. Check the code for repeated opens without corresponding closes.

For more specifics, post the stackdump if you have it and we can guide you on how to read that if you are not sure.

Dan
Hein van den Heuvel
Honored Contributor

Re: Pascal program crashing with -RMS-F-DME, dynamic memory exhausted

Is it causing a problem more often now?
Anything change recently?
CONVERTs with bigger buckets --> more memory?
Time for a convert? Unlikely impact

>> Are there any particular quotas I should be looking at?

Good question.

DME refers to VIRTUAL memory shortage 'at the wrong time', that is while RMS needed it.

So you can to watch and/or increase PGFLQUOTA
You also may want to watch (F$GETJPI ?) FREP0VA and FREP1VA


Sysgen param IMGIOCNT can be use to move more RMS stuff in P1 space and decrease 'fragmentation' of that memory zone.

The better way to set that is per image using IOSEGMENT in the option file.
Far too few folks use that.
If you can not re-link readily, then you can just tweak the image header to fix this on th e fly, for example with the DCL below.

Now you should also look at factors influencing usage, specifically SET RMS.

Issue a SHOW RMS and see if there are oddly large, and/or changed numbers there?

Does this program open and close files with global buffers repeatedly?

Good luck,
Hein


$! IMGIOCNT.COM Hein van den Heuvel
$if p1.eqs."" then $inquire p1 "image file name"
$
$! libr /extr=$EIHDDEF/out=tt: sys$library:lib.mlb
$! EIHD$L_IMGIOCNT 60
$
$open/read/write file 'f$parse(p1,".exe")
$offset = 60 !Alpha. We'll assume exe matches current system.
$if f$getsyi("arch_name").eqs."VAX" then exit ! offset = 32
$read file header
$old = f$cvsi(offset*8,32,header)
$write sys$output "IMGIOCNT was ", old, "."
$if p2.nes.""
$then
$ header[offset*8,32] = 'p2
$ write/update/symbol file header
$ write sys$output "IMGIOCNT now ", p2,"."
$endif
$close file
Robert Gezelter
Honored Contributor

Re: Pascal program crashing with -RMS-F-DME, dynamic memory exhausted

Brian,

I suggest that you consider enabling dumps on that image. Analyzing the resulting process dump file may be quite illuminating (see SET PROCESS/DUMP).

- Bob Gezelter, http://www.rlgsc.com
H.Becker
Honored Contributor

Re: Pascal program crashing with -RMS-F-DME, dynamic memory exhausted

>>>Sysgen param IMGIOCNT can be use to move more RMS stuff in P1 space and decrease 'fragmentation' of that memory zone.

Which - as you probably know - affects all processes.

Relinking with an options file gives you the linker limit which on Alpha is very conservative. A relinked image only affects the P1 layout, when running this image.

>>>If you can not re-link readily, then you can just tweak the image header to fix this on th e fly, ...

Not really on the fly, it's a change on the disk.

Both, IOSEGMENT and IMGIOCNT are a number of pagelets, that is a virtual address space, in P1. P1 is limited to 1GB. Obviously that's too much but it is difficult to give a good upper limit for this. Although you have 32 bits for the IOSEGMENT in the image header, you should be very careful with the DCL script and numbers resulting in more than half of P1: there is much more than RMS buffers which needs to be in this memory region and the shown DCL script doesn't do any check, here.
John Gillings
Honored Contributor

Re: Pascal program crashing with -RMS-F-DME, dynamic memory exhausted

re: Robert - enabling process dumps...

Excellent suggestion, but chances are whatever is causing the DME will probably block the creation of a dump file. Sometimes it even blocks issueing an error message.

Brian,

See SHOW PROCESS/MEMORY to see the process dynamic memory area. Unfortunately this doesn't have a /ID option, so you can only see it from the process itself. The SYSGEN parameters which control it are PIOPAGES and CTLPAGES. Not to be messed with lightly!

As well as everything else suggested, I'd also add checking for runaway logical name and/or symbol creation. I'd also check SHOW RMS for a non-zero value in disk multibuffer counts.
A crucible of informative mistakes
Hoff
Honored Contributor

Re: Pascal program crashing with -RMS-F-DME, dynamic memory exhausted

Get NFS entirely out of the path. That stuff can lead to all sorts of wacky I/O errors. (I just got done debugging a seriously bad diagnostic being emitted by a rather more current NFS configuration, too. How bad? Did you know that an NFS mount "NOPRIV" diagnostic can mean "I don't have a compatible NFS server to talk to?" Neither did I.)

Make absolutely certain that your NFS is patched to current, as you're (also) operating in the same range with a very insidious floating point register corruption lurking within NFS. Que pueden causar errores oscuro; obscure bugs can follow.

Back within your own Pascal code, desk-check the open and write and close paths, as errors and failures to deal with errors can get tangled, and the results can be confusing at best. (The older and longer that code has been in service, the more likely it contains status check errors and IOSB and synchronization bugs, too.)

If you're not interested in making a career out of debugging this particular (or any other) code, then the next step can be to Instrument the code. VMS doesn't provide these routines, but there are source code examples around and you can add your own instrumentation. (In non-trivial code, it's often best to start with the diagnostics as the scaffolding and build the application code around that.)
labadie_1
Honored Contributor

Re: Pascal program crashing with -RMS-F-DME, dynamic memory exhausted

John Gillings said

"See SHOW PROCESS/MEMORY to see the process dynamic memory area. Unfortunately this doesn't have a /ID option, so you can only see it from the process itself."

Well, if memory serves me, 2 articles in the HP VMS database were about doing it, one in DCL, 2) and an Sda extension called ctlpa, in order to do the same thing inside SDA.

I even know the author
:-)

labadie_1
Honored Contributor

Re: Pascal program crashing with -RMS-F-DME, dynamic memory exhausted

See

OpenVMS - Example C: How to Monitor Another Process Using an SDA Extension

http://www11.itrc.hp.com/service/cki/docDisplay.do?docLocale=en&docId=emr_na-c01597305

and for Itanium, replace NOTINPHYS with NOREAD
labadie_1
Honored Contributor

Re: Pascal program crashing with -RMS-F-DME, dynamic memory exhausted

On Itanium

$ set noon
$ say :== write sys$output
$ if P1.eqs."" then exit
$! if f$getsyi("ARCH_NAME") .nes. "Alpha" then exit
$ if .not.f$privilege("CMKRNL")
$ then
$ say "the privilege CMKRNL is needed"
$ exit
$ endif
$ if f$extract(0,4,f$getsyi("version")).ges."V7.3"
$ then
$ goto follow
$ else
$ say "the SDA> repeat /until=condition is not yet available"
$ say "a workaround may be a high number of SDA> exam @."
$ say "until the message NOREAD (on Itanium) is received."
$ exit
$ endif
$follow:
$ cpn = 0
$ tot_n = %X0
$ tot_largest = %X0
$ pid = f$getjpi("","PID")
$ fntmp = "sys$scratch"+":"+f$getjpi("","pid")+".tmp"
$ fntmp_a = "sys$scratch:sda_" + pid + "_a.tmp"
$ fntmp_b = "sys$scratch:sda_" + pid + "_b.tmp"
$ fntmpall = "sys$scratch:sda_" + pid + "*.tmp"
$ open/write log 'fntmp
$ write log "$ set noon"
$ write log "$ def/user sys$error nla0:"
$ write log "$ def/user sys$output nla0:"
$ write log "$ ana/sys "
$ write log "set proc/id=''P1' "
$ write log "set out ''fntmp_a' "
$ write log "exam ctl$gq_allocreg"
$ write log "exam @."
$ write log "repeat/until=NOREAD"
$ close log
$ @'fntmp'
$ ! keep only the useful lines
$ sea 'fntmp_a' "00000000.7"/out='fntmp_b'
$ open/read log1 'fntmp_b
$ cp = 0
$loop:
$ read/end=end log1 line
$ cp = cp + 1
$ tot_'cp = "%x"+f$extract(20,8,line)
$ tot_n = tot_n + tot_'cp
$ if tot_'cp.gt.tot_largest then tot_largest = tot_'cp
$ goto loop
$ end:
$ close log1
$ tot_largest = tot_largest + 0
$ !delete/nolog/noconf 'fntmpall';*
$ say "sh proc/mem/id=''P1' -> ''tot_n' free ,and ''tot_largest' is the largest"
$ exit


and on Alpha

$ set noon
$ say :== write sys$output
$ if P1.eqs."" then exit
$! if f$getsyi("ARCH_NAME") .nes. "Alpha" then exit
$ if .not.f$privilege("CMKRNL")
$ then
$ say "the privilege CMKRNL is needed"
$ exit
$ endif
$ if f$extract(0,4,f$getsyi("version")).ges."V7.3"
$ then
$ goto follow
$ else
$ say "the SDA> repeat /until=condition is not yet available"
$ say "a workaround may be a high number of SDA> exam @."
$ say "until the message NOTINPHYS is received."
$ exit
$ endif
$follow:
$ cpn = 0
$ tot_n = %X0
$ tot_largest = %X0
$ pid = f$getjpi("","PID")
$ fntmp = "sys$scratch"+":"+f$getjpi("","pid")+".tmp"
$ fntmp_a = "sys$scratch:sda_" + pid + "_a.tmp"
$ fntmp_b = "sys$scratch:sda_" + pid + "_b.tmp"
$ fntmpall = "sys$scratch:sda_" + pid + "*.tmp"
$ open/write log 'fntmp
$ write log "$ set noon"
$ write log "$ def/user sys$error nla0:"
$ write log "$ def/user sys$output nla0:"
$ write log "$ ana/sys "
$ write log "set proc/id=''P1' "
$ write log "set out ''fntmp_a' "
$ write log "exam ctl$gq_allocreg"
$ write log "exam @."
$ write log "repeat/until=NOTINPHYS"
$ close log
$ @'fntmp'
$ ! keep only the useful lines
$ sea 'fntmp_a' "00000000.7"/out='fntmp_b'
$ open/read log1 'fntmp_b
$ cp = 0
$loop:
$ read/end=end log1 line
$ cp = cp + 1
$ tot_'cp = "%x"+f$extract(20,8,line)
$ tot_n = tot_n + tot_'cp
$ if tot_'cp.gt.tot_largest then tot_largest = tot_'cp
$ goto loop
$ end:
$ close log1
$ tot_largest = tot_largest + 0
$ !delete/nolog/noconf 'fntmpall';*
$ say "sh proc/mem/id=''P1' -> ''tot_n' free ,and ''tot_largest' is the largest"
$ exit