[comp.sys.ibm.pc] MSC signal

colin@vu-vlsi.UUCP (Colin Kelley) (01/10/87)

I'm having trouble with a ^C handler using MSC 4.0 and PC-DOS 3.1.  I have
signal(SIGINT, interrupt); to call my routine interrupt() when ^C is pressed.
This works as expected, but sometimes bombs out with a stack overflow.
After further inspection with CodeView, it appears that SS register is always
left pointing at the DOS stack after a ^C rather than being restored to point
at the program's stack segment; since _chkstk() only looks at SP (not SS),
the stack check will sometimes succeed and sometimes fail.  However, the
program seems destined to fail if it continues to use the DOS stack rather
than its own!

One cheap work-around is to compile with the /Gs option to inhibit stack
overflow checks, but that's obviously not acceptable--it's just treating the
symptom, not the disease.

I recall reading somewhere on the net that the authors of Procomm experienced
the same or a similar problem, but I didn't see a solution posted...

Oh yeah, and while I'm at it, I think I've found a certain lack of
functionality in MSC's implementation of malloc() and free().  When testing my
program with CodeView, I only have about 32K of heap free.  The program
malloc()'s as many fixed-size chunks as it can, which turns out to be only 5
chunks.  This correctly uses up all 32K.  But then, if I free() all that
memory and try to malloc() it again, using the same size chunks, MSC only
succeeds in allocating 2 or 3 chunks before it reports that all memory has
been used.  This indicates that MSC's free() isn't doing a good job of merging
free()'d memory.  I experience the same trouble whether the chunks are
free()'d in the order they were malloc()'d or in the opposite order. 

Anyone got any suggestions/solutions for either problem?  Thanks!

	-Colin Kelley  ..{cbmvax,pyrnj,psuvax1,bpa}!vu-vlsi!colin

backman@interlan.UUCP (Larry Backman) (01/12/87)

In article <558@vu-vlsi.UUCP> colin@vu-vlsi.UUCP (Colin Kelley) writes:
>I'm having trouble with a ^C handler using MSC 4.0 and PC-DOS 3.1.  I have
>signal(SIGINT, interrupt); to call my routine interrupt() when ^C is pressed.
>This works as expected, but sometimes bombs out with a stack overflow.
>After further inspection with CodeView, it appears that SS register is always
>left pointing at the DOS stack after a ^C rather than being restored to point
>at the program's stack segment; since _chkstk() only looks at SP (not SS),
>the stack check will sometimes succeed and sometimes fail.  However, the
>program seems destined to fail if it continues to use the DOS stack rather
>than its own!
>

	The reason you are getting DOS's stack is that you are trapping an
	interrupt!  When ^C is hit, the SIGINT function will call your routine
	as an interrupt handler .  It is your responsibility  as an interrupt
	routine to set up your environment correctly.  I had the same problem
	writing a series of NETBIOS POST routines; I solved it by a thin 
	assembly interface that restored SS:SP back into my environment, and
	then calling C code.  I eventually ended up turning off stack checking
	in a single module that handled NETBIOS  because it was getting in my 
	way as well as slowing down my code.  I did however leave stack checking
	on in the other modules that were part of the program.

	I am curious about your problems with free and malloc.  I am using them
	very heavily and have not seen problems with them.  Could you provide
	a code fragment?

					Larry Backman
					Micom - Interlan, Inc.
					155 Swanson Rd.
					Boxborough, Ma. 01719
					617-263-9929 x291

					ulowell!
					mit-eddie!        interlan!backman
					ihnp4!	

djfiander@watnot.UUCP (01/13/87)

>>I'm having trouble with a ^C handler using MSC 4.0 and PC-DOS 3.1.  I have
>>signal(SIGINT, interrupt); to call my routine interrupt() when ^C is pressed.
>>This works as expected, but sometimes bombs out with a stack overflow.
>
>	The reason you are getting DOS's stack is that you are trapping an
>	interrupt!  When ^C is hit, the SIGINT function will call your routine
>	as an interrupt handler .  It is your responsibility  as an interrupt
>	routine to set up your environment correctly.
>

I don't think very much of the idea that a system routine that was obviously
designed to call a C routine (otherwise just set up the INT vector yourself)
doesn't set the stack pointer to the required data segment.  The
interrupt() function is _not_ an interrupt function.  The signal() function
sets the SIGINT vector to point to a hidden bit of code in the library which
calls interrupt().  I don't know this for a fact, but it seems reasonable, 
since the description of signal() in the msc documentation says that the 
interrupt vector is reset to the default after each call to the user routine.

-David J. Fiander (watmath!watnot!djfiander)
"What now Boss?"

colin@vu-vlsi.UUCP (Colin Kelley) (01/21/87)

In article <117@interlan.UUCP> backman@interlan.UUCP (1014-Larry Backman) writes:
>> [my query about MSC signal not restoring SS:SP]
>
>	The reason you are getting DOS's stack is that you are trapping an
>	interrupt!  When ^C is hit, the SIGINT function will call your routine
>	as an interrupt handler .  It is your responsibility  as an interrupt
>	routine to set up your environment correctly.

Remember, I didn't take over an interrupt--I just called signal() to have
it done for me.  If MS-DOS requires that SS:SP be restored, then signal()
should set up some code to do this before calling my code.

Anyway, several other people acknowledged via mail that this is an MSC 4.0
bug (actually, MSC didn't change; it's just that it should have once MS-DOS
3.x decided to use its own stack).  The work-around is a very simple
assembly-language interface routine which first restores SS:SP, then jumps
into the real C code.  I'll be happy to e-mail you this code if you need it.

>	I am curious about your problems with free and malloc.  I am using them
>	very heavily and have not seen problems with them.  Could you provide
>	a code fragment?

I wrote such a code fragment, and was surprised to find that it didn't
exhibit the problem.  So I went back to the big program (which did exhibit
the problem) and set a breakpoint at the start of malloc() using CodeView.
It turns out that some long-forgotten routine was malloc()ing a few bytes
now and then but never freeing them.  I fixed this code and memory allocation
now works as expected (almost--see #2 below).  Sorry for crying wolf...

While I'm at it, I might as well throw out two other small MSC problems:

1. _fmalloc() and _ffree() are provided (they allow malloc()ing and free()ing
far pointers in program compiled with small data).  What about _frealloc()?
It isn't documented, but I tried calling it anyway.  It isn't there.  Was
this just an oversight at Microsoft, or is there a reason?

2. Memory which has been malloc()ed and then later free()d is never returned
to MS-DOS; hence any attempt to spawn() or otherwise run another program
may fail due to lack of memory, even if all of that memory has been free()d.
I remember seeing in the Lattice 3.10 manual that their compiler now took
care of this.  Any solutions or work-arounds for MSC 4.0?

	-Colin Kelley  ..{cbmvax,pyrnj,psuvax1,bpa}!vu-vlsi!colin