          <<< NOTED::DISK$NOTES7:[NOTES$LIBRARY_7OF4]HACKERS.NOTE;1 >>>
                               -< ** Hackers ** >-
================================================================================
Note 1786.0          how to force cleanup on image rundown?           20 replies
CUJO::SAMPSON                                       192 lines   2-NOV-1995 23:21
--------------------------------------------------------------------------------
	Hello,

	What do you think would be the best way to ensure that certain
cleanup tasks are *always* performed by a program on image rundown,
even if the user issues control-Y/STOP, or a QUIT to the debugger,
either of which prevents execution of the normal user-mode exit handlers?

	Use of the IMG$ADD_PRIVILEGED_VECTOR routine to specify a kernel
rundown routine has been suggested by a knowledgeable source.  Would it
be best to use this method to perform all critical cleanup in kernel
mode, or (alternatively) would it be possible to make use of this method
to force all declared user-mode exit handlers to execute (in user mode)?
How would/should the latter be done?

						Thanks,
						Bob Sampson


           <<< TURRIS::DISK$NOTES_PACK:[NOTES$LIBRARY]DEBUG.NOTE;4 >>>
                                   -< DEBUG >-
================================================================================
Note 1725.0              ensuring cleanup when debugging               4 replies
CUJO::SAMPSON                                        53 lines   1-NOV-1995 02:31
--------------------------------------------------------------------------------
	Hello,

	I've written a set of routines for a customer, and packaged them
as a shareable image.  Exit handlers are declared for cleanup at image
exit.  I try to ensure that the exit handlers get executed by preventing
anyone from deleting the process until after the exit handlers have
executed (the last one executed allows the process to be deleted again).

	The customer wants to link against this shareable image, and use
these routines, during application testing and debugging.  However, running
an application under the debugger allows all of the declared exit handlers
to be inadvertently skipped, if the user quits the debug session.  This
leaves the process undeletable and the cleanup undone.

	I'm looking for the best way to either ensure that all the exit
handlers run, regardless of whether the user quits the debug session,
or, failing that, to detect from within the routines at run time that
a debug session exists, and avoid making the process undeletable.

	There is a fairly simple way to determine whether the debugger
has already been invoked, shown below.

#include <ints.h>
#include <lib$routines.h>
#include <ssdef.h>
#include <starlet.h>
#include <stdio.h>

uint32 debugger_activated()
{
  lib$establish(lib$sig_to_ret); /* return SS$_DEBUG if no debugger */
  lib$signal(SS$_DEBUG,1,"\002go"); /* try to invoke debugger */
  return SS$_NORMAL; /* if debugger was there */
}

