home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ocl150a.zip / OCL / Source / OXcptBase.cpp < prev    next >
C/C++ Source or Header  |  1997-01-10  |  9KB  |  308 lines

  1. // OCL - OS/2 Class Library
  2. // (c) Cubus 1995
  3. // All Rights Reserved
  4. // OXcptBase.cpp
  5.  
  6.  
  7. /*
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Neither the name Cubus nor the name Team OCL may be used to
  14.  *    endorse or promote products derived from this software
  15.  *    without specific prior written permission.
  16.  * 3. See OCL.INF for a detailed copyright notice.
  17.  *
  18.  *              THIS SOFTWARE IS PROVIDED ``AS IS'' AND
  19.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  22.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28.  * SUCH DAMAGE.
  29.  */
  30.  
  31. // $Header: W:/Projects/OCL/Source/rcs/OXcptBase.cpp 1.50 1996/08/11 23:49:37 B.STEIN Release $
  32.  
  33. #define __OCL_SOURCE__
  34.  
  35. #define OINCL_OSTRING
  36. #define OINCL_BASE
  37.  
  38. #include <ocl.hpp>
  39. #include <OXcptBase.hpp>
  40.  
  41. #include <stdarg.h>
  42.  
  43.  
  44. pOXcptBase OXcptBase::currentHandler = NULL;
  45.  
  46.  
  47. OXcptBase::OXcptBase(BOOL killMessages)
  48.    : killMsg(killMessages),
  49.      record(NULL) {}
  50.  
  51. OXcptBase::~OXcptBase()
  52.   {}
  53.  
  54.  
  55. PSZ OXcptBase::isOfType() const
  56.  return("OXcptBase"); 
  57.  
  58.  
  59.  
  60. BOOL OXcptBase::setHandler(OXCPTRECORD& regRecord)
  61. {
  62.  if (!OXcptBase::currentHandler)
  63.    OXcptBase::currentHandler = this;
  64.  
  65.  record = ®Record;
  66.  
  67.  regRecord.prev_structure   = NULL;
  68.  regRecord.ExceptionHandler = (_ERR*)&OXcptBase::OXCPT_CATCH;
  69.  
  70.  if (!DosSetExceptionHandler(®Record))
  71.    return(!DosSetSignalExceptionFocus(SIG_SETFOCUS, ×));
  72.  return(FALSE);
  73. }
  74.  
  75.  
  76. BOOL OXcptBase::unsetHandler()
  77. {
  78.  if (OXcptBase::currentHandler == this)
  79.    OXcptBase::currentHandler = NULL;
  80.  
  81.  if (record)
  82.    return(!DosUnsetExceptionHandler(record));
  83.  return(FALSE);
  84. }
  85.  
  86.  
  87.  
  88. BOOL OXcptBase::handler(PEXCEPTIONREPORTRECORD report,
  89.                         OXCPTRECORD *record,
  90.                         CONTEXTRECORD *context,
  91.                         PVOID pargs)
  92. {
  93.  BOOL    disable = TRUE;
  94.  ULONG   nest;
  95.  OString msg("\nException Handler registered:\n");
  96.  
  97.  DosEnterMustComplete(&nest);
  98.  msg + except_printf("\nFatal exception: %8.8lX.\n",report->ExceptionNum);
  99.  
  100.  switch (report->ExceptionNum) 
  101.   {
  102.    case XCPT_PROCESS_TERMINATE:
  103.    case XCPT_ASYNC_PROCESS_TERMINATE:
  104.    case XCPT_UNWIND:
  105.      DosExitMustComplete(&nest);
  106.      return(TRUE);
  107.  
  108.    case XCPT_CPP_EXCEPTION:
  109.      DosExitMustComplete(&nest);
  110.      return(FALSE);
  111.  
  112.    case XCPT_ACCESS_VIOLATION:
  113.      msg + except_printf("Access violation.\n");
  114.      switch (report->ExceptionInfo[0]) 
  115.       {
  116.        case XCPT_READ_ACCESS:
  117.        case XCPT_WRITE_ACCESS:
  118.          msg + except_printf("Invalid linear address %8.8lX.\n", report->ExceptionInfo[1]);
  119.          break;
  120.        case XCPT_SPACE_ACCESS:
  121.          msg + except_printf("Invalid selector %8.8lX.\n",report->ExceptionInfo[1]);
  122.          break;
  123.        case XCPT_LIMIT_ACCESS:
  124.          msg + except_printf("Limit access fault.\n");
  125.          break;
  126.        case XCPT_UNKNOWN_ACCESS:
  127.          msg + except_printf("Unknown access fault.\n");
  128.          break;
  129.        default:
  130.          msg + except_printf("Other unknown access fault.\n");
  131.       }
  132.      break;
  133.    case XCPT_INTEGER_DIVIDE_BY_ZERO:
  134.      msg + except_printf("Integer divide by zero.\n");
  135.      break;
  136.    case XCPT_INTEGER_OVERFLOW:
  137.      msg + except_printf("Integer overflow.\n");
  138.      break;
  139.    case XCPT_ILLEGAL_INSTRUCTION:
  140.      msg + except_printf("Illegal instruction.\n");
  141.      break;
  142.    case XCPT_FLOAT_DENORMAL_OPERAND:
  143.      msg + except_printf("Float denormal operand.\n");
  144.      break;
  145.    case XCPT_FLOAT_DIVIDE_BY_ZERO:
  146.      msg + except_printf("Float divide by zero.\n");
  147.      break;
  148.    case XCPT_FLOAT_INEXACT_RESULT:
  149.      msg + except_printf("Float inexact result.\n");
  150.      break;
  151.    case XCPT_FLOAT_INVALID_OPERATION:
  152.      msg + except_printf("Float invalid operation.\n");
  153.      break;
  154.    case XCPT_FLOAT_OVERFLOW:
  155.      msg + except_printf("Float overflow.\n");
  156.      break;
  157.    case XCPT_FLOAT_STACK_CHECK:
  158.      msg + except_printf("Float stack check.\n");
  159.      break;
  160.    case XCPT_FLOAT_UNDERFLOW:
  161.      msg + except_printf("Float underflow.\n");
  162.      break;
  163.    case XCPT_PRIVILEGED_INSTRUCTION:
  164.      msg + except_printf("Privileged instruction.\n");
  165.      break;
  166.    case XCPT_NONCONTINUABLE_EXCEPTION:
  167.      msg + except_printf("Unknown noncontinuable exception.\n");
  168.      disable = FALSE;
  169.      break;
  170.    case XCPT_SIGNAL:
  171.      msg << "Acknowledged signal: ";
  172.      switch (report->ExceptionInfo[0]) 
  173.       {
  174.        case XCPT_SIGNAL_BREAK:
  175.          msg + except_printf("Control-Break.\n");
  176.          break;
  177.        case XCPT_SIGNAL_INTR:
  178.          msg + except_printf("Control-C.\n");
  179.          break;
  180.        case XCPT_SIGNAL_KILLPROC:
  181.          msg + except_printf("DosKillProcess.\n");
  182.          break;
  183.       }
  184.      DosExitMustComplete(&nest);
  185.      if (killMsg)
  186.        exceptionMessage(msg);
  187.      if (killTrace())
  188.       {
  189.        DosAcknowledgeSignalException(XCPT_SIGNAL_INTR);
  190.        DosAcknowledgeSignalException(XCPT_SIGNAL_KILLPROC);
  191.        DosAcknowledgeSignalException(XCPT_SIGNAL_BREAK);
  192.        return(TRUE);
  193.       }
  194.      else
  195.       {
  196.        unsetHandler(); 
  197.        DosExit(EXIT_THREAD, 0);
  198.       }  
  199.   }
  200.  
  201.  except_print_context(msg, context);
  202.  msg + except_printf("Cannot continue.\n");
  203.  
  204.  DosExitMustComplete(&nest);
  205.  exceptionMessage(msg);
  206.  unsetHandler();
  207.  if (disable)
  208.    DosError(FERR_DISABLEEXCEPTION);
  209.  return(trapTrace());
  210.  
  211. #ifdef __BCPLUSPLUS__
  212.   #pragma warn -par
  213. #endif
  214. }
  215. #ifdef __BCPLUSPLUS__
  216.   #pragma warn .par
  217. #endif
  218.  
  219.  
  220.  
  221. ULONG OXcptBase::OXCPT_CATCH(EXCEPTIONREPORTRECORD *report,
  222.                              OXCPTRECORD *record,
  223.                              CONTEXTRECORD *context,
  224.                              PVOID pargs)
  225. {
  226.  if ((!OXcptBase::currentHandler) || 
  227.      (!OXcptBase::currentHandler->handler(report, record, context, pargs))) {
  228.    return(XCPT_CONTINUE_SEARCH); } 
  229.  else
  230.    return(XCPT_CONTINUE_EXECUTION);
  231. #ifdef __BCPLUSPLUS__
  232.   #pragma warn -par
  233. #endif
  234. }
  235. #ifdef __BCPLUSPLUS__
  236.   #pragma warn .par
  237. #endif
  238.  
  239.  
  240.  
  241. // C helpers
  242.  
  243.  
  244. PSZ __CPP_EXPORT__ except_printf(const char *format, ...) 
  245. {
  246.  va_list      ap;
  247.  static CHAR  buf[CCHMAXPATH];
  248.  
  249.  va_start(ap, format);
  250.  vsprintf(buf, format, ap);
  251.  va_end(ap);
  252.  
  253.  return((PSZ)buf);
  254. }
  255.  
  256.  
  257. void __CPP_EXPORT__ except_print_context(OString& msg, PCONTEXTRECORD cont) 
  258. {
  259.  PTIB   ptib;
  260.  PPIB   ppib;
  261.  APIRET rc;
  262.  
  263.  if (cont->ContextFlags & CONTEXT_CONTROL) {
  264.    msg + except_printf("EIP : %8.8lX\n",cont->ctx_RegEip  );
  265.    msg + except_printf("EBP : %8.8lX\n",cont->ctx_RegEbp  );
  266.    msg + except_printf("ESP : %8.8lX\n",cont->ctx_RegEsp  );
  267.    msg + except_printf("EFLG: %8.8lX\n",cont->ctx_EFlags  ); }
  268.  
  269.  if (cont->ContextFlags & CONTEXT_INTEGER) {
  270.    msg + except_printf("EAX : %8.8lX\n",cont->ctx_RegEax  );
  271.    msg + except_printf("EBX : %8.8lX\n",cont->ctx_RegEbx  );
  272.    msg + except_printf("ECX : %8.8lX\n",cont->ctx_RegEcx  );
  273.    msg + except_printf("EDX : %8.8lX\n",cont->ctx_RegEdx  );
  274.    msg + except_printf("EDI : %8.8lX\n",cont->ctx_RegEdi  );
  275.    msg + except_printf("ESI : %8.8lX\n",cont->ctx_RegEsi  ); }
  276.  
  277.  if (cont->ContextFlags & CONTEXT_CONTROL) {
  278.    msg + except_printf("CS  : %4.4lX\n",cont->ctx_SegCs   );
  279.    msg + except_printf("SS  : %4.4lX\n",cont->ctx_SegSs   ); }
  280.  
  281.  if (cont->ContextFlags & CONTEXT_SEGMENTS) {
  282.    msg + except_printf("GS  : %4.4lX\n",cont->ctx_SegGs);
  283.    msg + except_printf("FS  : %4.4lX\n",cont->ctx_SegFs);
  284.    msg + except_printf("ES  : %4.4lX\n",cont->ctx_SegEs);
  285.    msg + except_printf("DS  : %4.4lX\n",cont->ctx_SegDs); }
  286.  
  287.  if (cont->ContextFlags & CONTEXT_CONTROL) 
  288.   {
  289.    if (DosGetInfoBlocks(&ptib, &ppib) == 0) {
  290.      static CHAR modname[CCHMAXPATH];
  291.     
  292.      msg + except_printf("Process id: %lu, ", ppib->pib_ulpid);
  293.      rc = DosQueryModuleName(ppib->pib_hmte,CCHMAXPATH, modname);
  294.      msg + except_printf(".EXE name: %s\n", rc == 0 ? modname : "?????");
  295.      msg + except_printf("Thread id: %lu,  ordinal : %lu, priority : %p\n",
  296.                          ptib->tib_ptib2->tib2_ultid ,
  297.                          ptib->tib_ordinal,
  298.                          ptib->tib_ptib2->tib2_ulpri );
  299.      msg + except_printf("Stack bottom: %8.8lX, ", ptib->tib_pstack);
  300.      msg + except_printf("top: %8.8lX \n",ptib->tib_pstacklimit); }
  301.   }
  302. }
  303.  
  304.  
  305. // end of source
  306.