From: leichter@lrw.com (Jerry Leichter)
Newsgroups: comp.os.vms
Subject: re: Need help with UNASEFC
Date: 9 Sep 92 16:30:42 GMT
Distribution: world
Organization: The Internet


	I have a very simple client-server pair of programs with a bizarre
	bug.

	The server reads a big file into memory, listens for queries on a
	mailbox (using SYS$QIOW), and responds by writing back to the client's
	mailbox.

	The client sends queries to the server's mailbox and reads the
	reponses back on its own mailbox (again, using SYS$QIOW).

	Everything works great.  I modified the server to use SYS$CRMPSC to
	map the big file into memory rather than reading it all in at the
	beginning.  I've stepped through with the debugger, and everything
	works as expected.  All system service return values come back with
	SUCCESS.

	However, the client (which has not been changed) often chokes and dies
	when it tries to read the response.  The QIOW status is UNASEFC
	(unassociated event flag cluster), but the IOSB status is SUCCESS and
	the transfer count is correct.  It seems to happen only when the
	server has to touch one of the mapped pages for the first time.  If
	the client is run again immediately with the same query, the response
	comes back just fine.

	Neither program relies on event flags since they're using QIO rather
	than QIOW, so they both specify 0 as the event flag number.  Thus they
	aren't even trying to use event flags in a common event flag cluster
	(there are no other references to event flags in either program).

It's impossible to tell for sure, but I'll make a guess:  Check your SYS$QIOW
call and make sure you are passing it by value, NOT by reference.  Since so
many values in VMS are passed by reference, it's easy to get this wrong and
use &0 instead of just 0.  The result would be pretty much what you see:  VMS
only uses the low order byte of the value passed to determine the event flag
number; it ignores the extra high-order bits.  If you pass an address, you are
really specifying some arbitrary event flag.  If it happens to be in cluster 2
or 3 (50% chance), the common event flag range, UNASEFC is the likely result.
The other half of the time, some random local event flag gets used, and
eventually set when the operation completes.  In most cases, this will have
no visible effects on the program.  Note that an argument like &0 is likely
to be passed as the address of a zero pushes onto the stack, so that even
multiple calls from the same line of code may produce different effects at
run time.  Totally unconnected changes to the path the code follows could
change the address passed.

BTW, a failure status from the QIO[W] call itself means that the error was
detected before the I/O was ever started.  Any later problems are reported in
the IOSB status field.  The success status and correct length you are seeing
in the IOSB are left over from the last successful use of the IOSB - SYS$QIO
won't clear the IOSB unless it can successfully queue the request.

	Just to add more confusion, when the client program sees the
	non-success status returned from QIOW, it calls exit() (VAX C RTL)
	with that status.  The client then dies with an access violation
	inside exit().  When running with the debugger, things get really
	hosed up, and I get all these messages about internal DEBUG coding
	errors.

This sounds as if you are writing garbage into the stack, perhaps in error
recovery code that had previously never been exercised.

	Any clues out there?  (VMS V5.5, VAX C V3.2)

							-- Jerry