Jump to content

CPGuide - Exception Management: Difference between revisions

From EDM2
No edit summary
Line 1: Line 1:
{{IBM-Reprint}}
{{IBM-Reprint}}
{{CPGuide}}
{{CPGuide}}
An ''exception'' is an abnormal condition that can occur during program execution. Common causes of exceptions include:
*I/O errors
*Protection violations
*Math errors
*Intervention by the user or by another process
Activities that can cause exceptions include:
*Trying to use memory that you do not have permission to access
*Dividing by 0
*The user pressing Ctrl+Break
Exceptions include both unexpected errors (such as a memory protection violation) and expected errors (such as guard-page exceptions). Exceptions can be a synchronous exception, that is, caused by an action of the executing thread, or an asynchronous exception, caused by an event external to the executing thread (such as the user pressing Ctrl+Break). When an exception is caused by the user pressing Ctrl+Break or Ctrl+C, or by another process issuing DosKillProcess for your process, the exception is called a signal exception.
In most cases, the default action taken by OS/2 when an exception occurs is to terminate the application that caused the exception. Rather than having OS/2 default action occur, an application can register its own subroutine to handle exceptions. These routines are called exception handlers. Exception handlers enable an application to handle some errors itself, allowing the application to avoid termination (or at least to terminate gracefully).
When exception handlers are registered, they are added to an exception handler chain. The chain starts empty and each new handler is added to the head of the chain. Exceptions are passed to the exception handlers in the chain in Last-In-First-Out order, so the last exception handler to be registered is the first one to get an opportunity to handle each exception.
Exception handlers have the capability to complete critical code sections without being interrupted by other asynchronous exceptions; these critical code sections are called must-complete sections.
Exception handlers can be removed from the exception handler chains with DosUnsetExceptionHandler. Another way that exception handlers can be removed from the chain is with an unwind operation. When unwinding an exception handler, the exception handler is first called, then removed from the exception handler chain.
The following topics are related to the information in this chapter:
*Memory
*Program execution and control


==About Exception Management==
==About Exception Management==
A multitasking operating system must manage applications carefully. A serious error (such as an attempt to access protected memory) occurring in one application cannot be permitted to damage any other application in the system. To manage errors that might damage other applications, OS/2 defines a class of error conditions called exceptions and defines default actions for those errors.
When an exception occurs, the default action taken by OS/2 is usually to terminate the application causing the exception (unless the application has registered its own exception handling routines). In some cases, when the exception can safely be ignored, execution is allowed to continue.
Rather than having OS/2 default action occur, an application can register its own exception handlers routines. An exception handler routine could be written to correct certain error conditions-when these error conditions occur, the thread's exception handler gets the exception, corrects the condition, and the thread continues executing rather than being terminated immediately by OS/2. OS/2's default action is taken if there are no user-defined exception handling routines or if all user-defined routines return without handling the exception.
An application can use DosSetExceptionHandler to register an exception handling routine. DosSetExceptionHandler takes a pointer to an EXCEPTIONREGISTRATIONRECORD data structure as its only argument. The first field in this data structure is a pointer to the previous exception handler in the chain. This field is maintained by OS/2 and must never be modified by an application. The second field is a pointer to the exception handling routine that will be registered by OS/2.
A single exception handler can be used to handle all the exceptions that you choose to handle. It is not necessary to have a separate exception handler for each exception.
Once an exception handling routine is registered, the system will notify it when an exception occurs. OS/2 sends synchronous exceptions only to the thread causing the exception. An application must register an exception handler for each thread that is handling exceptions. When OS/2 terminates an application, however, a process-termination exception is sent to all threads used by the application to be terminated. When the user presses Ctrl+Break, an asynchronous signal exception is sent only to Thread 1, the main thread, of the executing process.
The exception handling routine is passed the following four parameters that provide exception-specific information:
;EXCEPTIONREPORTRECORD
:Describes the exception and its parameters. The first field of this data structure contains the number of the exception that occurred.
;EXCEPTIONREGISTRATIONRECORD
:The EXCEPTIONREGISTRATIONRECORD data structure used to initially register the exception handler. This is a microprocessor-specific value.
;ContextRecord
:Describes the machine state at the time the exception occurred.
;DispatcherContext
:Contains state information on nested exception and collided unwinds. This information must not be modified by the application.
Details of the parameters and data structures can be found in Exception Handler Interface.
OS/2 places the exception handlers for each thread in an exception handler chain. Registering an exception handler adds it to the head of the chain.
When an application registers an exception handler, the exception handler is added to the head of the chain. If the application calls a routine in a dynamic link library (DLL), the DLL might register an exception handler in case there is an exception while its code is executing; the DLL deregisters the exception handler before returning control to the application. The DLL's exception handler would be ahead of the application's exception handler in the chain.
Exception handlers in the chain are notified of an exception in Last-In-First-Out (LIFO) order. Thus, if an exception occurs while your thread is executing, the exception handler for your thread is notified of the exception first. If your exception handler chooses to handle the exception, the earlier exception handlers in the chain never see the exception. If your exception handler chooses not to handle the exception, it is passed along to the next earlier exception handler in the chain. If no exception handler in the chain chooses to handle the exception, OS/2 takes the default action for the exception.
If an exception happens while DLL code is executing, and if the DLL's exception handler chooses to handle the exception, your application's exception handlers will never be aware it.


