¦ EXCEPTION_CONTINUE_EXECUTION The system assumes that the exception is resolved and continues thread execution at the point at which the exception occurred. Filter functions typically return this value after handling the exception to continue processing as normal.

¦ EXCEPTION_CONTINUE_SEARCH The system continues its search for an appropriate exception handler.

¦ EXCEPTION_EXECUTE_HANDLER The system thread execution continues sequentially from the exception handler rather than from the point of the exception.

NOTE Exception handling support

Exception handling is an extension of the C language, but it is natively supported in C+ + .

Termination Handler Syntax

Windows Embedded CE supports termination handling. As a Microsoft extension to the C and C++ languages, it enables you to guarantee that the system always runs a certain block of code not matter how the flow of control leaves the guarded code block. This code section is called a termination handler, and is used to perform cleanup tasks even if an exception or some other error occurs in the guarded code. For example, you can use a termination handler to close thread handles that are no longer needed.

The following code fragment illustrates how to use the __try and __finally keywords for structured exception handling:

__try {

 // Place guarded code here.

} __finally {

 // Place termination code here.

}

Termination handling supports the __leave keyword within the guarded section. This keyword ends thread execution at the current position in the guarded section and resumes thread execution at the first statement in the termination handler without unwinding the call stack.

NOTE Using __try, __except, and __finally blocks

A single __try block cannot have both an exception handler and a termination handler. If you must use both __except and __finally, use an outer try-except statement and an inner try-finally statement.

Dynamic Memory Allocation

Dynamic memory allocation is an allocation technique that relies on structured exception handling to minimize the total number of committed memory pages on the system. This is particularly useful if you must perform large memory allocations. Precommitting an entire allocation can cause the system to run out of committable pages and result in virtual memory allocation failures.

The dynamic memory allocation technique is as follows:

1. Call VirtualAlloc with a base address of NULL to reserve a block of memory. The system reserves this memory block without committing the pages.

2. Try to access a memory page. This raises an exception because you cannot read from or write to a non- committed page. This illegal operation results in a page fault exception. Figure 3-5 and Figure 3-6 show the outcome of an unhandled page fault in an application called PageFault.exe.

3. Implement an exception handler based on a filter function. Commit a page in the filter function from the reserved region. If successful, return EXCEPTION_CONTINUE_EXECUTION to continue thread execution in the __try block at the point where the exception occurred. If the page allocation failed, return EXCEPTION_EXECUTE_HANDLER to invoke the exception handler in the __except block and release the entire region of reserved and committed pages.

Figure 3-5 An unhandled page fault exception from a user's perspective

Figure 3-6 An unhandled page fault exception's debug output over KITL in Visual Studio 2005

The following code snippet illustrates the dynamic memory allocation technique based on page fault exception handling:

#define PAGESTOTAL 42 // Max. number of pages

LPTSTR lpPage;    // Page to commit

DWORD dwPageSize; // Page size, in bytes

INT ExceptionFilter(DWORD dwCode) {

 LPVOID lpvPage;

 if (EXCEPTION_ACCESS_VIOLATION != dwCode) {

  // This is an unexpected exception!

  // Do not return EXCEPTION_EXECUTE_HANDLER

  // to handle this in the application process.

  // Instead, let the operating system handle it.

  return EXCEPTION_CONTINUE_SEARCH;

 }

 // Allocate page for read/write access.

 lpvPage = VirtualAlloc((LPVOID) lpPage,

 dwPageSize, MEM_COMMIT, PAGE_READWRITE);

 if (NULL == lpvPage) {

  // Continue thread execution

  // in __except block.

  return EXCEPTION_EXECUTE_HANDLER;

 }

 // Set lpPage to the next page.

 lpPage = (LPTSTR) ((PCHAR) lpPage + dwPageSize);

 // Continue thread execution in __try block.

 return EXCEPTION_CONTINUE_EXECUTION;

}

VOID DynamicVirtualAlloc() {

 LPVOID lpvMem;

 LPTSTR lpPtr;

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату