[comp.sys.amiga] I Want my ZombieMsg Back!!!

G@epsilon.stacken.kth.se (Gunnar Nordmark) (06/22/88)

Last night I rebooted my machine X times and couldn't figure out what was
wrong with my program, it just hang.  After many hours I located the problem
to a WaitPort() on a so called ZombieMsg that the ARP ASyncRun is supposed to
return when the child process dies. I have set up the message with a reply
port and put a pointer to it in pcb_LastGasp :-) but ASyncRun just ignores it.

I need this message BADLY because I've implented the UNIX* functions
popen() and pclose() - the death message generates a software interrupt when
it arrives at the replyport - then the interrupt handler breakes the pipe -
and finally the function pclose() can return. (It should not return until
the child is terminated)

The mecanism works great if I PutMsg() the ZombieMsg directly to the replyport
*instead* of calling ASyncRun(), so the ONLY thing I need for this functions
to fly is ASyncRun() actually returning my message, but alas, it doesn't.

(1, 2 3...)  HEEEEELLP!!!

SNAIL: Gunnar Nordmark          VOICE: (+46) 8 - 755 42 52
       Nora strand 5
       S-182 34 DANDERYD        EMAIL: G@epsilon.stacken.kth.se
       SWEDEN                          nordmark@vaxkab.sunet.se

drs-ano@duvan.nada.kth.se (Gunnar Nordmark) (06/23/88)

In article <421@draken.nada.kth.se> G@epsilon.stacken.kth.se (Gunnar Nordmark) writes:
>Last night I rebooted my machine X times and couldn't figure out what was
>wrong with my program, it just hang.  After many hours I located the problem
>to a WaitPort() on a so called ZombieMsg that the ARP ASyncRun is supposed to
>return when the child process dies. I have set up the message with a reply
>port and put a pointer to it in pcb_LastGasp :-) but ASyncRun just ignores it.

The problem is solved.
There is a *SERIOUS* bug in the header file arpbase.h (1.1 REL2) that I
received from comp.sys.amiga a while ago - the structure definition for
ProcessControlBlock is garbled. I discovered this when I compared the
C-header with the assembler version, they didn't match:

---------  this is from arpbase.h  ----------

struct ProcessControlBlock {
	ULONG	pcb_StackSize;		/* Stacksize for new process */
	BYTE	pcb_Pri;		/* Priority of new task */
	BYTE	pcb_Control;		/* Control bits, see defines below */
	APTR	pcb_TrapCode;		/* Optional Trap Code */
	ULONG	pcb_Input,p_Output;	/* Optional stdin, stdout */
	union {
		ULONG	pcb_SplatFile;	/* File to use for Open("*") */
		BYTE	*pcb_ConName;	/* CON: filename */
	} pcb_Console;
	ULONG	pcb_SplatFile;		/* File to use for Open("*") */
	CPTR	pcb_LoadedCode; 	/* If not null, will not load/unload code */
	struct ZombieMsg *pcb_LastGasp;	 /* ReplyMsg() to be filled in by exit */
	struct MsgPort	*pcb_WBProcess;	/* Valid only when PRB_NOCLI */
};


---------  and now look at arpbase.i  ----------

	STRUCTURE ProcessControlBlock,0
		ULONG	pcb_StackSize	; Stacksize for new process
		BYTE	pcb_Pri		; Priority of new process 
		BYTE	pcb_Control	; Control bits, see BITDEF's below.
		APTR	pcb_TrapCode	; Optional trapcode vector
		ULONG	pcb_Input	; Optional default input
		ULONG	pcb_Output	; Optional default output
		UNION	pcb_Console,4
		    UMEMB pcb_Splatfile ; file to use for Open("*")
		    UMEMB pcb_ConName	; CON: filename 
		ULONG	pcb_LoadedCode	; If not null, use this code
		CPTR	pcb_LastGasp	; ReplyMsg to be filled in by exit code
		CPTR	pcb_WBProcess	; Valid only when PRB_NOCLI.
		LABEL	pcb_Sizeof

---------------------