===System Exceptions===
===System Exceptions===
OS/2 defines a class of error conditions called system exceptions, and specifies the default actions that are taken when these system exceptions occur. The default action taken by OS/2 in most cases is to terminate the thread that caused the system exception.
System exceptions include both synchronous and asynchronous exceptions. Synchronous exceptions are caused by events that are internal to the execution of a thread. For example, synchronous exceptions could be caused by invalid parameters, or by the request of a thread to end its own execution.
Asynchronous exceptions are caused by events that are external to the execution of a thread. For example, an asynchronous exception can be caused by a user entering a Ctrl+C or Ctrl+Break key sequence, or by a process calling DosKillProcess to end the execution of another process.
The Ctrl+Break, Ctrl+C, and DosKillProcess-generated exceptions are also known as signals, or as signal exceptions.
OS/2 delivers exceptions that occur in 16-bit as well as 32-bit code. The sequence or hierarchy for delivering exceptions is as follows:
�When an exception occurs in 32-bit code, the system gives control only to the 32-bit exception handlers registered for the current thread. If the thread has not registered any 32-bit handlers, the system default action occurs.
�When an exception occurs in 16-bit code, the system first gives control to the 32-bit exception handlers registered for the current thread. If the exception is not handled by one of these handlers, control is passed to the 16-bit handler, if one exists for the given exception. If there is no 16-bit handler for the exception, the system default action occurs.
Notification of an exception is usually sent only to the thread that caused the exception. However, if a thread uses DosExit to terminate all the threads in the process, notification of the process-termination exception is sent to every thread in the process. The thread that used DosExit gets a XCPT_PROCESS_TERMINATE exception, all the other threads in the process get a XCPT_ASYNC_PROCESS_TERMINATE exception.
Exit-list processing occurs on a per-process basis after a process-termination exception has been delivered to each thread in the process and each thread has finally ended except Thread 1 (the main thread). Therefore, any thread that handles a process-termination exception must eventually end its own execution voluntarily. Otherwise, the process-termination sequence will not conclude properly.
The following tables briefly list the possible exceptions. For more detailed information about the system exceptions, including default system action, parameters, and related trap numbers, see the Control Program Programming Reference.
Non-Fatal, Software-Generated Exceptions
┌──────────────────────────────────────┬──────────────────────┐
│Exception Symbolic Constant          │Description          │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_GUARD_PAGE_VIOLATION            │A guard page has been │
│                                      │accessed.            │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_UNABLE_TO_GROW_STACK            │The system is unable  │
│                                      │to allocate the memory│
│                                      │page directly below  │
│                                      │the guard page just  │
│                                      │accessed.            │
└──────────────────────────────────────┴──────────────────────┘
Fatal, Software-Generated Exceptions
┌──────────────────────────────────────┬──────────────────────┐
│Exception Symbolic Constant          │Description          │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_IN_PAGE_ERROR                    │An I/O error occurred │
│                                      │while reading a memory│
│                                      │page into memory.    │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_PROCESS_TERMINATE                │The thread has        │
│                                      │terminated itself with│
│                                      │DosExit.              │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_ASYNC_PROCESS_TERMINATE          │Another thread in the │
│                                      │process has caused the│
│                                      │thread to terminate.  │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_NONCONTINUABLE_EXCEPTION        │An exception handler  │
│                                      │has attempted to      │
│                                      │continue execution in │
│                                      │response to a        │
│                                      │non-continuable      │
│                                      │exception.            │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_INVALID_DISPOSITION              │An exception handler  │
│                                      │has returned an      │
│                                      │invalid value.        │
└──────────────────────────────────────┴──────────────────────┘
Fatal, Hardware-Generated Exceptions
┌──────────────────────────────────────┬──────────────────────┐
│Exception Symbolic Constant          │Description          │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_ACCESS_VIOLATION                │An access violation or│
│                                      │page fault has        │
│                                      │occurred.            │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_INTEGER_DIVIDE_BY_ZERO          │An attempt to divide  │
│                                      │by 0 has occurred in  │
│                                      │an integer operation. │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_FLOAT_DIVIDE_BY_ZERO            │An attempt to divide  │
│                                      │by 0 has occurred in a│
│                                      │floating point        │
│                                      │operation.            │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_FLOAT_INVALID_OPERATION          │An invalid floating  │
│                                      │point operation was  │
│                                      │attempted.            │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_ILLEGAL_INSTRUCTION              │An attempt was made to│
│                                      │execute an instruction│
│                                      │that is not defined on│
│                                      │the host machine's    │
│                                      │architecture.        │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_PRIVILEGED_INSTRUCTION          │An attempt was made to│
│                                      │execute an instruction│
│                                      │that is not permitted │
│                                      │in the current machine│
│                                      │mode or that the      │
│                                      │application does not  │
│                                      │have permission to    │
│                                      │execute.              │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_INTEGER_OVERFLOW                │An integer operation  │
│                                      │generated a carry-out │
│                                      │of the most          │
│                                      │significant bit.      │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_FLOAT_OVERFLOW                  │A floating point      │
│                                      │operation generated a │
│                                      │resulting exponent    │
│                                      │that is greater than  │
│                                      │the magnitude        │
│                                      │permitted for the    │
│                                      │operands.            │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_FLOAT_UNDERFLOW                  │A floating point      │
│                                      │operation generated a │
│                                      │resulting exponent    │
│                                      │that is less than the │
│                                      │magnitude provided for│
│                                      │the operands.        │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_FLOAT_DENORMAL_OPERAND          │An attempt was made to│
│                                      │perform an arithmetic │
│                                      │operation on a        │
│                                      │denormal operand.    │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_FLOAT_INEXACT_RESULT            │The result of an      │
│                                      │operation is not      │
│                                      │exactly representable │
│                                      │in the target format. │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_FLOAT_STACK_CHECK                │An illegal stack      │
│                                      │operation was        │
│                                      │attempted by the      │
│                                      │floating point        │
│                                      │coprocessor.          │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_DATATYPE_MISALIGNMENT            │An attempt was made to│
│                                      │store a data in an    │
│                                      │address that is not  │
│                                      │naturally aligned on a│
│                                      │hardware architecture │
│                                      │that does not provide │
│                                      │alignment hardware.  │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_BREAKPOINT                      │A breakpoint          │
│                                      │instruction was      │
│                                      │executed.            │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_SINGLE_STEP                      │One instruction has  │
│                                      │been executed in      │
│                                      │single-step mode.    │
└──────────────────────────────────────┴──────────────────────┘
Fatal Exceptions
┌──────────────────────────────────────┬──────────────────────┐
│Exception Symbolic Constant          │Description          │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_INVALID_LOCK_SEQUENCE            │An invalid operation  │
│                                      │was attempted within  │
│                                      │an interlocked section│
│                                      │of code.              │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_ARRAY_BOUNDS_EXCEEDED            │An array index outside│
│                                      │its upper and lower  │
│                                      │boundary was detected.│
└──────────────────────────────────────┴──────────────────────┘
Unwind Operation Exceptions
┌──────────────────────────────────────┬────────────────────────────┐
│Exception Symbolic Constant          │Description                │
├──────────────────────────────────────┼────────────────────────────┤
│XCPT_UNWIND                          │An unwind operation is in  │
│                                      │process.                    │
├──────────────────────────────────────┼────────────────────────────┤
│XCPT_BAD_STACK                        │An                          │
│                                      │EXCEPTIONREGISTRATIONRECORD │
│                                      │data structure was reached  │
│                                      │that is not properly aligned│
│                                      │or that is not within the  │
│                                      │current stack boundaries.  │
├──────────────────────────────────────┼────────────────────────────┤
│XCPT_INVALID_UNWIND_TARGET            │The address of the target  │
│                                      │EXCEPTIONREGISTRATIONRECORD │
│                                      │is below the current stack  │
│                                      │pointer or not in the      │
│                                      │exception handler chain.    │
└──────────────────────────────────────┴────────────────────────────┘
Fatal Signal Exceptions
┌──────────────────────────────────────┬──────────────────────┐
│Exception Symbolic Constant          │Description          │
├──────────────────────────────────────┼──────────────────────┤
│XCPT_SIGNAL                          │A signal was made to  │
│                                      │your process (usually │
│                                      │to stop). All the    │
│                                      │signal exceptions    │
│                                      │(Ctrl+Break, Ctrl+C,  │
│                                      │and                  │
│                                      │XCPT_SIGNAL_KILLPROC) │
│                                      │come under this      │
│                                      │exception.            │
└──────────────────────────────────────┴──────────────────────┘


