Date: Tue, 28 Mar 1995 11:04:44 EST From: THE MASKED PROGRAMMER To: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: Interrupt debugs (forward) From: MX%"ldoan1 AT osf1 DOT gmu DOT edu" 27-MAR-1995 18:34:06.45 To: MX%"badcoe AT bsa DOT bristol DOT ac DOT uk" CC: MX%"ldoan1 AT osf1 DOT gmu DOT edu",MX%"ld AT netrix DOT com" Subj: Re: How to debug after playing with timer-int ? Return-Path: Received: from dira.bris.ac.uk by BSA.bris.ac.uk (MX V4.1 AXP) with SMTP; Mon, 27 Mar 1995 18:34:05 EST Received: from osf1.gmu.edu by dira.bris.ac.uk with SMTP (PP); Mon, 27 Mar 1995 19:28:57 +0100 Received: by osf1.gmu.edu; (5.65/1.1.8.2/07Sep94-1001AM/GMUv1) id AA22973; Mon, 27 Mar 1995 13:28:47 -0500 Date: Mon, 27 Mar 1995 13:28:46 -0500 (EST) From: Long Doan To: THE MASKED PROGRAMMER CC: Long Doan , ld AT netrix DOT com Subject: Re: How to debug after playing with timer-int ? In-Reply-To: <0098DFB0 DOT F05C6628 DOT 1 AT bsa DOT bristol DOT ac DOT uk> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII On Mon, 27 Mar 1995, THE MASKED PROGRAMMER wrote: > Hi, > Badders here again. Hi! It's me again... I'll try to answer your questions point by point. > (1) I've been told that a redirected int0x8 will crash if it occurs during an You should NEVER call an interrupt inside your handler because: 1. Some interrupt handler do a STI, resulting in multiple interrupts. 2. Your interrupt routine's stack is rather small, calling a lot of functions/interrupts/mode switchs is likely to cause a crash (stack overflow -> Segment violation.) 3. Calling an software interrupt is likely to cause a mode switch (I assume that a SW interrupt is used for calling DOS, BIOS, etc.) which takes up a whole lot of CPU cycles, and might results in too many pending interrupts. So only call them when absolutely necessary (i.e. call the old handler.) > int0x16. Aren't interrupts disabled during interrupt handling ? (I have > the impression that HW ones are but SW one are not, can I disable SW ones ? SW interrupts are NOT really interrupts, so they cannot be masked. When a CLI instruction is executed, it only tell the PIC to stop making all those interrupt requests. > (2) Which djgpp activities use int0x16 ? My current guess is: > > printf/puts/getchar/getkey ... > File I/O > > But are there any 'less obvious' ones (memory allocation ? paging ?) In a interrupt handler, you should only do: 1. Modify your current stack. 2. Use data in your CS segment. (DS is not what the normal DS of your program under DPMI, so you WILL cause a segmentation violation if you do any referencing to variable without setup a proper DS. For more information regarding this, look up serial.c in Ladybug v. 1.02 (ldbg102.zip) The program actually writes the value of its DS into its interrupt handler.) 3. Do CPU level IO (inb, outb, inw, outw, inl, outl, ...) > (3) Does anybody have any general advise for how to debug a program involving > interrupt routines. I sometimes try to use edebug (is that what its > called ?) and sometimes it behaves reasonably and sometimes the machine > hangs even before reaching points I know it reaches otherwise. Try to use Ladybug (I use it to debug programs with timer interrupt all the time. Note: 1. Always set breakpoint AFTER ACK instructions (outportb (0x20, 0x20), outportb (0xa0, 0x20)) or instructions that call the previous handler. 2. If you uses the profiling (Performance Analyzer) feature, make sure that you timer has been installed BEFORE turning Ladybug's timer on. > I guess that edebug isn't really intended to handle this sort of thing ? > (I did really expect it to.) Is their some other way of doing it (given > that I can't really put prints everywhere 'cos they cause crashes ...) Yep, use Ladybug (This starts to sound like a commercial... :-)) > (4) Last night I advanced the program to the point where it was able to print > error messages (instead of just hanging the system or printing: > > "UnspUnspUnsp ...." > > all over the screen and I got the message: > > "Internal Stack Exhausted > system halted" You're having interrupts over interrupts, see above. > My guess is that this is a system error (or rather a processor exception ?) > caused by my _go32_dpmi_simulate_fcall_iret to the old int0x8 handler > running out of stack-space (I just gave it the default). This morning I > tried using _go32_dpmi_allocate_dos_memory() to get a buffer (512 bytes) for > use as a local stack and the program crashed with an "Unsuported int0x0" > but I didn't yet check that the allocation had succeded (how would I do > that anyway, the info page is slightly ambiguous ...) Hmm... It sounds like you're doing A LOT in a interrupt handler, you might wants to use the Real Time Clock interrupt (0x70) instead of the Time Of Day interrupt (0x08). For more details, search for a message from Hung Bui (hvb.netrix.com) regarding the matter. On the other hand, the problem might just be in the go32_simulate_... () calls. If so, look up the code in perform.c of Ladybug 1.02. I simplified the calls to a couple moves and a intx86 () call. Also note that I creates two seperate handler for the real and protected mode interrupts. This allows me to do without the wrappers, which helped me got rid of similar error messages. > (5) I often get "Unsupported int 0xz" (where "z" is a number). I guess that > this is not a direct error, but is more likely to be due to some data > getting corrupted and used to generate an interrupt ? That sounds like your handler has done something funny to the stack (i.e. pop too many or too little parameters) resulting in a screwed up stack. When other interrupts come in/returns, strange things happens. > Some times I get (as above) a screen-full of "UnspUnspUnsp" which I guess > is due to the above occuring inside the int0x8 handler (and consequently > the next error occurs *before* its printing the last one). Percicely. > (6) What does it mean when I get two error dumps in a row, particularly when > they have different selectors. Can edebug display instructions from other > that my_cs() ? Same as above, except that the fault(s) is in go32's stack, so go_till_stop (), main (), ... (I'm talking about go32 here) start to return to the wrong location. Or, the function in _atexit () is called twice due to a stack error. If you see that this message is helpful, please post it to the list, someone else might want it. If you have more questions, please sends them directly to me (at both address in my .sig, below.) If your program still doesn't work, send me a copy and I'll try to help. +--------------------------------------------------------+ | Long Doan ldoan1 AT osf1 DOT gmu DOT edu | | ld AT netrix DOT com | +--------------------------------------------------------+