home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sherlock.zip / EXCEPT.C < prev    next >
C/C++ Source or Header  |  1994-06-29  |  7KB  |  249 lines

  1. /*
  2. **  Sherlock - Copyright 1992, 1993, 1994
  3. **    Harfmann Software
  4. **    Compuserve: 73147,213
  5. **    All rights reserved
  6. */
  7. /*
  8. **  Handle an exeption from the debuggee.
  9. */
  10. #include    <stdlib.h>
  11. #include    <stdio.h>
  12. #define     INCL_DOSSESMGR
  13. #define     INCL_DOSPROCESS
  14. #define     INCL_DOSEXCEPTIONS
  15. #include    <os2.h>
  16. #include    <sys\stat.h>
  17. #include    "debug.h"
  18.  
  19. #include    "Debugger.h"
  20. #include    "SrcInter.h"
  21. #include    "Source.h"
  22. #include    "Except.h"
  23. #include    "BrkPoint.h"
  24.  
  25. ULONG   ExecptionNumber;
  26.  
  27. /*
  28. ** Get an ASCII equivalent of the exection's name.
  29. */
  30. static char *findExceptionName(ULONG exceptionNum)
  31. {
  32.     switch(exceptionNum) {
  33.  
  34.         /*
  35.         ** Portable Non-Fatal Software-Generated Exceptions
  36.         */
  37.         case XCPT_GUARD_PAGE_VIOLATION:
  38.             return "Guard Page violation";
  39.  
  40.         /*
  41.         ** Portable Fatal Hardware-Generated Exceptions
  42.         */
  43.         case XCPT_ACCESS_VIOLATION:
  44.             return "Access violation";
  45.         case XCPT_INTEGER_DIVIDE_BY_ZERO:
  46.             return "Integer divide by zero";
  47.         case XCPT_FLOAT_DIVIDE_BY_ZERO:
  48.             return "Float divide by zero";
  49.         case XCPT_FLOAT_INVALID_OPERATION:
  50.             return "Float invalid operation";
  51.         case XCPT_ILLEGAL_INSTRUCTION:
  52.             return "Illegal instruction";
  53.         case XCPT_PRIVILEGED_INSTRUCTION:
  54.             return "Privileged instruction";
  55.         case XCPT_INTEGER_OVERFLOW:
  56.             return "Integer overflow";
  57.         case XCPT_FLOAT_OVERFLOW:
  58.             return "Float overflow";
  59.         case XCPT_FLOAT_UNDERFLOW:
  60.             return "Float underflow";
  61.         case XCPT_FLOAT_DENORMAL_OPERAND:
  62.             return "Float denormal operand";
  63.         case XCPT_FLOAT_INEXACT_RESULT:
  64.             return "Float inexact result";
  65.         case XCPT_FLOAT_STACK_CHECK:
  66.             return "Float stack check";
  67.         case XCPT_DATATYPE_MISALIGNMENT:
  68.             return "Datatype misalignment";
  69.         case XCPT_BREAKPOINT:
  70.             return "Breakpoint";
  71.         case XCPT_SINGLE_STEP:
  72.             return "Single step";
  73.  
  74.         /*
  75.         ** Portable Fatal Software-Generated Exceptions
  76.         */
  77.         case XCPT_IN_PAGE_ERROR:
  78.             return "In page error";
  79.         case XCPT_PROCESS_TERMINATE:
  80.             return "Process terminate";
  81.         case XCPT_NONCONTINUABLE_EXCEPTION:
  82.             return "Noncontinuable exception";
  83.         case XCPT_INVALID_DISPOSITION:
  84.             return "Invalid disposition";
  85.  
  86.         /*
  87.         ** Non-portable Fatal exceptions
  88.         */
  89.         case XCPT_INVALID_LOCK_SEQUENCE:
  90.             return "Invalid lock sequence";
  91.         case XCPT_ARRAY_BOUNDS_EXCEEDED:
  92.             return "Array bounds exceeded";
  93.  
  94.         /*
  95.         ** Unwind operation exceptions.
  96.         */
  97.         case XCPT_UNWIND:
  98.             return "Unwind";
  99.         case XCPT_BAD_STACK:
  100.             return "Bad stack";
  101.         case XCPT_INVALID_UNWIND_TARGET:
  102.             return "Invalid unwind target";
  103.  
  104.         /*
  105.         ** Fatal signal exceptions.
  106.         */
  107.         case XCPT_SIGNAL:
  108.             return "Signal";
  109.     }
  110.     return "UNKNOWN";
  111. }
  112.  
  113. /*
  114. ** Handle an exception.  Return whether the execption was expected
  115. ** or whether it was unexpected.
  116. */
  117. int HandleException(int command)
  118. {
  119. DebugModule *module;
  120.  
  121.     /*
  122.     ** Pre-first change for debugger help.
  123.     */
  124.     fprintf(logFile, "Execption type %d at %08x\n",
  125.         debugBuffer.Value, debugBuffer.Addr);
  126.     if(debugBuffer.Value == 0) {
  127.  
  128.     /*
  129.         ** Single step is always expected if the command was
  130.         ** single step!
  131.         */
  132.         if((command == DBG_C_SStep) &&
  133.            (debugBuffer.Buffer == XCPT_SINGLE_STEP)) {
  134.                 debugBuffer.Value = XCPT_CONTINUE_STOP;
  135.         DispatchCommand(DBG_C_Continue);
  136.                 return 0;
  137.         }
  138.  
  139.         /*
  140.         ** Breakpoints are expected only if a breakpoint was
  141.         ** set at the address.
  142.         */
  143.         if(debugBuffer.Buffer == XCPT_BREAKPOINT) {
  144.             if(isValidBreakpoint(debugBuffer.Addr)) {
  145.                 debugBuffer.Value = XCPT_CONTINUE_STOP;
  146.         DispatchCommand(DBG_C_Continue);
  147.                 return 0;
  148.             } else {
  149.                 debugBuffer.Value = XCPT_CONTINUE_SEARCH;
  150.         DispatchCommand(DBG_C_Continue);
  151.         fprintf(logFile, "ERROR! Unexpected breakpoint!\n");
  152.                 return 0;
  153.             }
  154.         }
  155.  
  156.         /*
  157.         ** Unknown exection!
  158.         */
  159.     fprintf(logFile, "ERROR! Unexpected exception: %s (%08x) for pre-first!\n",
  160.                 findExceptionName(debugBuffer.Buffer), debugBuffer.Buffer);
  161.     debugBuffer.Value = XCPT_CONTINUE_STOP;
  162.     DispatchCommand(DBG_C_Continue);
  163.     return 0;
  164.     }
  165.  
  166.     /*
  167.     ** First or second notification.
  168.     */
  169.     if((debugBuffer.Value == 1) || (debugBuffer.Value == 2)) {
  170.     EXCEPTIONREPORTRECORD    stats;
  171.     int            i;
  172.  
  173.     debugBuffer.Len    = sizeof(stats);
  174.     debugBuffer.Addr   = debugBuffer.Buffer;
  175.     debugBuffer.Buffer = (ULONG) &stats;
  176.     if(DispatchCommand(DBG_C_ReadMemBuf) != DBG_N_Success) {
  177.         fprintf(logFile, "Unable to get exception record\n");
  178.     }
  179.  
  180.     fprintf(logFile, "  Except #: %08x  %s\n",
  181.         stats.ExceptionNum,
  182.         findExceptionName(stats.ExceptionNum));
  183.     fprintf(logFile, "  Flags:    %08x\n",
  184.         stats.fHandlerFlags);
  185.     fprintf(logFile, "  Next Rec: %08x\n",
  186.         stats.NestedExceptionReportRecord);
  187.     fprintf(logFile, "  Except Addr: %08x\n",
  188.         stats.ExceptionAddress);
  189.     fprintf(logFile, "  Num Parms: %d\n",
  190.         stats.cParameters);
  191.     for(i=0; i<stats.cParameters; i++) {
  192.         fprintf(logFile, "  Except %d: %08x\n",
  193.             i, stats.ExceptionInfo[i]);
  194.     }
  195.  
  196.     /*
  197.     ** Find where this address is.
  198.     */
  199.     module = FindModule(debugBuffer.MTE, NULL);
  200.     if(module != NULL) {
  201.         char    funcName[MAX_FUNCNAME];
  202.         char    sourceName[CCHMAXPATH];
  203.         ULONG   lineNum;
  204.  
  205.         FindSource(module, (ULONG) stats.ExceptionAddress,
  206.            funcName, sourceName, &lineNum);
  207.         if(lineNum != 0)
  208.         fprintf(logFile, "\n"
  209.                 "  Module:   %s\n"
  210.                 "  Size:     %u\n"
  211.                 "  Timestamp:%s\n"
  212.                 "  Function: %s\n"
  213.                 "  Source:   %s\n"
  214.                 "  Line:     %d\n\n",
  215.             module->name, module->fileSize,
  216.             ctime(&module->fTimestamp),
  217.             funcName, sourceName, lineNum);
  218.         else
  219.         fprintf(logFile, "  Module:   %s\n"
  220.                 "  Size:     %u\n"
  221.                 "  Timestamp:%s\n"
  222.                 "  Lo Function: %s\n"
  223.                 "  Hi Function: %s\n\n",
  224.             module->name, module->fileSize,
  225.             ctime(&module->fTimestamp),
  226.             funcName, sourceName);
  227.     }
  228.  
  229.     /*
  230.     ** Tell the system to continue with the exception handling.
  231.     */
  232.     debugBuffer.Value = XCPT_CONTINUE_STOP;
  233.     DispatchCommand(DBG_C_Continue);
  234.     return 0;
  235.     }
  236.  
  237.     /*
  238.     ** Invalid stack notification.
  239.     */
  240.     if(debugBuffer.Value == 3) {
  241.     fprintf(logFile, "INVALID STACK EXECTION %08x AT: %08x\n",
  242.                 debugBuffer.Buffer, debugBuffer.Addr);
  243.     }
  244.  
  245.     debugBuffer.Value = XCPT_CONTINUE_STOP;
  246.     DispatchCommand(DBG_C_Continue);
  247.     return 0;
  248. }
  249.