===Signal Exceptions===
===Signal Exceptions===
Signal exceptions are special events sent to a thread when the user presses certain key sequences or when another thread or process explicitly initiates the exception. There are three types of signal exceptions:
;XCPT_SIGNAL_BREAK
:When the user presses Ctrl+Break
;XCPT_SIGNAL_INTR
:When the user presses Ctrl+C
;XCPT_SIGNAL_KILLPROC
:When another process uses DosKillProcess to send a XCPT_SIGNAL_KILLPROC exception to your process.
Signal exceptions are sent only to Thread 1 (the main thread) in the process receiving the exception. If an exception handler is registered on Thread 1, it must be prepared to receive signal exceptions. The thread 1 exception handler can always ignore the signal exception by returning XCPT_CONTINUE_SEARCH.
If the thread 1 exception handler is to receive signal exceptions, it must use DosSetSignalExceptionFocus to notify OS/2 that it wants to receive the XCPT_SIGNAL_INTR (Ctrl+C) and XCPT_SIGNAL_BREAK (Ctrl+Break) signals. Otherwise, these exceptions are not passed to the exception handler and the default action-to terminate the process-is taken by OS/2. The thread will get XCPT_SIGNAL_KILLPROC signals whether it uses DosSetSignalExceptionFocus or not.
All three of these signals are delivered by a single exception-XCPT_SIGNAL-and the exception handler for Thread 1 can choose to handle none, some, or all of the signals. The signal being sent can be determined by examining the exception information in EXCEPTIONREPORTRECORD.
The following table provides information about each type of signal.
Signal Exceptions
┌────────────┬──────────────────────────┬───────────────────────────┐
│Signal      │Symbolic Constant        │Description                │
├────────────┼──────────────────────────┼───────────────────────────┤
│Ctrl+Break  │XCPT_SIGNAL_BREAK        │This exception is sent to  │
│            │                          │Thread 1 in the current    │
│            │                          │keyboard-focus process when│
│            │                          │a Ctrl+Break key sequence  │
│            │                          │is received from the      │
│            │                          │keyboard. The default      │
│            │                          │action taken by OS/2 for  │
│            │                          │this exception is forced  │
│            │                          │process termination.      │
├────────────┼──────────────────────────┼───────────────────────────┤
│Ctrl+C      │XCPT_SIGNAL_INTR          │This exception is sent to  │
│            │                          │Thread 1 in the current    │
│            │                          │keyboard-focus process when│
│            │                          │a Ctrl+C key sequence is  │
│            │                          │received from the keyboard.│
│            │                          │The default action taken by│
│            │                          │OS/2 for this exception is │
│            │                          │forced process termination.│
├────────────┼──────────────────────────┼───────────────────────────┤
│Kill Process│XCPT_SIGNAL_KILLPROC      │This exception is sent to  │
│Signal      │                          │Thread 1 in the process    │
│            │                          │specified when an          │
│            │                          │application uses          │
│            │                          │DosKillProcess. The        │
│            │                          │XCPT_SIGNAL_KILLPROC signal│
│            │                          │exception results from an  │
│            │                          │action external to the    │
│            │                          │process. The default action│
│            │                          │taken by OS/2 for this    │
│            │                          │exception is forced process│
│            │                          │termination.              │
└────────────┴──────────────────────────┴───────────────────────────┘
====Handling Signal Exceptions====
====Handling Signal Exceptions====
====Sending Signal Exceptions====
====Sending Signal Exceptions====

