### Signal and Exception Handling Considerations

Considerations when registering a signal handler:

- You can register any function as a signal handler. Make sure you are registering a valid function.
- If your signal handler resides in a DLL, ensure that you change the signal handler when you unload the DLL. You will see no warnings or error messages if you unload the DLL without changing the handler, but your program will probably terminate the next time the handler is called. If another DLL has been loaded in the same address range, your program may continue but with undefined results.
- The SIGILL signal is not guaranteed to occur when you call an invalid function using a pointer. If the pointer points to a valid instruction stream, SIGILL is not raised.

Considerations when writing a signal handler:

- Your signal handler may call any non-critical C library functions, but not any critical functions . This is because critical functions are not reentrant. If such a function is on the stack at the time of the signal, reentering it may cause odd side effects or make your program fail.
- Your signal handler should not assume that SIGSEGV always implies an invalid data pointer. Other events, such as an address pointer to outside of your code segment, can raise this signal.
- The SIGILL signal is not guaranteed to occur when you call an invalid function using a pointer. If the pointer points to a valid instruction stream, SIGILL is not raised.
- When you call longjmp to leave a signal handler, be sure that the buffer you are jumping to was created by the thread that you are in. Do not call setjmp from one thread and longjmp from another. The IBM C and C++ Compilers library terminates a process where such a call is made.
- To protect internal data structures on OS/2, some library code is placed in must-complete sections. When a signal occurs, the library waits until such a section ends before it reports the signal. You can use the OS/2 API DosEnterMustComplete to create must-complete sections in your own code.
- Declare variables referenced by both the signal handler and by other code to be volatile, to ensure they are always updated when they are referenced.
- Because the ANSI draft of the C++ language does not specify the behavior of a throw statement in a signal handler, the most portable way to ensure that the appropriate destructors are called is to add statements to the setjmp location that will do a throw if necessary.
- If a file I/O routine from <stdio.h> is taking input from the console when an asynchronous signal (SIGINT, SIGBREAK, or SIGTERM) occurs, the behavior depends on whether a signal handler is registered. If no handler is registered, the input stream is terminated and the default signal action is taken. If a handler is registered, entry to the handler is deferred until the library routine returns.
- Do not use a C++ throw to exit a signal handler for signals SIGINT, SIGTERM, and SIGBREAK. When the signal is asynchronous, stack layout at the time of the signal may not permit clean stack unwind by the C++ exception handler code.

Considerations when writing exceptions

- Keep your exception handler simple and specific. Exception handlers are easier to write and maintain if you limit what they can do. Also, include a #pragma handler statement in every function in your executable module that can be called from a DLL. This directive generates the code to register the exception handler before the function runs, and to remove the exception handler when the function ends.
- Check for and handle only the exceptions that you expect to encounter, and allow the default exception handler to handle the unexpected. If the operating system adds new exceptions, or if you create your own, the default handler will handle them.
- Always check the exception flags to determine how the exception occurred. Any exception handler can be unwound by a subsequent handler.
- If you are using semaphores and an exception occurs while your code owns a semaphore, you must ensure that the semaphore is released. You can release the semaphore either by continuing the excecution or by explicitly releasing the semaphore in the signal handler.
- Your exception handler receives the exception registration record when an exception occurs. Do not use the return address of the calling function to tell the handler where to resume execution, because the values of the registers other than EBP (for example, EBX, EBI, and EDI) at the return are generally not available to your exception handler.
- You need approximately 1.5K of stack remaining for the operating system to be able to call your exception handler. If you do not have enough stack left, the operating system terminates your process.
- The IBM C and C++ Compilers default exception handler is not available in the subsystem libraries.
- Avoid using restricted OS/2 APIs because they can interfere with IBM C and C++ Compilers default exception handling.

C++ Exception Handling Overview
Signals and Exceptions
Signal and Exception Handling
Calling Conventions

Critical Functions