Rotor SEH
For the Rotor port me and Robert are working on my attention recently has been on working on the finer details of SEH within Rotor, as a backgrounder I recommend Chris Brummie's SEH article. Note that Chris's article details SEH in the sense of what Win32 provides, within Rotor in order to maintain an abstraction between the OS and the CLR SEH is handled within the PAL. When the PAL targets Win32 it makes use of the features witin the Win323 kernel, that the services for SEH. However when it targets another OS what happens then, as you can't say for sure what each OS might provide the PAL has to handle this its self. For this it could use C++ SEH, but for various (the finer details of which I will explain another time) reasons this is not ideal, instead the PAL has its own implementation. This implementation is split into a series of Macro's for runtime error's and functions to handle OS related errors that the host OS will bubble up to the PAL. To get an idea of what is different we can see the following.
try {
} except ( ExceptionFilter() ) {
}
In Win32 and in non Win32 we need to replace the above with
PAL_TRY {
} PAL_EXCEPT_FILTER(ExceptionFilter) {
} PAL_ENDTRY
Here we have a series of Macro's, PAL_TRY, PAL_EXCEPT_FILTER and PAL_ENDTRY. The PAL specification details these and other runtime SEH related Macro's. For porting to an OS does not require that you modify these, of course if you add something new to the SEH features then this is the code to start your approach :)
OS related errors are a little more involved, this portion of SEH translates OS signals into SEH errors. OS signals are used by the OS to notify a program or process of a failure or error, OS signals have been around for 30 years so most modern OS have them. The PAL spec details the following requirements for OS signals.
UNIX system-based style signal() handlers, or an equivalent mechanism for catching software errors such as accessing memory at an invalid address. The mechanism must be able to report back the CPU's registers at the time of the fault.
However does not detail what the OS signals are, here is a list of the required signals.
- SIGHUP: Hang up control or procss
- SIGINT: Interrupt from keyboard
- SIGQUIT: Quit from keyboard
- SIGILL: Illegal instruction
- SIGTRAP: Breakpoint for debugging
- SIGABRT: Abnormal termination
- SIGEMT: EMT error
- SIGFPE: Floating-point exception
- SIGBUS: Bus error
- SIGSEGV: Invalid memory referance
- SIGSYS: Bad system call
- SIGALRM: Real-timer clock
- SIGTERM: Process termination
- SIGURG: Urgent condition on socket
- SIGTSTP: Stop process issued frm tty
- SIGCONT: Resume execution if stopped
- SIGCHLD: Child process stopped or terminated
- SIGTTIN: Background process requires input
- SIGTTOU: Background process requires output
- SIGIO: I/O now possible
- SIGXCPU: CPU time limit exceeded
- SIGXFSZ: File size limit exceeded
- SIGVTALRM: Virtual timer clock
- SIGPROF: Profile timer clock
- SIGWINCH: Window resizing
Some of these signals are not POSIX signals, but some are so you will need to check that your target OS kernal can handle these signals, for Linux (as with most Unix systems) these signals are available. The PAL maps these signals when it starts via PAL_Initialize which calls SEHInitialize, this then calls SEHInitializeSignals which uses the handle_signal function to setup each signal in the list. Note that SEHInitializeSignals and handle_signal can be found in the signal.c file within the Exception folder in the Unix directory.