Revision as of 16:46, 26 March 2020

Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation

Control Program Programming Guide and Reference
  1. Introduction to the Control Program
  2. Control Program Functions
  3. Keyboard Functions
  4. Mouse Functions
  5. Video Functions
  6. Data Types
  7. Errors
  8. Debugging
  9. Kernel Debugger Communications Protocol
  10. Device I/O
  11. Dynamic Linking
  12. Error Management
  13. Exception Management
  14. Extended Attributes
  15. File Management
  16. File Names
  17. File Systems
  18. Generic IOCtl Commands
  19. Memory Management
  20. Message Management
  21. National Language Support
  22. Pipes
  23. Program Execution Control
  24. Queues
  25. Semaphores
  26. Timers
  27. Notices
  28. Glossary

An exception is an abnormal condition that can occur during program execution. Common causes of exceptions include:

  • I/O errors
  • Protection violations
  • Math errors
  • Intervention by the user or by another process

Activities that can cause exceptions include:

  • Trying to use memory that you do not have permission to access
  • Dividing by 0
  • The user pressing Ctrl+Break

Exceptions include both unexpected errors (such as a memory protection violation) and expected errors (such as guard-page exceptions). Exceptions can be a synchronous exception, that is, caused by an action of the executing thread, or an asynchronous exception, caused by an event external to the executing thread (such as the user pressing Ctrl+Break). When an exception is caused by the user pressing Ctrl+Break or Ctrl+C, or by another process issuing DosKillProcess for your process, the exception is called a signal exception.

