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