ENTERPRISE

Windows System Programming : Exception Handling - Using Termination Handlers to Improve Program Quality, Using a Filter Function

4/29/2013 7:40:41 PM

1. Using Termination Handlers to Improve Program Quality

Termination and exception handlers allow you to make your program more robust by both simplifying recovery from errors and exceptions and helping to ensure that resources and file locks are freed at critical junctures.

Toupper, illustrates these points, using ideas from the preceding code fragments. toupper processes multiple files, as specified on the command line, rewriting them so that all letters are in uppercase. Converted files are named by prefixing UC_ to the original file name, and the program “specification” states that an existing file should not be overridden. File conversion is performed in memory, so there is a large buffer (sufficient for the entire file) allocated for each file. There are multiple possible failure points for each processed file, but the program must defend against all such errors and then recover and attempt to process all the remaining files named on the command line.

Note that this program depends on file sizes, so it will not work on objects for which GetFileSizeEx fails, such as a named pipe . Furthermore, it fails for large text files longer than 4GB.

The code in the Examples file has more extensive comments.

Run 1 shows toupper operation. Originally, there are two text files, a.txt and b.txt. The cat programdisplays the contents of these two files; you could also use the Windows type command. toupper converts these two files, continuing after failing to find b.txt. Finally, cat displays the two converted files, UC_a.txt and UC_c.txt.

Run 1. toupper: Converting Text Files to Uppercase

2. Using a Filter Function

Program 2 is a skeleton program that illustrates exception and termination handling with a filter function. This example prompts the user to specify the exception type and then proceeds to generate an exception. The filter function disposes of the different exception types in various ways; the selections here are arbitrary and intended simply to illustrate the possibilities. In particular, the program diagnoses memory access violations, giving the virtual address of the reference.

Program 2. Exception: Processing Exceptions and Termination
#include "Everything.h"
#include <float.h>

DWORD Filter(LPEXCEPTION_POINTERS, LPDWORD);
double x = 1.0, y = 0.0;

int _tmain(int argc, LPTSTR argv[])
{
   DWORD eCategory, i = 0, ix, iy = 0;
   LPDWORD pNull = NULL;
   BOOL done = FALSE;
   DWORD fpOld, fpNew;
   fpOld = _controlfp(0, 0); /* Save old control mask. */
                    /* Enable floating-point exceptions. */
   fpNew = fpOld & ~(EM_OVERFLOW | EM_UNDERFLOW | EM_INEXACT
          | EM_ZERODIVIDE | EM_DENORMAL | EM_INVALID);
   _controlfp(fpNew, MCW_EM);

   while (!done) __try { /* Try-finally. */
      _tprintf(_T("Enter exception type: "));
      _tprintf(_T
             (" 1: Mem, 2: Int, 3: Flt 4: User 5: __leave "));
      _tscanf(_T("%d"), &i);
      __try { /* Try-except block. */
         switch (i) {
         case 1: /* Memory reference. */
            ix = *pNull; *pNull = 5; break;
         case 2: /* Integer arithmetic. */
            ix = ix / iy; break;
         case 3: /* Floating-point exception. */
            x = x / y;
            _tprintf(_T("x = %20e\n"), x); break;
         case 4: /* User-generated exception. */
            ReportException(_T("User exception"), 1); break;
         case 5: /* Use the _leave statement to terminate. */
            __leave;
         default: done = TRUE;
         }
      } /* End of inner __try. */

      __except (Filter(GetExceptionInformation(), &eCategory))
      {
         switch (eCategory) {
            case 0:
               _tprintf(_T("Unknown Exception\n")); break;
            case 1:
               _tprintf(_T("Memory Ref Exception\n")); continue;
            case 2:
               _tprintf(_T("Integer Exception\n")); break;
            case 3:
               _tprintf(_T("Floating-Point Exception\n"));
               _clearfp(); break;
            case 10:
               _tprintf(_T("User Exception\n")); break;
            default:
               _tprintf( _T("Unknown Exception\n")); break;
         } /* End of switch statement. */

         _tprintf(_T("End of handler\n"));
      } /* End of try-except block. */
   } /* End of While loop -- the termination handler is below. */

   __finally { /* This is part of the while loop. */
      _tprintf(_T("Abnormal Termination?: %d\n"),
             AbnormalTermination());
   }
   _controlfp(fpOld, 0xFFFFFFFF); /* Restore old FP mask.*/
   return 0;
}

					  