In most cases, the default action taken by OS/2 when an exception occurs is to terminate the application that caused the exception. Rather than having OS/2 default action occur, an application can register its own subroutine to handle exceptions. These routines are called exception handlers. Exception handlers enable an application to handle some errors itself, allowing the application to avoid termination (or at least to terminate gracefully).

When exception handlers are registered, they are added to an exception handler chain. The chain starts empty and each new handler is added to the head of the chain. Exceptions are passed to the exception handlers in the chain in Last-In-First-Out order, so the last exception handler to be registered is the first one to get an opportunity to handle each exception.

Exception handlers have the capability to complete critical code sections without being interrupted by other asynchronous exceptions; these critical code sections are called must-complete sections.

Exception handlers can be removed from the exception handler chains with DosUnsetExceptionHandler. Another way that exception handlers can be removed from the chain is with an unwind operation. When unwinding an exception handler, the exception handler is first called, then removed from the exception handler chain.

The following topics are related to the information in this chapter:

  • Memory
  • Program execution and control

About Exception Management

A multitasking operating system must manage applications carefully. A serious error (such as an attempt to access protected memory) occurring in one application cannot be permitted to damage any other application in the system. To manage errors that might damage other applications, OS/2 defines a class of error conditions called exceptions and defines default actions for those errors.

When an exception occurs, the default action taken by OS/2 is usually to terminate the application causing the exception (unless the application has registered its own exception handling routines). In some cases, when the exception can safely be ignored, execution is allowed to continue.

Rather than having OS/2 default action occur, an application can register its own exception handlers routines. An exception handler routine could be written to correct certain error conditions-when these error conditions occur, the thread's exception handler gets the exception, corrects the condition, and the thread continues executing rather than being terminated immediately by OS/2. OS/2's default action is taken if there are no user-defined exception handling routines or if all user-defined routines return without handling the exception.

An application can use DosSetExceptionHandler to register an exception handling routine. DosSetExceptionHandler takes a pointer to an EXCEPTIONREGISTRATIONRECORD data structure as its only argument. The first field in this data structure is a pointer to the previous exception handler in the chain. This field is maintained by OS/2 and must never be modified by an application. The second field is a pointer to the exception handling routine that will be registered by OS/2.

A single exception handler can be used to handle all the exceptions that you choose to handle. It is not necessary to have a separate exception handler for each exception.

Once an exception handling routine is registered, the system will notify it when an exception occurs. OS/2 sends synchronous exceptions only to the thread causing the exception. An application must register an exception handler for each thread that is handling exceptions. When OS/2 terminates an application, however, a process-termination exception is sent to all threads used by the application to be terminated. When the user presses Ctrl+Break, an asynchronous signal exception is sent only to Thread 1, the main thread, of the executing process.