main()
{
  if (debugger_activated() & 1)
    printf("The debugger has already been activated.\n");
  else
    printf("The debugger has *not* been activated yet.\n");
{

	This is enough to handle the usual case where the debugger is
initially given control, but it cannot handle the case where the application
starts without the debugger, the exit handlers are all declared, the process
is made undeletable, and then the user presses control-Y and issues the DEBUG
command.

	Does anyone know of a more foolproof way of doing the right thing?

							Thanks,
							Bob Sampson
================================================================================
Note 1725.1              ensuring cleanup when debugging                  1 of 4
SSPADE::DIETER                                       16 lines   1-NOV-1995 08:16
--------------------------------------------------------------------------------

you could setup a system wide DBG$INIT command 
procedure with the following contents:

define/command quit = "exit"

this would redefine the debugger's quit command
to be exit.  however, this might not work if some
users had their own dbg$init procedures...  I 
don't know offhand what happens if there is a 
job/process dbg$init logical AND a group/system
one, although I suspect the debugger will only
execute the 'local' one...  (you could have 
folks @ the system one from their local ones...)

Mary
================================================================================
Note 1725.2              ensuring cleanup when debugging                  2 of 4
CSC64::BLAYLOCK "If at first you doubt,doubt again." 33 lines   1-NOV-1995 13:32
--------------------------------------------------------------------------------


How do you deal with just a

	run image
	<ctrl/y>
	STOP

sequence?  This bypasses exit handlers also (with or without
the debuggers presence).

Anyway, if you are in kernel mode doing a 

	ctl$gl_pcb->pcb$v_nodelet = 1 ;

investigate the routine IMG$ADD_PRIVILEGED_VECTOR (on AXP it's
IMG$ADD_PRIVILEGED_VECTOR_ENTRY) to add a kernel rundown routine
to your image.  See [SYS.LIS]IMGMAPISD.LIS on a neighborhood results
listing.

For example:

static int kernel_rundown_routine( int ) ;

extern
	img$add_privileged_vector_entry( (*func)(), int, int ) ;

#define VEC_TYPE_KERNEL_RUNDOWN 2
#define PERM_FLAG_TEMPORARY 0

	...
	img$add_privileged_vector_entry(kernel_rundown_routine, 
			VEC_TYPE_KERNEL_RUNDOWN, PERM_FLAG_TEMPORARY );
================================================================================
Note 1725.3              ensuring cleanup when debugging                  3 of 4
CUJO::SAMPSON                                        40 lines   1-NOV-1995 21:47
                                -< cool ideas! >-
--------------------------------------------------------------------------------
	re .1:

	That's a good idea that I could incorporate into the routine that
checks for an active debug session; something like:

lib$signal(SS$_DEBUG,1,"\037define/command quit = \"exit\";go");


	re .2:

>How do you deal with just a
>
>	run image
>	<ctrl/y>
>	STOP
>
>sequence?  This bypasses exit handlers also
>(with or without the debuggers presence).

	Good point.  Clearly I hadn't dealt with that at all.

>investigate the routine IMG$ADD_PRIVILEGED_VECTOR (on AXP it's
>IMG$ADD_PRIVILEGED_VECTOR_ENTRY) to add a kernel rundown routine
>to your image.  See [SYS.LIS]IMGMAPISD.LIS on a neighborhood results
>listing.

	Ah, *very* intriguing, thanks!  This looks like the surest way
to see that the process is always made deletable after image rundown.

	Is there any way this could also be used to force all of the exit
handler linked lists (user, super, exec) to execute as well?  Are the
linked lists still intact when the kernel rundown routine runs?  Is there
a good way on both Alpha and VAX for the kernel rundown routine to execute
the exit handlers in the access modes (user, super, exec) from which they
were declared?

	The reason I ask is that, if I could ensure that the exit handlers
*always* execute, even when the process is stopped, then I might not even
have to ever make the process undeletable.  The rundown would *always*
get done, unless the system crashes, but at that point, who cares?!?
================================================================================
Note 1725.4              ensuring cleanup when debugging                  4 of 4
CSC64::BLAYLOCK "If at first you doubt,doubt again."  9 lines   2-NOV-1995 12:13
--------------------------------------------------------------------------------


I think that you might want to move this discussion to 
NOTED::HACKERS or to the VAXAXP::VMSNOTES conference.
There is a section in the IDSM on image rundown and
termination that would describe what lists are still
intact and at what time.  As to whether on not to execute
exit routines really depends on what you are trying to
clean up.
================================================================================
Note 1786.1          how to force cleanup on image rundown?              1 of 20
XDELTA::HOFFMAN "Steve; VMS Engineering"             22 lines   3-NOV-1995 11:04
                             -< Avoid If Possible >-
--------------------------------------------------------------------------------

   The easiest way around this is to rap the knuckles of a developer that
   incorrectly exits from the image -- you're spending a lot of time and
   effort dealing with a problem that apparently creeps in only during
   the debugging cycle.  With a sufficiently large quantity of bloody
   knuckles, the problem goes away.  :-)

   The best way to deal with this situation is to not get into a situation
   where one *has* to perform the specified tasks on the way out -- even
   if the problem around debugging is resolved, the application will still
   have to deal with system crashes and power failures.  My tendency would
   be to consider a design that cleans up after a failure automatically --
   using locks when feasible or reasonable, and specific lock-coordinated
   procedures and restart-recovery sequences for dealing with unfinished
   modification sequences during a restart, and trying to entirely avoid
   a "last one out" switch -- trying to avoid a switch or operation that
   *has* to be performed "on the way out".

   And, of course, you can provide a tool that can tweak the "last one
   out" bit for use during debugging -- this is useful when one of the
   developers is bigger than you are.  :-)

================================================================================
Note 1786.2          how to force cleanup on image rundown?              2 of 20
CUJO::SAMPSON                                        14 lines   4-NOV-1995 08:04
                       -< "don't do that!" isn't enough >-