Do you see the difference?  (Well, it's hard not to)
arpbase.h has two (!) pcb_Splatfile fields. (Guess why my program dived :-)
An other difference is that pcb_Output is defined as p_Output in
the C header. Ok, the latter looks like a transmission error, but the
two pcb_Splatfile fields can't be explained by this.
So I'm afraid that it was a buggy arpbase.h that made it out on the net.

I changed my arpbase.h to conform with arpbase.i, and voila! It worked!

There is nothing wrong with ASyncRun(), it runs like a champ. (Thank God)

SNAIL: Gunnar Nordmark          VOICE: (+46) 8 - 755 42 52
       Nora strand 5
       S-182 34 DANDERYD        EMAIL: G@epsilon.stacken.kth.se
       SWEDEN                          nordmark@vaxkab.sunet.se

drs-ano@duvan.nada.kth.se (Gunnar Nordmark) (06/24/88)

In article <423@draken.nada.kth.se> G@epsilon.stacken.kth.se (Gunnar Nordmark) writes:
>There is nothing wrong with ASyncRun(), it runs like a champ. (Thank God)
                                            ^^^^^^^^^^^^^^^^^

POOF!!  When you beleive in something deeply, it's quite annoying to finally
realize that it was all a dream.  There is a definitive (and deadly) problem
with ASyncRun - here goes:

First you explicitly opens an input and an output file for the new process.
Then you passes them along in the PCB with pcb_Control set to PRF_SAVEIO.
Also you supply a ZombieMsg, so you'll know when the process has completed.
When it has, you close the the filehandl....   [Oh, it's you again!]

The Input file (at least) that you supply is garbled in some way.
You can't use it or close it or do anything with it, it's a one way ticket.
The SAVEIO flag is devoted for this sole purpose, but the only case where
it actually works is when you supply your *own* standard input.
If you open a new standard input for the process you guru severly if
you try to close it when the new process has completed.

Maybe it's a bug in AmigaDOS, I don't know. But I don't appreciate it.
It took me over 12 hours in a row (=no food) to find this bug so now
I have lost about all of my former enthousiasm over ASyncRun.

But that can be changed! Has anyone any suggestions/workarounds for this?

(Uptil now this has been a one man discussion, but the articles will reach
the rest of you RSN :-)

SNAIL: Gunnar Nordmark          VOICE: (+46) 8 - 755 42 52
       Nora strand 5
       S-182 34 DANDERYD        EMAIL: G@epsilon.stacken.kth.se
       SWEDEN                          nordmark@vaxkab.sunet.se

riley@batcomputer.tn.cornell.edu (Daniel S. Riley) (06/25/88)

In article <421@draken.nada.kth.se> G@epsilon.stacken.kth.se (Gunnar Nordmark) writes:
>Last night I rebooted my machine X times and couldn't figure out what was
>wrong with my program, it just hang.  After many hours I located the problem
>to a WaitPort() on a so called ZombieMsg that the ARP ASyncRun is supposed to
>return when the child process dies. I have set up the message with a reply
>port and put a pointer to it in pcb_LastGasp :-) but ASyncRun just ignores it.

Check the C header file ArpBase.h against the assembler ArpBase.i.  I found 
that in my copy of ArpBase.h, struct ProcessControlBlock has an extra 
declaration of ULONG pcb_SplatFile after the union which contains ULONG
pcb_SplatFile.  This offsets pcb_LastGasp by 4 bytes, so ASyncRun can't
find it.  After I deleted the extra declaration, ASyncRun worked fine for
me with a LastGasp port.  Here's what ArpBase.h has:

struct ProcessControlBlock {
	...lots of good stuff...
	union {
		ULONG	pcb_SplatFile;
		BYTE	*pcb_ConName;
	}
	ULONG	pcb_SplatFile;		/* this should not be here */
	CPTR	pcb_LoadedCode;
	struct ZombieMsg *pcb_LastGasp;
	...
};

The only other ASyncRun bug that I've found is in the documentation, which
refers to pcb_Flags;  this field is actually named pcb_Control in the header
files.

I have not reported these to the ARP project yet.  If anyone on the net logs
on to BIX more regularly than I, please report this to Charlet et al.
(Thanks)

-Dan Riley (dsr@crnlns.bitnet, dsr@lns61.tn.cornell.edu)
-Wilson Lab, Cornell U.
-Disclaimer:  New, Improved, Guaranteed 100% content free.