The exception handling routine is passed the following four parameters that provide exception-specific information:

EXCEPTIONREPORTRECORD
Describes the exception and its parameters. The first field of this data structure contains the number of the exception that occurred.
EXCEPTIONREGISTRATIONRECORD
The EXCEPTIONREGISTRATIONRECORD data structure used to initially register the exception handler. This is a microprocessor-specific value.
ContextRecord
Describes the machine state at the time the exception occurred.
DispatcherContext
Contains state information on nested exception and collided unwinds. This information must not be modified by the application.

Details of the parameters and data structures can be found in Exception Handler Interface.

OS/2 places the exception handlers for each thread in an exception handler chain. Registering an exception handler adds it to the head of the chain.

When an application registers an exception handler, the exception handler is added to the head of the chain. If the application calls a routine in a dynamic link library (DLL), the DLL might register an exception handler in case there is an exception while its code is executing; the DLL deregisters the exception handler before returning control to the application. The DLL's exception handler would be ahead of the application's exception handler in the chain.

Exception handlers in the chain are notified of an exception in Last-In-First-Out (LIFO) order. Thus, if an exception occurs while your thread is executing, the exception handler for your thread is notified of the exception first. If your exception handler chooses to handle the exception, the earlier exception handlers in the chain never see the exception. If your exception handler chooses not to handle the exception, it is passed along to the next earlier exception handler in the chain. If no exception handler in the chain chooses to handle the exception, OS/2 takes the default action for the exception.

If an exception happens while DLL code is executing, and if the DLL's exception handler chooses to handle the exception, your application's exception handlers will never be aware it.


System Exceptions

OS/2 defines a class of error conditions called system exceptions, and specifies the default actions that are taken when these system exceptions occur. The default action taken by OS/2 in most cases is to terminate the thread that caused the system exception.

System exceptions include both synchronous and asynchronous exceptions. Synchronous exceptions are caused by events that are internal to the execution of a thread. For example, synchronous exceptions could be caused by invalid parameters, or by the request of a thread to end its own execution.

Asynchronous exceptions are caused by events that are external to the execution of a thread. For example, an asynchronous exception can be caused by a user entering a Ctrl+C or Ctrl+Break key sequence, or by a process calling DosKillProcess to end the execution of another process.

The Ctrl+Break, Ctrl+C, and DosKillProcess-generated exceptions are also known as signals, or as signal exceptions.

OS/2 delivers exceptions that occur in 16-bit as well as 32-bit code. The sequence or hierarchy for delivering exceptions is as follows:

�When an exception occurs in 32-bit code, the system gives control only to the 32-bit exception handlers registered for the current thread. If the thread has not registered any 32-bit handlers, the system default action occurs.

�When an exception occurs in 16-bit code, the system first gives control to the 32-bit exception handlers registered for the current thread. If the exception is not handled by one of these handlers, control is passed to the 16-bit handler, if one exists for the given exception. If there is no 16-bit handler for the exception, the system default action occurs.

Notification of an exception is usually sent only to the thread that caused the exception. However, if a thread uses DosExit to terminate all the threads in the process, notification of the process-termination exception is sent to every thread in the process. The thread that used DosExit gets a XCPT_PROCESS_TERMINATE exception, all the other threads in the process get a XCPT_ASYNC_PROCESS_TERMINATE exception.

Exit-list processing occurs on a per-process basis after a process-termination exception has been delivered to each thread in the process and each thread has finally ended except Thread 1 (the main thread). Therefore, any thread that handles a process-termination exception must eventually end its own execution voluntarily. Otherwise, the process-termination sequence will not conclude properly.

The following tables briefly list the possible exceptions. For more detailed information about the system exceptions, including default system action, parameters, and related trap numbers, see the Control Program Programming Reference.

Non-Fatal, Software-Generated Exceptions

┌──────────────────────────────────────┬──────────────────────┐ │Exception Symbolic Constant │Description │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_GUARD_PAGE_VIOLATION │A guard page has been │ │ │accessed. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_UNABLE_TO_GROW_STACK │The system is unable │ │ │to allocate the memory│ │ │page directly below │ │ │the guard page just │ │ │accessed. │ └──────────────────────────────────────┴──────────────────────┘


Fatal, Software-Generated Exceptions