--------------------------------------------------------------------------------
	Steve,

	As you may have guessed, this is for my PFNMAP global sections
routines.  The cleanup that I want to ensure happens is my bookkeeping
for section unmapping, deletion, and deallocation.  Remember, these
routines are just a stopgap measure for about a year, until the
"sections without backing store" feature gets implemented in OpenVMS
V7.1 (I hope).  Even though this is a "temporary" implementation, it
still has to be bulletproofed reasonably well.  Note that the cleanup
is not required if the system crashes.  I just need to ensure cleanup
*every time* the image terminates, by whatever means.

							Thanks,
							Bob Sampson
================================================================================
Note 1786.3          how to force cleanup on image rundown?              3 of 20
AUSSIE::GARSON "achtentachtig kacheltjes"            10 lines   5-NOV-1995 17:27
--------------------------------------------------------------------------------
    re .0
    
    I don't think a kernel rundown routine could easily get anything to
    happen in user mode. Whatever you need to do, just do it in kernel
    mode.
    
    Another idea that you might want to consider is to use an auxiliary
    process to ensure that cleanup occurs when an image or process exits
    (but the system doesn't). Applicability depends strongly on what it is
    that you are doing.
================================================================================
Note 1786.4          how to force cleanup on image rundown?              4 of 20
XDELTA::HOFFMAN "Steve; VMS Engineering"             38 lines   6-NOV-1995 12:28
                        -< Cleanup at exit vs startup >-
--------------------------------------------------------------------------------

> Even though this is a "temporary" implementation, it
>still has to be bulletproofed reasonably well.  Note that the cleanup
>is not required if the system crashes.  I just need to ensure cleanup
>*every time* the image terminates, by whatever means.

   Focusing on application cleanup at termination is probably the wrong
   spot to focus -- while one does need to cleanup here to obtain the
   best performance, often the most reliable and best spot for application
   termination cleanup is at application startup, _not_ termination.

   Place an interlocked bitlock indicating a "modification is in progress"
   or a "section corrupt, cleanup needed", a "modification started at
   clocktime" quadword, and an "application performing cleanup PID" at
   the front of the section, and if the interlock is set for a programmable
   (large) multiple of the longest expected modification interval, code the
   application connection routine to assume the modification routine went
   nuts or crashed, and that it must then call a recovery routine to recover
   or reset the contents of the section.  Also code the connection and
   synchronization routines to "stall" while a write-modification (or
   cleanup) is in progress via a sleep(), $hiber/$wake or any other
   non-spinning method.  (Standard application-named locks could also be
   used to control and coordinate write-modification and section recovery
   access -- any of these options can involve creating a designated cleanup
   process, or these can be implemented as a distrubuted cleanup.)

   If you use queues and a robust design for manipulating the shared memory
   area, you may be able to code a routine that recovers most or all of an
   in-progress transaction.

   You _will_ want to centralize and consolidate _all_ code that handles
   section interlocking, section-private data structure access, and section
   initialization and recovery in one place -- I'd use a shareable image for
   this purpose.  I would _not_ use objects or an object library for this
   code, and I _would_ make sure I used both application-specific version
   numbering and version checks, and I would use the appropriate SMP-capable
   bitlock or lock manager interlocking.

================================================================================
Note 1786.5          how to force cleanup on image rundown?              5 of 20
CUJO::SAMPSON                                        19 lines   6-NOV-1995 16:46
                -< hmmm... kind of like a database recovery... >-
--------------------------------------------------------------------------------
	Steve,

	That's a good point.  Now I have to figure out how best to maintain
a system-wide list of mapper information for each section, which can be
searched for missing processes each time anyone maps or unmaps the section.
I have to do this in a way that meets the design criteria for my routines:

(1) Do not modify VMS or rely heavily on undocumented interfaces;

(2) Provide PFNMAP sections in a semi-transparent manner,
    with behavior like that of the system services themselves;

(3) For each section, the routines should synchronize allocation, clear
    the contents when created, and delete and deallocate when unmapped.
    Otherwise, the user applications completely determine the internal
    structure and contents of each section, and provide their own methods
    to synchronize access.

						Bob Sampson
================================================================================
Note 1786.6          how to force cleanup on image rundown?              6 of 20
XDELTA::HOFFMAN "Steve; VMS Engineering"             57 lines   7-NOV-1995 11:00
                         -< You NEED A Memory Manager >-
--------------------------------------------------------------------------------

:	That's a good point.  Now I have to figure out how best to maintain
:a system-wide list of mapper information for each section, which can be
:searched for missing processes each time anyone maps or unmaps the section.
:I have to do this in a way that meets the design criteria for my routines:

:(1) Do not modify VMS or rely heavily on undocumented interfaces;

   Save for the no-backing-storage section stuff you have already created,
   what I have mentioned makes use only of documented interfaces -- since
   this is HACKERS, I didn't go into details.

   Further, if you don't tie these interlocked routines tightly into the
   no-backing-store-section code you have written, you can reuse these same
   routines when/if OpenVMS supports the section-related features you need.
   (Some sort of memory manager is a general requirement of debugging,
   maintaining and manipulating shared memory -- it's not specific to the
   section stuff you have implemented.)

:(3) For each section, the routines should synchronize allocation, clear
:    the contents when created, and delete and deallocate when unmapped.
:    Otherwise, the user applications completely determine the internal
:    structure and contents of each section, and provide their own methods
:    to synchronize access.

   Plain and simple, you have signed up to write (or borrow) a memory
   manager, and this will end up using either the interlocked instructions
   (VAX) or PALcode calls (Alpha) for accessing interlocked bits and
   interlocked queues, and/or the lock manager.

   I've answered questions similar to this various times in various notes
   conferences, and often around C dynamic memory programming and around
   section-based memory management.  (It's always easier to "borrow" one
   of these than it is to write one -- like using the LIB$VM services.)

   Given the releases you plan on using this on, the memory management
   code should be both AST and thread-safe...

   Letting user applications "completely determine the internal structure
   and contents of each section" is doomed to failure or to long-term design
   and debug and upgrade headaches -- the user applications should not have
   any knowledge of the internal memory management structures, but should
   use a shared set of routines -- the applications should concern themselves
   only with reading, writing, locating, and modifying (etc) the data.

   User applications are *notorious* for memory-management related race
   conditions, for incorrectly interlocked memory accesses, and for
   unsynchronized multiple-part updates -- do not allow each application
   and each programmer to try to implement this stuff, because most of
   them _will_ get it wrong the first couple of times, and it'll take
   forever to debug multiple (buggy) memory managers -- in particular,
   race conditions can be a nightmare to track down.  And with central
   and common access routines, you can also create "pool poisoning"
   routines and can easily implement "fenceposts" on each end of the
   application-allocated memory to detect "memory stompers" -- tests to
   detect incorrect application memory references.

================================================================================
Note 1786.7          how to force cleanup on image rundown?              7 of 20
CUJO::SAMPSON                                        42 lines   8-NOV-1995 01:32
                        -< kernel rundown working well >-
--------------------------------------------------------------------------------
	Steve,

	Thanks for the good advice.  I'm not sure how to put it into
practice, though, in this situation.  I haven't been asked to provide
a general-purpose memory manager.  I've been asked to provide jacket
or "lookalike" routines that semi-transparently manage the allocation
and mapping of PFNMAP sections.  The scope of my endeavor *must* be
limited (at least for the present) to accomplishing my assigned task.

	The customer already has working applications ("legacy code",
if you will), which already do their own memory management for the
contents of the sections.  I'm pretty sure they are using a single set
(or library) of routines for shared memory management.  I know that our
DMQ product (Distributed Message Queueing) plays a major role.  I'm
quite sure that improvements are possible, and I may even be called
upon to help with them someday, but not today.

	Progress report: Today I was able to demonstrate that the
IMG$ADD_PRIVILEGED_VECTOR[_ENTRY] facility works as advertised.
I had to code the declared routine as a JSB entry in Macro-32
(on both Alpha and VAX), which in turn calls my kernel rundown routine
written in DEC C.  It works great for making the process deletable,
even when the exit handlers are not executed.

	I also found that the declared exit handler linked lists are still
intact when the kernel image rundown routine is called, so I also plan to
use the information from them to perform the needed cleanup from kernel mode.
I suppose that if the exit handlers are allowed to execute, they will
execute after the kernel rundown routine, and the cleanup it has already
done does not need to be repeated by the exit handlers.  If the PCB$L_STS
NODELET bit is cleared, the exit handler routine can return without
re-attempting the cleanup work.

	This approach appears to be fairly bulletproof, even though I'm
still relying on image rundown (and using an undocumented interface) to
get the cleanup work done.  I think the principles you've outlined are
generally quite sound, and I've been learning from them.  Right now,
though, I think it's best to provide this "quick-and-dirty" interim
solution, using the simplest methods I can implement at the moment.

						Thanks,
						Bob Sampson
================================================================================
Note 1786.8          how to force cleanup on image rundown?              8 of 20
AUSSIE::GARSON "achtentachtig kacheltjes"            10 lines   8-NOV-1995 02:33
--------------------------------------------------------------------------------
    re .7
    
    What access mode exit handler?
    
    I would have thought that by the time image rundown occurs the user
    mode exit handler would have been removed from the list and been run
    unless it were bypassed by e.g. $ STOP. In any case it would not be
    secure to invoke a user mode exit handler from kernel mode - and if you
    have the run down handler working properly I would forget about exit
    handlers.
================================================================================
Note 1786.9          how to force cleanup on image rundown?              9 of 20
CUJO::SAMPSON                                        47 lines  11-NOV-1995 01:22
             -< if it were simple, it wouldn't be a hack, right? >-
--------------------------------------------------------------------------------
> What access mode exit handler?

	They are declared in user mode primarily, although for some reason
I try to generalize these routines and exit handlers to be useable in three
access modes: user, super, and exec.

> I would have thought that by the time image rundown occurs the user
> mode exit handler would have been removed from the list and been run
> unless it were bypassed by e.g. $ STOP.

	That's my whole purpose in declaring the kernel image rundown handler:
to perform cleanup in the cases where the exit handlers are bypassed.  I was
surprised to find out that the linked lists of declared exit handlers are
still intact when the kernel image rundown runs and the (user-mode) exit
handlers were bypassed.

> In any case it would not be secure to invoke a user mode exit handler
> from kernel mode - and if you have the run down handler working properly
> I would forget about exit handlers.

	I've rewritten the cleanup code to avoid doing any I/O.  This makes
it difficult to debug (especially from kernel mode), and I'm now having to
find out what's causing a halt/restart on Alpha 2100 systems when the
cleanup code runs in kernel mode after issuing a DCL STOP command.  My
suspicion is that my plan simply can't cope with massive deletion of P0/P1
outer-mode address space that is initiated by the STOP command.

	The exit handlers themselves do not run from kernel mode.
Instead, the information from the declared exit handler linked lists
is used to perform the cleanup tasks they would have done.

	I don't think I can forget about using exit handlers, because they
need to be there; not only to specify the cleanup that needs to be done,
but also to actually perform the cleanup during a normal image exit.  After
a normal image exit takes place, the linked list of (user-mode) declared
exit handlers is empty, so the kernel image rundown routine has nothing
much to do.

	So, either the exit handlers or kernel image rundown routine
perform the cleanup (depending on the situation), but not both.

	Okay, okay, the complexity seems to be increasing, and maybe it's
time to heed some of Steve's advice...  I haven't even discussed here how
much grief the debugger quit command is giving me!

							Thanks,
							Bob Sampson
================================================================================
Note 1786.10         how to force cleanup on image rundown?             10 of 20
AUSSIE::GARSON "achtentachtig kacheltjes"             9 lines  12-NOV-1995 16:21
--------------------------------------------------------------------------------
    re .9
    
    My suggestion would be to let the kernel rundown handle cleanup always.
    Don't even declare an exit handler. In the case of normal exit the
    image rundown still occurs.
    
    It is not secure for the kernel rundown handler to check the list of
    user mode exit handlers because that is user writeable i.e. unless you
    have complete control over the image.
================================================================================
Note 1786.11         how to force cleanup on image rundown?             11 of 20
CUJO::SAMPSON                                        13 lines  12-NOV-1995 18:57
                              -< that's right on >-
--------------------------------------------------------------------------------
	re .-1:

	Thank you.  Both of your suggestions are good ones.  I'll create my
own protected linked list for later use by the kernel image rundown routine.
Let's see, is it possible to allocate heap storage from kernel mode?  How
would I do this in a reasonably modular and re-entrant manner?

	I don't have complete control over the image, so you're right, it
isn't secure to check the user-mode exit handlers.  The user would have to
make an effort to spoof the handler, but it could certainly be done.

							Thanks,
							Bob Sampson
================================================================================
Note 1786.12         how to force cleanup on image rundown?             12 of 20
AUSSIE::GARSON "achtentachtig kacheltjes"             8 lines  12-NOV-1995 20:21
--------------------------------------------------------------------------------
    re .11
    
    Heap in the normal meaning of LIB$GET_VM or NEW or malloc() or whatever
    is a no-no in kernel mode. If you really need allocation to be dynamic
    then you can just allocate from pool. I would tend to avoid this unless
    absolutely necessary e.g. ensure that all cleanup code is called and
    ensure that the code can tell whether anything actually needs to be
    cleaned up. Why do you need a linked list?
================================================================================
Note 1786.13         how to force cleanup on image rundown?             13 of 20
CUJO::SAMPSON                                        10 lines  12-NOV-1995 22:22
                    -< anything that works is fine with me >-
--------------------------------------------------------------------------------
	re .-1:

	Not sure whether I really do need a linked list; I need to maintain
a list of indeterminate length, specifying section mapping information for
cleanup.  The actual mapped pages get cleaned up automatically, but I'm
wanting to maintain my section allocation bookkeeping, so that the routines
can know when it is appropriate to deallocate page frame storage.

							Thanks,
							Bob Sampson
================================================================================
Note 1786.14         how to force cleanup on image rundown?             14 of 20
XDELTA::HOFFMAN "Steve; VMS Engineering"             31 lines  13-NOV-1995 08:52
             -< Applications Design Via NOTES While You Wait :-) >-