The __finally block restores the state of the floating-point mask. Restoring state, as done here, is not important when the process is about to terminate, but it is important later when a thread is terminated. In general, a process should still restore system resources by, for example, deleting temporary files and releasing synchronization resources and file locks . Program 3 shows the filter function.

Program 3. Filter: Exception Filtering
static DWORD Filter(LPEXCEPTION_POINTERS pExP, LPDWORD eCategory)
/* Categorize the exception and decide action. */
{
   DWORD exCode, readWrite, virtAddr;
   exCode = pExP->ExceptionRecord->ExceptionCode;
   _tprintf(_T("Filter. exCode: %x\n"), exCode);
   if ((0x20000000 & exCode) != 0) { /* User exception. */
      *eCategory = 10;
      return EXCEPTION_EXECUTE_HANDLER;
   }

   switch (exCode) {
      case EXCEPTION_ACCESS_VIOLATION:
         readWrite = /* Was it a read, write, execute? */
                pExP->ExceptionRecord->ExceptionInformation[0];
         virtAddr = /* Virtual address of the violation. */
                pExP->ExceptionRecord->ExceptionInformation[1];
         _tprintf(
         _T("Access Violation. Read/Write/Exec: %d. Address: %x\n"),
                readWrite, virtAddr);
         *eCategory = 1;
         return EXCEPTION_EXECUTE_HANDLER;
      case EXCEPTION_INT_DIVIDE_BY_ZERO:
      case EXCEPTION_INT_OVERFLOW:
         *eCategory = 2;
         return EXCEPTION_EXECUTE_HANDLER;
      case EXCEPTION_FLT_DIVIDE_BY_ZERO:
      case EXCEPTION_FLT_OVERFLOW:
         _tprintf(_T("Flt Exception - large result.\n"));
         *eCategory = 3;
         _clearfp();
         return EXCEPTION_EXECUTE_HANDLER;

      default:
         *eCategory = 0;
         return EXCEPTION_CONTINUE_SEARCH;
   }
}

					  

This example does not illustrate memory allocation exceptions.

Run 3, after the filter function (Program 3) shows the program operation.

Run 3. Filter: Exception Filtering

Program 3 shows the filter function used in Program 2. This function simply checks and categorizes the various possible exception code values. The code in the Examples file checks every possible value; here the function tests only for a few that are relevant to the test program.

Other  
 
Most View
Sharkoon DarkGlider Gaming Laser - Perfect For Resting Your Hand
Free Website Builders Group Test : Wix
Windows Vista : Scripting and Automation - Wacky Script Ideas
Logitech UltraThin Keyboard Cover For iPad Air
Review : Toshiba Satellite L50-B
Simulating SOA : The Ideal SOA Simulator
Windows Server 2008 Server Core : Accessing the Windows Package Manager with the PkgMgr Utility, Adding and Removing Applications with the OCSetup Utility
The Xperia T - Remarkable In How Unremarkable It Is (Part 2)
Do You Really Need Security?
Windows Server 2003 : Planning a Host Name Resolution Strategy - Understanding Name Resolution Requirements
REVIEW
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
VIDEO TUTORIAL
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
Popular Tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS
Top 10
3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
3 Tips for Maintaining Your Cell Phone Battery (part 1) - Charge Smart
OPEL MERIVA : Making a grand entrance
FORD MONDEO 2.0 ECOBOOST : Modern Mondeo
BMW 650i COUPE : Sexy retooling of BMW's 6-series
BMW 120d; M135i - Finely tuned
PHP Tutorials : Storing Images in MySQL with PHP (part 2) - Creating the HTML, Inserting the Image into MySQL
PHP Tutorials : Storing Images in MySQL with PHP (part 1) - Why store binary files in MySQL using PHP?
Java Tutorials : Nested For Loop (part 2) - Program to create a Two-Dimensional Array
Java Tutorials : Nested For Loop (part 1)