┌──────────────────────────────────────┬──────────────────────┐ │Exception Symbolic Constant │Description │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_IN_PAGE_ERROR │An I/O error occurred │ │ │while reading a memory│ │ │page into memory. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_PROCESS_TERMINATE │The thread has │ │ │terminated itself with│ │ │DosExit. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_ASYNC_PROCESS_TERMINATE │Another thread in the │ │ │process has caused the│ │ │thread to terminate. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_NONCONTINUABLE_EXCEPTION │An exception handler │ │ │has attempted to │ │ │continue execution in │ │ │response to a │ │ │non-continuable │ │ │exception. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_INVALID_DISPOSITION │An exception handler │ │ │has returned an │ │ │invalid value. │ └──────────────────────────────────────┴──────────────────────┘


Fatal, Hardware-Generated Exceptions

┌──────────────────────────────────────┬──────────────────────┐ │Exception Symbolic Constant │Description │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_ACCESS_VIOLATION │An access violation or│ │ │page fault has │ │ │occurred. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_INTEGER_DIVIDE_BY_ZERO │An attempt to divide │ │ │by 0 has occurred in │ │ │an integer operation. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_FLOAT_DIVIDE_BY_ZERO │An attempt to divide │ │ │by 0 has occurred in a│ │ │floating point │ │ │operation. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_FLOAT_INVALID_OPERATION │An invalid floating │ │ │point operation was │ │ │attempted. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_ILLEGAL_INSTRUCTION │An attempt was made to│ │ │execute an instruction│ │ │that is not defined on│ │ │the host machine's │ │ │architecture. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_PRIVILEGED_INSTRUCTION │An attempt was made to│ │ │execute an instruction│ │ │that is not permitted │ │ │in the current machine│ │ │mode or that the │ │ │application does not │ │ │have permission to │ │ │execute. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_INTEGER_OVERFLOW │An integer operation │ │ │generated a carry-out │ │ │of the most │ │ │significant bit. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_FLOAT_OVERFLOW │A floating point │ │ │operation generated a │ │ │resulting exponent │ │ │that is greater than │ │ │the magnitude │ │ │permitted for the │ │ │operands. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_FLOAT_UNDERFLOW │A floating point │ │ │operation generated a │ │ │resulting exponent │ │ │that is less than the │ │ │magnitude provided for│ │ │the operands. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_FLOAT_DENORMAL_OPERAND │An attempt was made to│ │ │perform an arithmetic │ │ │operation on a │ │ │denormal operand. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_FLOAT_INEXACT_RESULT │The result of an │ │ │operation is not │ │ │exactly representable │ │ │in the target format. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_FLOAT_STACK_CHECK │An illegal stack │ │ │operation was │ │ │attempted by the │ │ │floating point │ │ │coprocessor. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_DATATYPE_MISALIGNMENT │An attempt was made to│ │ │store a data in an │ │ │address that is not │ │ │naturally aligned on a│ │ │hardware architecture │ │ │that does not provide │ │ │alignment hardware. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_BREAKPOINT │A breakpoint │ │ │instruction was │ │ │executed. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_SINGLE_STEP │One instruction has │ │ │been executed in │ │ │single-step mode. │ └──────────────────────────────────────┴──────────────────────┘


Fatal Exceptions

┌──────────────────────────────────────┬──────────────────────┐ │Exception Symbolic Constant │Description │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_INVALID_LOCK_SEQUENCE │An invalid operation │ │ │was attempted within │ │ │an interlocked section│ │ │of code. │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_ARRAY_BOUNDS_EXCEEDED │An array index outside│ │ │its upper and lower │ │ │boundary was detected.│ └──────────────────────────────────────┴──────────────────────┘


Unwind Operation Exceptions

┌──────────────────────────────────────┬────────────────────────────┐ │Exception Symbolic Constant │Description │ ├──────────────────────────────────────┼────────────────────────────┤ │XCPT_UNWIND │An unwind operation is in │ │ │process. │ ├──────────────────────────────────────┼────────────────────────────┤ │XCPT_BAD_STACK │An │ │ │EXCEPTIONREGISTRATIONRECORD │ │ │data structure was reached │ │ │that is not properly aligned│ │ │or that is not within the │ │ │current stack boundaries. │ ├──────────────────────────────────────┼────────────────────────────┤ │XCPT_INVALID_UNWIND_TARGET │The address of the target │ │ │EXCEPTIONREGISTRATIONRECORD │ │ │is below the current stack │ │ │pointer or not in the │ │ │exception handler chain. │ └──────────────────────────────────────┴────────────────────────────┘


