[comp.os.msdos.programmer] Borland TC++ & TD: Debugging applications that contain hardware ISR's

rbono@necis.UUCP ( NM1D) (01/18/91)

Since I spent a bit of time looking for a work-around for this, I thought
that I would share this with others, to same them some headaches....

  I have found that the debugger built into Borland TurboC++ (1.0) is not
very useful for debugging applications that contain a hardware Interrupt Service
Routine (ISR)..  This actually deals with the debugger built into TC++ and
TD (2.0).  I called Borland on this (talked with 'Dave' on the support line).
They told me that I would have to live with this problem as it would require a
major change to fix or provide a work around.

They did state that TD-remote MAY not exhibit this problem, I havn't confirmed
this. 

Problem:  Can't single step, through 'background' code when a hardware interrupt
          service routine is part of the application.  This is because Turbo
          'swaps' the interrupt vectors on each breakpoint or single step.  If
          a hardware interrupt that is supposed to be handled by your
          code occurs when the program is halted, the system may crash or hang
          (unpredictable results).  This is because the interrupt vectors are
          not pointing to the proper ISR at the time of the interrupt.

This is a big problem when trying to use IRQ0 through IRQ7.

There is no currently known work-around (Borland confirmed this).

Occurs in: TC++ 1.0, TC++ 1.01, TD 2.0, TD286, TD386

example:  Design a *simple* terminal emulator.  The terminal emulator contains
          code to handle the I/O to the COM port in an 'interrupt driven'
          fashion (i.e.: when a byte is received on COM1, IRQ4 is driven
          active, the ISR is responsible for placing the byte into a buffer.
          the buffer is read by the background task).

          The simple backgound code might look like this (this is a simplified
          example):

        main(void)
        {
        unsigned char inbyte;
        int key;

          InstallComHandler();    // Install the COM1 Interrupt Service Routine
                                  //  this will take over the vector for IRQ4

          while(1)                         // exit loop with proper keystroke
          {
              if(ComBufferHasData())       // if there is a byte in the buffer
              {
                 inbyte = ReadComBuffer(); // read byte from buffer
                 putch(inbyte);            // display the byte
              }

              if(KeyPress())               // if a key has been pressed
              {
                 key = ReadKey();          // read the key

                 if(key == EXIT)           // if user desires to exit the pgm
                 {
                    RemoveComHandler();    // remove the COM ISR
                    exit(1);               // exit the program
                 } 
                 else
                 {
                    OutputToComPort(key);  // Output keystroke to the COM port
                 }
              }
 
          } 
        }


   If you single step through this code, or set a breakpoint anywhere in this
code and the COM port generates an interrupt, the interrupt will never be
serviced if it occurs when the program is not executing.  This will
most-probably cause the ISR to stop functioning.   This is due to the fact
that the debugger restores the interrupt vectors as they were before the
program was running, each time a breakpoint occurs (and during single stepping).
 
  You can place one breakpoint into your code and follow execution from that
point.  But if another interrupt occurs during your single stepping, or during
the time the Debugger has control, your application may never 'see' the
interrupt or may hang or crash the system.

  This 'feature' of the debugger is explained in a paragraph
in the Turbo Debugger manual.  It states that the debugger maintains three
sets of interrupt vectors (vectors 00 - 0x2F).  The first copy is made before
the debugger is started. This set is restored when exiting back to DOS and
when shelling out to DOS.  The second set is the Debugger's own copy of the
vectors.  THESE ARE IN EFFECT WHENEVER THE DEBUGGER IS RUNNING OR ON THE SCREEN
(emphasis is mine).  The third set is those of the program that you are
debugging.  These vectors are RESTORED EVERY TIME YOU RUN OR STEP your program,
and are saved each time you stop your program (by single stepping, or break-
point).

 The problem is that when debugging applications that make use of external
hardware interrupts, the debugger actually 'gets in the way' and will not
allow these interrupts to be serviced by your ISR (Interrupt Service Routine).

 I have found NO WORKAROUND for this.  If anyone does, please let me know.
This makes the Borland package almost useless (in my opinion) for debugging
software that makes use of hardware interrupts (i.e.: IRQ0-IRQ7). 

This should not affect software that makes use of software interrupts 
(INT X instructions).

 It would be nice if Borland provided an option that allowed a specified vector
(or vectors) to remain in place during the debugging of an application.  They
could then restore the vectors when exiting the debugger or shelling out to DOS.

  I thought that since this consumed a day of my time looking for a workaround,
that I would let other know about this limitation.  If someone does have
a workaround.  Please inform me.

 This occured with TC++ 1.0 (I assume with 1.01 also) and with TD 2.0 (includes
TD386 and TD286).

--
 /**************************************************************************\
 * Rich Bono (NM1D)      Note NEW email address:     rbono@necis.ma.nec.com * 
 * (508) 635-6300          NEC Technologies Inc.                NM1D@WB1DSW * 
 \**************************************************************************/

-- 
 /**************************************************************************\
 * Rich Bono (NM1D)      Note NEW email address:     rbono@necis.ma.nec.com * 
 * (508) 635-6300          NEC Technologies Inc.                NM1D@WB1DSW * 
 \**************************************************************************/

williams@umaxc.weeg.uiowa.edu (Kent Williams) (01/19/91)

EVEN WORSE.  I have a VIP 386SX system, and a microsoft serial mouse on COM1.
When I use td386, the mouse works fine in the debugger.  If I move the mouse
while my application is running, I get popped back into TD with an exception
6 error (Invalid opcode)


--
             Kent Williams --- williams@umaxc.weeg.uiowa.edu 
"'Is this heaven?' --- 'No, this is Iowa'" - from the movie "Field of Dreams"
"This isn't heaven, ... this is Cleveland" - Harry Allard, in "The Stupids Die"