--------------------------------------------------------------------------------

>	Not sure whether I really do need a linked list; I need to maintain
>a list of indeterminate length, specifying section mapping information for
>cleanup.  The actual mapped pages get cleaned up automatically, but I'm
>wanting to maintain my section allocation bookkeeping, so that the routines
>can know when it is appropriate to deallocate page frame storage.

   The more you head down this path, the more it sounds like you should
   use a pseudo device driver as the control point for the global section.

   The pseudo driver provides you with a consistent and documented kernel
   mode structures -- in this case, one or more cloned UCBs -- that can be
   created for each section present in the system.  The UCB allows a place
   where you can store pointers to the section.  The driver provides you
   with a secure and (potentially) non-privileged interface to your kernel
   code, and the driver itself provides you -- via the last-channel-deassign
   mechanism -- a documented and supported way to do your section cleanup.

   A pseudo driver is usually a pretty simple hunk of code (as OpenVMS
   device drivers go :-), and can usually run at IPL 2 with code solely
   in the `FDT' portion of the standard driver template -- there's no need
   for the high-IPL stuff as there is no physical device present.  You can
   use device-specific I/O function codes and modifiers to handle the
   creation, deletion and connection to the sections, and even to handle
   the mapping from the process to the section.  (Once mapped to the global
   section, the process can access the section directly.)

   For an example of a "bookkeepping" pseudo device driver, see the
   DECwindows WSAn: workstation device.

   (Learning enough about OpenVMS yet?  :-)
================================================================================
Note 1786.15         how to force cleanup on image rundown?             15 of 20
CUJO::SAMPSON                                        26 lines  13-NOV-1995 13:12
                      -< appreciated, but a *driver*?!? >-
--------------------------------------------------------------------------------
	re .-1:

>        <<< Note 1786.14 by XDELTA::HOFFMAN "Steve; VMS Engineering" >>>
>             -< Applications Design Via NOTES While You Wait :-) >-

>   (Learning enough about OpenVMS yet?  :-)

	Yep, I seem to be on the "bleeding edge" of software technology :-).
This task is taxing my skills and patience, and I thank you for your help.

	Steve, are you possibly hinting that OpenVMS itself may take a
similar tack (use of a pseudo-device driver) in the future, whether for
global sections, or for something new and different?

	If so, I can see a possible advantage to providing this kind of
user interface, but I still remain unconvinced of this being the proper
time for me to launch into it.

	All I really need right now is a process-specific protected list of
indeterminate length, with each list entry having only enough storage to
contain the section name, section type (system or group global or process
private), mapped process address range and access mode.  This seems (to me
at least) easier to concoct than a device driver.

							Thanks,
							Bob Sampson
================================================================================
Note 1786.16         how to force cleanup on image rundown?             16 of 20
XDELTA::HOFFMAN "Steve; VMS Engineering"             41 lines  13-NOV-1995 17:24
                  -< Pseudo Device Drivers and UWSS Modules >-
--------------------------------------------------------------------------------

>	Steve, are you possibly hinting that OpenVMS itself may take a
>similar tack (use of a pseudo-device driver) in the future, whether for
>global sections, or for something new and different?

   No, I'm pointing at a technique that provides you with a "free"
   interface into kernel mode, and "free" storage in kernel mode,
   and a "free" argument verifcation interface.  And at a technique
   that has been used before for similar "storage" purposes.

   I'm assuming that this same hunk of kernel code -- the code used to
   create and coordinate access to the section, as well as handling
   the run-down -- will be "disposed of" when the "no backing storage
   global section" code is added into in OpenVMS.

>	If so, I can see a possible advantage to providing this kind of
>user interface, but I still remain unconvinced of this being the proper
>time for me to launch into it.

   You know your schedule best.

>	All I really need right now is a process-specific protected list of
>indeterminate length, with each list entry having only enough storage to
>contain the section name, section type (system or group global or process
>private), mapped process address range and access mode.  This seems (to me
>at least) easier to concoct than a device driver.

   You're right. 

   But you'll need to concoct a way into kernel mode and may not want
   to give out CMKRNL to do it, how to allocate and track the necessary
   kernel data storage structures, how to protect the code from accidental
   or nefarious bogus argument specifications, how to get the code into
   kernel, how to use IPL-based or spinlock based interlocks, and how to
   automatically clean up when a process disconnects under various normal
   and unusual circumstances -- and this looks like the basic pieces of
   just about any device driver I've ever written.  (I've found a pseudo
   device driver equal to or better than the typical UWSS construct.)

   Just think what your resume will look like when you finish.  :-)

================================================================================
Note 1786.17         how to force cleanup on image rundown?             17 of 20
HDLITE::NEWMAN "Chuck Newman, 508/467-5499 (DTN 297" 13 lines  15-NOV-1995 09:59
              -< How I debugged my execlet from elevated mode... >-
--------------------------------------------------------------------------------
re: .9
	I've rewritten the cleanup code to avoid doing any I/O.  This makes
it difficult to debug (especially from kernel mode), and I'm now having to
find out what's causing a halt/restart on Alpha 2100 systems when the
cleanup code runs in kernel mode after issuing a DCL STOP command.  My

I've used SCH$QAST to queue an AST to another process to do debugging I/O.  I used
space in my execlet to store the string to write out.

Either that or push stuff on the stack and suspend yourself.  Restart the process
from another process after checking what you've shoved on the stack.

								-- Chuck Newman
================================================================================
Note 1786.18         how to force cleanup on image rundown?             18 of 20
EVMS::HALLYB "Fish have no concept of fire"           5 lines  16-NOV-1995 14:37
                      -< Even simpler, where applicable >-
--------------------------------------------------------------------------------
    If you're at the console you can call EXE$OUTZSTRING and EXE$OUTHEX
    with the argument in R1, and EXE$OUTCRLF with no arguments. I often
    use these to trace execution state.
    
      John
================================================================================
Note 1786.19         how to force cleanup on image rundown?             19 of 20
ZIMBRA::BERNARDO "David M. Bernardo, VMS Engineering" 5 lines  16-NOV-1995 19:27
--------------------------------------------------------------------------------
    Be careful of these routines, at least on Alpha to use them you must be
    at or above the console IPL, and if on an SMP system, running on the
    primary CPU.
    
    d.
================================================================================
Note 1786.20         how to force cleanup on image rundown?             20 of 20
CUJO::SAMPSON                                         4 lines  17-NOV-1995 09:25
                           -< moot for me right now >-
--------------------------------------------------------------------------------
	Thanks for the last few replies.  This is good information for
future reference.  In my particular problem at hand, I've abandoned trying
to do cleanup at rundown from kernel mode, in favor of some suggestions
that Steve has been making.