Fatal Signal Exceptions

┌──────────────────────────────────────┬──────────────────────┐ │Exception Symbolic Constant │Description │ ├──────────────────────────────────────┼──────────────────────┤ │XCPT_SIGNAL │A signal was made to │ │ │your process (usually │ │ │to stop). All the │ │ │signal exceptions │ │ │(Ctrl+Break, Ctrl+C, │ │ │and │ │ │XCPT_SIGNAL_KILLPROC) │ │ │come under this │ │ │exception. │ └──────────────────────────────────────┴──────────────────────┘


Signal Exceptions

Signal exceptions are special events sent to a thread when the user presses certain key sequences or when another thread or process explicitly initiates the exception. There are three types of signal exceptions:

XCPT_SIGNAL_BREAK
When the user presses Ctrl+Break
XCPT_SIGNAL_INTR
When the user presses Ctrl+C
XCPT_SIGNAL_KILLPROC
When another process uses DosKillProcess to send a XCPT_SIGNAL_KILLPROC exception to your process.

Signal exceptions are sent only to Thread 1 (the main thread) in the process receiving the exception. If an exception handler is registered on Thread 1, it must be prepared to receive signal exceptions. The thread 1 exception handler can always ignore the signal exception by returning XCPT_CONTINUE_SEARCH.

If the thread 1 exception handler is to receive signal exceptions, it must use DosSetSignalExceptionFocus to notify OS/2 that it wants to receive the XCPT_SIGNAL_INTR (Ctrl+C) and XCPT_SIGNAL_BREAK (Ctrl+Break) signals. Otherwise, these exceptions are not passed to the exception handler and the default action-to terminate the process-is taken by OS/2. The thread will get XCPT_SIGNAL_KILLPROC signals whether it uses DosSetSignalExceptionFocus or not.

All three of these signals are delivered by a single exception-XCPT_SIGNAL-and the exception handler for Thread 1 can choose to handle none, some, or all of the signals. The signal being sent can be determined by examining the exception information in EXCEPTIONREPORTRECORD.

The following table provides information about each type of signal.

Signal Exceptions

┌────────────┬──────────────────────────┬───────────────────────────┐ │Signal │Symbolic Constant │Description │ ├────────────┼──────────────────────────┼───────────────────────────┤ │Ctrl+Break │XCPT_SIGNAL_BREAK │This exception is sent to │ │ │ │Thread 1 in the current │ │ │ │keyboard-focus process when│ │ │ │a Ctrl+Break key sequence │ │ │ │is received from the │ │ │ │keyboard. The default │ │ │ │action taken by OS/2 for │ │ │ │this exception is forced │ │ │ │process termination. │ ├────────────┼──────────────────────────┼───────────────────────────┤ │Ctrl+C │XCPT_SIGNAL_INTR │This exception is sent to │ │ │ │Thread 1 in the current │ │ │ │keyboard-focus process when│ │ │ │a Ctrl+C key sequence is │ │ │ │received from the keyboard.│ │ │ │The default action taken by│ │ │ │OS/2 for this exception is │ │ │ │forced process termination.│ ├────────────┼──────────────────────────┼───────────────────────────┤ │Kill Process│XCPT_SIGNAL_KILLPROC │This exception is sent to │ │Signal │ │Thread 1 in the process │ │ │ │specified when an │ │ │ │application uses │ │ │ │DosKillProcess. The │ │ │ │XCPT_SIGNAL_KILLPROC signal│ │ │ │exception results from an │ │ │ │action external to the │ │ │ │process. The default action│ │ │ │taken by OS/2 for this │ │ │ │exception is forced process│ │ │ │termination. │ └────────────┴──────────────────────────┴───────────────────────────┘


Handling Signal Exceptions

Sending Signal Exceptions

Raising Exceptions

User-Defined Exceptions

Must-Complete Sections

Unwinding Exception Handlers

Nested Exit Lists

Process Exit Lists

Error Pop-Un Interface

Exception Handler Interface

Exception Handler Parameters

Exception Handler Data Structures

ExceptionReportRecord Data Structure

ExceptionRegisterRecord Data Structure

ContextRecord Data Structure

Exception Handler Return Values

Using Exception Management

Example Exception Handler

Registering an Exception Handler

System Exceptions