From b249cc5e26a5ec9adfc2f8fbb0b2778079741aa9 Mon Sep 17 00:00:00 2001 From: Dave Beazley Date: Fri, 16 Mar 2001 03:54:59 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@1053 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Tools/WAD/Papers/README | 8 + Tools/WAD/Papers/WADTalk.pdf | Bin 0 -> 385395 bytes Tools/WAD/Papers/fig1.png | Bin 0 -> 7965 bytes Tools/WAD/Papers/python.html | 860 +++++++++++++++++++++++++++ Tools/WAD/Papers/usenix2001.tex | 993 ++++++++++++++++++++++++++++++++ 5 files changed, 1861 insertions(+) create mode 100644 Tools/WAD/Papers/README create mode 100644 Tools/WAD/Papers/WADTalk.pdf create mode 100644 Tools/WAD/Papers/fig1.png create mode 100644 Tools/WAD/Papers/python.html create mode 100644 Tools/WAD/Papers/usenix2001.tex diff --git a/Tools/WAD/Papers/README b/Tools/WAD/Papers/README new file mode 100644 index 000000000..8cac04da5 --- /dev/null +++ b/Tools/WAD/Papers/README @@ -0,0 +1,8 @@ +This directory contains papers and information about WAD. + +python.html - WAD paper from Python9. +usenix2001.tex - USENIX 2001 Technical conference submission. + This paper was accepted, but the text has not yet + been updated to final copy. +WADTalk.pdf - Slides from the WAD Talk at Python9. + diff --git a/Tools/WAD/Papers/WADTalk.pdf b/Tools/WAD/Papers/WADTalk.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8ca120d93aa3707215d28c5d30ff73b54dd45f38 GIT binary patch literal 385395 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%0Dulc7UkuTGrgUaCgHcQ}U;InnKle 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 literal 0 HcmV?d00001 diff --git a/Tools/WAD/Papers/python.html b/Tools/WAD/Papers/python.html new file mode 100644 index 000000000..90282bcea --- /dev/null +++ b/Tools/WAD/Papers/python.html @@ -0,0 +1,860 @@ + + +WAD: A Module for Converting Fatal Extension Errors into Python Exceptions + + +

+ +

WAD: A Module for Converting Fatal Extension Errors into Python Exceptions

+
David M. Beazley
+Department of Computer Science
+University of Chicago
+Chicago, IL 60637
+beazley@cs.uchicago.edu
+
+
+ +

Abstract

+ +One of the more popular uses of Python is as an extension language for +applications written in compiled languages such as C, C++, and +Fortran. Unfortunately, one of the biggest drawbacks of this approach +is the lack of a useful debugging and error handling facility for +identifying problems in extension code. In part, this limitation is +due to the fact that Python does not know anything about the internal +implementation of an extension module. A more difficult problem is +that compiled extensions sometimes fail with catastrophic errors such +as memory access violations, failed assertions, and floating point +exceptions. These types of errors fall outside the realm of normal +Python exception handling and are particularly difficult to identify +and debug. Although traditional debuggers can find the location of a +fatal error, they are unable to report the context in which such an +error has occurred with respect to a Python script. This paper describes +an experimental system that converts fatal extension errors +into Python exceptions. In particular, a dynamically +loadable module, WAD (Wrapped Application Debugger), has been developed which catches +fatal errors, unwinds the call stack, and generates Python exceptions +with debugging information. WAD requires no modifications to Python, +works with all extension modules, and introduces no performance +overhead. An initial implementation of the system is currently +available for Sun SPARC Solaris and i386-Linux. + + + +

1. Introduction

+ +One of the primary reasons C, C++, and Fortran programmers are +attracted to Python is its ability to serve as an extension language +for compiled programs. Furthermore, tools such as SIP, CXX, Pyfort, FPIG, +and SWIG make it extremely easy for a programmer to ``wrap'' existing +software into an extension module [1,2,3,4,5]. Although this approach is +extremely attractive in terms of providing a highly usable and +flexible environment for users, extension modules suffer from +problems not normally associated with Python +scripts---especially when they don't work. + +

+Normally, Python programming errors result in an exception like this: + +

+% python foo.py
+Traceback (innermost last):
+  File "foo.py", line 11, in ?
+    foo()
+  File "foo.py", line 8, in foo
+    bar()
+  File "foo.py", line 5, in bar
+    spam()
+  File "foo.py", line 2, in spam
+    doh()
+NameError: doh
+% 
+
+ +Unfortunately for compiled extensions, the following situation sometimes occurs: + +
+% python foo.py
+Segmentation Fault (core dumped)
+%
+
+ +Needless to say, this isn't very informative--well, +other than indicating that something ``very bad'' happened. + +

+In order to identify the source of a fatal error, a programmer can run a +debugger on the Python executable or on a core file like this: + +

+% gdb /usr/local/bin/python
+(gdb) run foo.py
+Starting program: /usr/local/bin/python foo.py
+
+Program received signal SIGSEGV, Segmentation fault.
+0xff060568 in doh () from /u0/beazley/Projects/WAD/Python/./libfoo.so
+(gdb) where
+#0  0xff060568 in doh () from /u0/beazley/Projects/WAD/Python/./libfoo.so
+#1  0xff082f34 in _wrap_doh ()
+   from /u0/beazley/Projects/WAD/Python/./dohmodule.so
+#2  0x2777c in call_builtin (func=0x1984b8, arg=0x1a1ccc, kw=0x0)
+    at ceval.c:2650
+#3  0x27648 in PyEval_CallObjectWithKeywords (func=0x1984b8, arg=0x1a1ccc,
+    kw=0x0) at ceval.c:2618
+#4  0x25d18 in eval_code2 (co=0x19acf8, globals=0x0, locals=0x1c7844,
+    args=0x1984b8, argcount=1625472, kws=0x0, kwcount=0, defs=0x0, defcount=0,
+    owner=0x0) at ceval.c:1951
+#5  0x25954 in eval_code2 (co=0x199620, globals=0x0, locals=0x1984b8,
+    args=0x196654, argcount=1862720, kws=0x197788, kwcount=0, defs=0x0,
+#6  0x25954 in eval_code2 (co=0x19ad38, globals=0x0, locals=0x196654,
+    args=0x1962fc, argcount=1862800, kws=0x198e90, kwcount=0, defs=0x0,
+    defcount=0, owner=0x0) at ceval.c:1850
+#7  0x25954 in eval_code2 (co=0x1b6c60, globals=0x0, locals=0x1962fc,
+    args=0x1a1eb4, argcount=1862920, kws=0x0, kwcount=0, defs=0x0, defcount=0,
+    owner=0x0) at ceval.c:1850
+#8  0x22da4 in PyEval_EvalCode (co=0x1b6c60, globals=0x1962c4, locals=0x1962c4)
+    at ceval.c:319
+#9  0x3adb4 in run_node (n=0x18abf8, filename=0x1b6c60 "", globals=0x1962c4,
+    locals=0x1962c4) at pythonrun.c:886
+#10 0x3ad64 in run_err_node (n=0x18abf8, filename=0x1b6c60 "",
+    globals=0x1962c4, locals=0x1962c4) at pythonrun.c:874
+#11 0x3ad38 in PyRun_FileEx (fp=0x18a5a8, filename=0xffbefd7a "foo.py",
+    start=1616888, globals=0x1962c4, locals=0x1962c4, closeit=1)
+    at pythonrun.c:866
+#12 0x3a1d8 in PyRun_SimpleFileEx (fp=0x18a5a8, filename=0xffbefd7a "foo.py",
+    closeit=1) at pythonrun.c:579
+#13 0x39d84 in PyRun_AnyFileEx (fp=0x18a5a8, filename=0xffbefd7a "foo.py",
+    closeit=1) at pythonrun.c:459
+#14 0x1f498 in Py_Main (argc=2, argv=0xffbefc84) at main.c:289
+#15 0x1eec0 in main (argc=2, argv=0xffbefc84) at python.c:10
+
+ +Unfortunately, even though the debugger identifies the location where the fault occurred, it +mostly provides information about the internals of the +interpreter. The debugger certainly doesn't reveal anything about the Python +program that led to the error (i.e., it doesn't reveal the +same information that would be contained in a Python traceback). As a result, +the debugger is of limited use when it comes to debugging an application that +consists of both compiled and Python code. + +

+Normally, extension developers try to avoid catastrophic errors by +adding error handling. If +an application is small or customized for use with Python, it can be +modified to raise Python exceptions. +Automated tools such as SWIG can also convert C++ +exceptions and C-related error handling mechanisms into Python +exceptions. However, no matter how much error checking is added, +there is always a chance that an extension will fail in an unexpected +manner. This is especially true for large applications that have been wrapped +into an extension module. In addition, certain types of errors such as floating +point exceptions (e.g., division by zero) are especially difficult to find +and eliminate. Finally, rigorous error checking may be omitted to improve +performance. + +

+To address these problems, an experimental module known as WAD (Wrapped +Application Debugger) has been developed. +WAD is able to +convert fatal errors into Python exceptions that include information +from the call stack as well as debugging +information. By turning such errors into Python exceptions, fatal +errors now result in a traceback that crosses the boundary between +Python code and compiled extension code. This makes it much +easier to identify and correct extension-related programming errors. +WAD requires no modifications to Python and is compatible with all +extension modules. However, it is also highly platform specific +and currently only runs on Sun Sparc +Solaris and i386-Linux. The primary goal of this paper is to motivate the problem +and to describe one possible solution. In addition, many of the +implementation issues +associated with providing an integrated error reporting mechanism are described. + +

2. An Example

+ +WAD can either be imported as a Python extension module or linked to an +extension module. To illustrate, consider the earlier example: + +
+% python foo.py
+Segmentation Fault (core dumped)
+%
+
+ +To identify the problem, a programmer can run Python interactively and import WAD as follows: + +
+% python
+Python 2.0 (#1, Oct 27 2000, 14:34:45) 
+[GCC 2.95.2 19991024 (release)] on sunos5
+Type "copyright", "credits" or "license" for more information.
+>>> import libwadpy
+WAD Enabled
+>>> execfile("foo.py")
+Traceback (most recent call last):
+  File "", line 1, in ?
+  File "foo.py", line 16, in ?
+    foo()
+  File "foo.py", line 13, in foo
+    bar()
+  File "foo.py", line 10, in bar
+    spam()
+  File "foo.py", line 7, in spam
+    doh.doh(a,b,c)
+SegFault: [ C stack trace ]
+
+#2   0x00027774 in call_builtin(func=0x1c74f0,arg=0x1a1ccc,kw=0x0)
+#1   0xff022f7c in _wrap_doh(0x0,0x1a1ccc,0x160ef4,0x9c,0x56b44,0x1aa3d8)
+#0   0xfe7e0568 in doh(a=0x3,b=0x4,c=0x0) in 'foo.c', line 28
+
+/u0/beazley/Projects/WAD/Python/foo.c, line 28
+
+    int doh(int a, int b, int *c) {
+ =>   *c = a + b;
+      return *c;
+    }
+
+>>>
+
+ +In this case, we can +see that the program has tried to assign a value to a +NULL pointer (indicated by the value "c=0x0" in the last function call). Furthermore, we obtain a Python traceback that shows the +entire sequence of functions leading to the problem. Finally, since +control returned to the interpreter, it is possible to interactively +inspect various aspects of the application or to continue with the computation +(although this clearly depends on the severity of the error and the nature of the application). + +

+In certain applications, it may be difficult to run Python +interactively or to modify the code to explicitly import a special +debugging module. In these cases, WAD can be attached to an extension module with the +linker. For example: + +

+% ld -G $(OBJS) -o dohmodule.so -lwadpy
+
+ +This requires no recompilation of any source code--only a relinking of the +extension module. When Python loads the relinked extension module, WAD is automatically +initialized before Python invokes the module initialization function. + +

3. Design Considerations for Embedded Error Recovery

+ +The primary design goal of WAD is provide an error reporting mechanism +for extension modules that is a natural extension of normal Python +exception handling. There are two primary motivations for +handling fatal errors in this manner: first, in the context of Python +programming, it is simply unnatural to run a separate debugging +application to identify a problem in an extension module when no such +requirement exists for scripts. Thus, an embedded error reporting +mechanism is simply more convenient. Second, the target users +of an extension module may not know how to use a debugger or even have +a development environment installed on their machine. Therefore, +the ability to produce an informative traceback within the +confines of the Python interpreter can be of tremendous value to an +extension developer. This is because users who report a problem will +be able to include an informative traceback as opposed to simply +saying ``the code crashed.'' + +

+A secondary design goal is to provide a system that is as non-invasive +as possible. The system should not require modifications to Python or +any extension modules and it should be easy to integrate +into the runtime environment of an application. In addition, it shouldn't +introduce any performance overhead. + +

+Finally, since WAD co-exists with the Python interpreter (i.e., in the same +process), there are a number of technical issues that have to be +addressed. First, fatal errors can theoretically occur anywhere in +the interpreter as well as in extension modules. Therefore, WAD needs +to know about Python's internal organization if it is going to provide +a graceful recovery back to the interpreter. Second, in order to +implement this recovery scheme, the system has to perform direct +manipulation of the CPU context and call stack. Last, but not least, +since the recovery code lives in the same address space as the +interpreter and extension modules it should not depend on the process +stack and heap (since both could have been corrupted by the faulting +application). + +

4. Catching Fatal Errors

+ +WAD catches catastrophic errors by installing a +reliable signal handler for SIGSEGV, SIGBUS, SIGABRT, SIGILL, and SIGFPE [9]. Unlike the +more familiar BSD-style signal interface (as provided by the Python +signal module), reliable signal handlers are installed using the sigaction() system call and have a few notable properties: + +
    +
  • The signal handler can be configured to run on its own dedicated stack. + +

    +

  • Handler functions can receive a structure containing the CPU context +including the CPU registers, program counter, and stack pointer. + +

    +

  • Changes to the CPU context take effect immediately after the signal handler returns. +
+ +Therefore, the high level implementation of WAD is relatively straightforward: when a fatal signal occurs, +a handler function runs on an isolated signal handling stack. +The CPU context is then used to unwind the call stack and to inspect the process state. Finally, +if possible, the CPU context is modified in a manner that allows the signal handler to +return to Python with a raised exception. + +

5. A Detailed Description of the Recovery Mechanism

+ +In this section, a more detailed description of the error recovery +scheme is presented. The precise implementation details of this are +highly platform specific and involve a number of advanced topics including +the Unix process file system (/proc), the ELF object file format, and the +Stabs compiler debugging format [6,7,8]. The details of these topics are +beyond the scope of this paper. However, this section hopes to +give the reader a small taste of the steps involved in implementing the recovery mechanism. + +

+The services of WAD are only invoked upon the reception of a fatal +signal. This triggers a signal handling function that results in a return to Python +as illustrated in the following figure: + +

+ +
Control flow of the error recovery mechanism
+
+ +

+The steps required to implement this recovery are as follows: + +

    +
  1. The values of the program counter and stack pointer are obtained from the CPU + context structure passed to the WAD signal handler. + +

    +

  2. The virtual memory map of the process is inspected to identify all of +the shared libraries, dynamically loaded modules, and valid memory regions. +This information is obtained by reading from the Unix /proc filesystem. +The following table illustrates the nature of this data: + + +
    +Address     Size    Permissions        File
    +----------  -----   -----------------  ---------------------------------
    +00010000    1264K   read/exec         /usr/local/bin/python 
    +0015A000     184K   read/write/exec   /usr/local/bin/python 
    +00188000     296K   read/write/exec     [ heap ] 
    +FE7C0000      32K   read/exec         /u0/beazley/Projects/dohmodule.so 
    +FE7D6000       8K   read/write/exec   /u0/beazley/Projects/dohmodule.so 
    +...
    +FF100000     664K   read/exec         /usr/lib/libc.so.1 
    +FF1B6000      24K   read/write/exec   /usr/lib/libc.so.1 
    +FF1BC000       8K   read/write/exec   /usr/lib/libc.so.1 
    +FF2C0000     120K   read/exec         /usr/lib/libthread.so.1 
    +FF2EE000       8K   read/write/exec   /usr/lib/libthread.so.1 
    +FF2F0000      48K   read/write/exec   /usr/lib/libthread.so.1 
    +FF310000      40K   read/exec         /usr/lib/libsocket.so.1 
    +FF32A000       8K   read/write/exec   /usr/lib/libsocket.so.1 
    +FF330000      24K   read/exec         /usr/lib/libpthread.so.1 
    +FF346000       8K   read/write/exec   /usr/lib/libpthread.so.1 
    +FF350000       8K   read/write/exec    [ anon ] 
    +FF3B0000       8K   read/exec         /usr/lib/libdl.so.1 
    +FF3C0000     128K   read/exec         /usr/lib/ld.so.1 
    +FF3E0000       8K   read/write/exec   /usr/lib/ld.so.1 
    +FFBEA000      24K   read/write/exec    [ stack ] 
    +
    + +

    +

  3. The call stack is unwound to produce a traceback of the +calling sequence that led to the error. The unwinding process is just a simple +loop that is similar to the following: + +
    +long *pc = get_pc(context);
    +long *sp = get_sp(context);
    +while (sp) {
    +    /* Move to previous stack frame */
    +    pc = (long *) sp[15];      /* %i7 register on SPARC */
    +    sp = (long *) sp[14];      /* %i6 register on SPARC */
    +}
    +
    + +
  4. For each stack frame, symbol table and debugging information +is gathered and stored in a WAD exception frame object. +Obtaining this information is the most complicated part of WAD and involves +the following steps: first, the current program counter is mapped to an object file +using the virtual memory map obtained in step 2. Next, the object file is loaded +using mmap(). Once loaded, the ELF symbol table +is searched for an address match. The symbol table contains a collection of records +containing memory offsets, sizes, and names such as this: + +
    +Offset    Size    Name 
    +--------  ------  ---------
    +0x1280    324     wrap_foo
    +0x1600    128     foo
    +0x2408    192     bar
    +...
    +
    + +To find a match for a virtual memory address addr, WAD simply +searches for a symbol s such that base + +s.offset <= addr < base + +s.offset + s.size, where base is the base +virtual address of the object file in the virtual memory map. + +

    +Debugging information, if available, is scanned to identify a source +file, function name, and line number. This involves scanning object files for a +table of debugging information stored in a format +known as ``stabs.''. Stabs is a relatively simple, but highly extensible format that +is language independent and capable of encoding almost every aspect of the +original source code. For the purposes of WAD, only a small subset of this +data is actually used. + +

    +The following table shows a small fragment of relevant stabs data: +

    +type    desc   value        string                        description
    +------  -----  ---------    ---------------------------   -----------
    +0x64      0        0         /u0/beazley/Projects/foo/    Pathname
    +0x64      0        0        foo.c                         Filename
    +...                             
    +0x24      0        0        foo:F(0,3);(0,3)              Function
    +0xa0      4        68       n:p(0,3)                      Parameter
    +...                                                      
    +0x44      6        8                                      Line number
    +0x44      7        12                                     Line number
    +0x44      8        44                                     Line number
    +0x44      9        56                                     Line number
    +...                                                      
    +
    + +In the table, the type field indicates the type of debugging information. For +example, 0x64 specifies the source file, 0x24 is a function +definition, 0xa0 is a function parameter, and 0x44 is line number +information. Associated with each stab is a collection of parameters +and an optional string. The string usually contains symbol names and +other information. The desc and value fields are numbers +that usually contain byte offsets and line number data. +Therefore, to collect debugging information, WAD simply walks through the debugging +tables until it finds the function of interest. Once found, parameter and line +number specifiers are inspected to determine the location and values of the function +arguments as well the source line at which the error occurred. + +

    +

  5. After the complete traceback has been obtained, it is examined to see if +there are any ``safe'' return points to which control can be returned. +This is accomplished by maintaining an internal table of predefined symbolic return +points as shown in the following table: + +
    +Python symbol                     Return value
    +-----------------------------     ------------------
    +call_builtin                      NULL
    +_PyImport_LoadDynamicModule       NULL
    +PyObject_Repr                     NULL
    +PyObject_Print                    -1
    +PyObject_CallFunction             NULL
    +PyObject_CallMethod               NULL
    +PyObject_CallObject               NULL
    +PyObject_Cmp                      -1
    +PyObject_Compare                  -1
    +PyObject_DelAttrString            -1
    +PyObject_DelItem                  -1
    +PyObject_GetAttrString            NULL
    +PyObject_GetItem                  NULL
    +PyObject_HasAttrString            -1
    +PyObject_Hash                     -1
    +PyObject_Length                   -1
    +PyObject_SetAttrString            -1
    +PyObject_SetItem                  -1
    +PyObject_Str                      NULL
    +PyObject_Type                     NULL
    +...
    +PyEval_EvalCode                   NULL
    +
    + +The symbols in this table correspond to functions within the Python interpreter that +might execute extension code and include the parts of the interpreter that invoke builtin functions +as well as the functions from the abstract object interface. +If any of these symbols appear on the call stack, +a handler function is invoked to raise a Python exception. +This handler function +is given a WAD-specific traceback object that contains a copy of the +call stack and CPU registers as well as any symbolic and debugging +information that was obtained. If none of the symbolic return points +are encountered, WAD invokes a default handler that simply prints the +full C stack trace and generates a core file. + +

    +

  6. If a return point is found, the CPU context is modified in a manner that allows the signal handler to return + with a suitable Python error. + This last step is the most tricky part of the recovery process, but the general + idea is that CPU context is modified in a way that makes Python think that + an extension function simply raised an exception and returned an error. Currently, this + is implemented by having the signal handler return to a small + handler function written in assembly language which arranges to return the + desired value back to the specified return point. + +

    + The most complicated part of modifying the CPU context is that of restoring + previously saved CPU registers. By manually unwinding the call stack, the + WAD exception handler effectively performs the same operation as a longjmp() call in C. + However, unlike longjmp(), no previously saved set of CPU registers are available from which to resume + execution in the Python interpreter. The solution to this problem depends entirely on the + underlying architecture. On the SPARC, register values are saved in register windows + which WAD manually unwinds to restore the proper state. On the Intel, the solution is much + more interesting. To restore the register values, WAD must manually inspect the + machine instructions of each function on the call stack in order to find out where the + registers might have been saved. This information is then used to restore the registers from their + saved locations before returning to the Python interpreter. + +

    +

  7. Python receives the exception and produces a traceback. +
+ +

6. Initialization and Loading

+ +In the earlier example, it was shown that WAD could be both +loaded as an extension module or simply attached to an existing module +with the linker. This latter case is implemented by +wrapping the WAD initialization function inside the constructor of a +statically allocated C++ object like this: + +
+
+class WadInit {
+public:
+    WadInit() {
+        wad_init();   /* Call the real initialization function */
+    }
+};
+static WadInit wad_initializer;
+
+ +When the dynamic loader brings WAD into memory, it automatically +executes the constructors of all statically allocated C++ objects. +Therefore, this initialization code executes immediately after +loading, but before Python actually calls the module initialization +function. As a result, when an extension module is linked with WAD, +the debugging capability is enabled before any other operations occur---this +allows WAD to respond to fatal errors that might occur during module +initialization. + +The rest of the initialization process consists of the following: +
    +
  • The WAD signal handler is installed. +
  • A collection of return symbols are registered with the signal handler (see the previous section). +
  • Four new Python exception objects SegFault, BusError, AbortError, +and IllegalInstruction are added +to the __builtin__ module. +
+ +Although the use of a C++ static constructor has the potential to +conflict with C++ extension code that also uses static constructors, +it is always possible to enable WAD prior to loading a C++ extension +(e.g., WAD could be loaded separately). + +

7. Implementation Details

+ +Currently, WAD is written in ANSI C with a small amount of C++, +and a small amount of assembly code (to assist in the return to the interpreter). +The entire implementation contains approximately 2000 semicolons and most of the code +relates to the gathering of source code information (symbol tables, +debugging information, etc.). + +

+Although there are libraries such as GNU bfd that can assist with the +reading of object files, none of these are used in the implementation [10]. +First, these libraries tend to be quite large +and are oriented more towards stand-alone tools such as debuggers, +linkers, and compilers. Second, due to usual nature of the runtime +environment and the restrictions on memory utilization (no heap, no +stack), the behavior of these libraries is somewhat unclear and +would require further study. +Finally, given the small size of the prototype implementation, it didn't seem necessary to rely on a +large general purpose library. + +

8. Discussion

+ +The primary focus of this work is to provide a more useful error +reporting mechanism to extension developers. +However, this does not imply that +WAD is appropriate as a general purpose exception +handling mechanism. First, let's focus +on the recovery mechanism: + +
    +
  • When WAD unwinds the call stack, objects allocated on the stack +are lost. This may interact poorly with C++ extensions since the +unwinding process does not invoke C++ destructors. It may be possible to fix +this problem, but doing so would require coordination with the C++ runtime library. + +

    +

  • Similarly, if a procedure allocates objects on the heap, stack unwinding +may cause those objects to never be reclaimed. + +

    +

  • Closely related to heap management, stack unwinding may result in +open files, sockets, and other system resources. Furthermore, in a multithreaded +environment, deadlock may occur if a procedure is holding a lock when an error occurs. + +

    +

  • An application may fail by overwriting the process heap and corrupting +memory. Although WAD can produce internal diagnostics even when the heap has been +destroyed, Python may fail immediately upon return from the +WAD signal handler or shortly thereafter. + +

    +

  • If an application destroys the call stack (via buffer overflow), WAD will +be unable to complete a stack trace and will be unable to return to +Python. + +

    +

  • Memory management problems such as double-freeing of memory are particularly +difficult to identify. If an extension module corrupts the memory allocator +in some manner, this may cause Python to fail in a completely unexpected location. +WAD is usually able to produce a traceback in this situation, but +it may not correspond to the real source of the problem. + +
+ +In addition, there are a number of issues that pertain to WAD's interaction with the +Python interpreter: + +
    +
  • The recovery mechanism is entirely based on symbolic information stored +in the Python executable. Therefore, the return points are simply specified +as strings such as ``call_builtin'' as opposed to real memory addresses. +Because of this, WAD is compatible with essentially any version of Python (provided +it supports class-based exceptions). + +

    +

  • WAD is unable to manage multiple return values to same procedure. +For example, Python's eval_code2() procedure contains a huge +case statement for executing byte codes. Within this procedure, certain +function calls return NULL to indicate an error and others return -1. Since WAD +is unable to determine which value to return, this particular procedure does not make a very +good return point for error recovery. + +

    +

  • An alternative approach to the symbolic recovery scheme would be to +instrument Python with a collection of safe return points using setjmp()/longjmp(). +This approach is not used because it would require a significant number of changes to +the interpreter and it would introduce an unacceptable amount of performance overhead. + +

    +

  • WAD is generally safe to use with Python threads. However, if a +compiled extension function manually releases the Python interpreter +lock and subsequently faults, the return behavior is unspecified. In +the future, it may be possible to use the interpreter lock to provide coordination +between the interpreter and the error recovery mechanism. + +

    +

  • Compiled extension code may perform an eval operation in which Python code is executed +in the interpreter. This results in a situation where the complete call-stack of an +application crosses the boundary between Python and C several times. WAD can +still handle faults in this setting as long as an application is doing a reasonable amount of +error checking. For example, a fatal error that occurs inside an eval operation could +be caught by the extension code and propagated further up the call stack. + +

    +

  • In certain cases, Python may be configured to handle the SIGFPE signal for floating point +exceptions. The default Python handling of this error is to abort and dump core. However, +with WAD, a complete stack traceback will be obtained when a SIGFPE occurs. + +

    +

  • WAD is extremely inefficient. Due to restrictions on the heap and stack, +WAD relies heavily on mmap() and a variety of other file +operations as it handles errors. It also performs linear searches of symbol and +debugging tables. As a result, WAD's generation of a +Python exception is several orders of magnitude slower than an ordinary +exception. +
+ +Finally, there are a number of application specific issues to note: + +
    +
  • Aggressive compiler optimization techniques may prevent WAD from +accurately reporting locations within the original source code. +This is particularly problematic with numerical applications where +techniques such procedure inlining can make it impossible to obtain accurate +debugging information. Since these types of problems also arise in +full-featured debuggers, it is unlikely that they can be easily fixed in WAD (at least not +without a considerable amount of work). + +

    +

  • If an application implements its own exception handling, +it may provide Python with less information than what would obtained with WAD. +For example, a programmer might implement a function like this: + +
    +void *Malloc(int size) {
    +   void *ptr;
    +   ptr = malloc(size);
    +   if (!ptr) throw("Out of memory");
    +   return ptr;
    +}
    +
    + +In this case, the ``throw'' function may initiate an internal +exception handling mechanism that relies upon setjmp/longjmp or C++ exceptions. +When the error eventually makes it back to the interpreter, the user will get an ``out +of memory'' exception, but no additional information will be +provided. In contrast, if the programmer simply used an assert() statement, WAD would produce a full stack trace leading to +the error. +
+ + +Despite its various limitations, WAD is applicable to a wide range of +extension-related errors. Furthermore, most of the errors that are +likely to occur are of a more benign variety. For example, a +segmentation fault may simply be the result of an uninitialized +pointer (perhaps the user forgot to call an initialization procedure). +Likewise, bus errors, failed assertions, and floating point exceptions +rarely result in a situation where the WAD recovery mechanism would be +unable to produce a meaningful Python traceback. + +

9. Related Work

+ +There is a huge body of literature concerning the implementation of +exception handling in various programming languages and environments. +A detailed discussion of this work is clearly not possible here, but +a general overview of various exception handling issues can be found in [11]. +In general, there are a few themes that seem to prevail. +First, +considerable attention has been given to exception handling mechanisms +in specific languages such as efficient exception handling for C++. +Second, a great deal of work has been given to the semantic aspects of +exception handling such as exception hierarchies, finalization, and +whether or not code is restartable after an exception has occurred. +Finally, a fair amount of exception work has been done in the context +of component frameworks and distributed systems. Most of this work +tends to concentrate on explicit exception handling mechanisms. Very little +work appears to have been done in the area of converting hardware generated errors +into exceptions. + +

+With respect to debuggers, quite a lot of work has been done in +creating advanced debugging support for specific languages and +integrated development environments. However, very little of this work +has concentrated on the problem of extensible systems and +compiled-interpreted language integration. For instance, debuggers +for Python are currently unable to cross over into C extensions whereas C +debuggers aren't able to easily extract useful information from the +internals of the Python interpreter. + +

+One system of possible interest is Rn which was developed in the +mid-1980s at Rice University [12]. This system, primarily +designed for working with large scientific applications written in +Fortran, provided an execution monitor that consisted of a special +debugging process with an embedded interpreter. When attached to +compiled Fortran code, this monitor could dynamically patch +the executable in a manner that allowed parts of the code to be executed in the +interpreter. This was used to provide a debugging environment in which +essentially any part of the compiled application could be modified at +run-time by simply compiling the modified code (Fortran) to an +interpreted form and inserting a breakpoint in the original executable +that transferred control to the interpreter. Although this +particular scheme is not directly related to the functionality +of WAD, it is one of the few systems in which +interpreted and compiled code have been tightly coupled within +a debugging framework. Several aspects of the interpreted/compiled +interface are closely related to way in which WAD operates. In addition, +various aspects of this work may be useful should WAD be extended with +new capabilities. + +

10. Future Directions

+ +WAD is currently an experimental prototype. Although this paper has +described its use with Python, the core of the system is generic and +is easily extended to other programming environments. For example, when +linked to C/C++ code, WAD will automatically produce stack +traces for fatal errors. A module for generating Tcl exceptions has +also been developed. Plans are underway to provide support for other +extensible systems including Perl, Ruby, and Guile. + +

+Finally, a number of extensions to the WAD approach may be possible. +For example, even though the current implementation only returns a +traceback string to the Python interpreter, the WAD signal handler +actually generates a full traceback of the C call stack including all +of the CPU registers and a copy of the stack data. Therefore, with a +little work, it may be possible to implement a diagnostic tool that +allows the state of the C stack to be inspected from the Python +interpreter after a crash has occurred. Similarly, it may be possible +to integrate the capabilities of WAD with those provided by the Python +debugger. + +

11. Conclusions and Availability

+ +WAD provides a simple mechanism for converting fatal errors into +Python exceptions that provide useful information to extension +writers. In doing so, it solves one of the most frustrating aspects +of working with compiled Python extensions--that of identifying program errors. +Furthermore the system requires no code modifications to Python and introduces +no performance overhead. +Although the system is +necessarily platform specific, the system does not involve a +significant amount of code. As a result, it may be relatively +straightforward to port to other Unix systems. + +

+As of this writing, WAD is still undergoing active development. However, +the software is available for experimentation and download at +at http://systems.cs.uchicago.edu/wad. + +

References

+ +[1] D.M. Beazley, Using SWIG to Control, Prototype, and Debug C Programs with Python, +4th International Python Conference, Livermore, CA. (1996). + +

+[2] P.F. Dubois, Climate Data Analysis Software, 8th International Python Conference, +Arlington, VA. (2000). + +

+[3] P.F. Dubois, A Facility for Creating Python Extensions in C++, 7th International Python +Conference, Houston, TX. (1998). + +

+[4] SIP. http://www.thekompany.com/projects/pykde/. + +

+[5] FPIG. http://cens.ioc.ee/projects/f2py2e/. + +

+[6] R. Faulkner and R. Gomes, The Process File System and Process Model in UNIX System V, USENIX Conference Proceedings, +January 1991. + +

+[7] J.R. Levine, Linkers & Loaders. Morgan Kaufmann Publishers, 2000. + +

+[8] Free Software Foundation, The "stabs" debugging format. GNU info document. + +

+[9] W. Richard Stevens, UNIX Network Programming: Interprocess Communication, Volume 2. PTR +Prentice-Hall, 1998. + +

+[10] S. Chamberlain. libbfd: The Binary File Descriptor Library. Cygnus Support, bfd version 3.0 edition, April 1991. + +

+[11] M.L. Scott. Programming Languages Pragmatics. Morgan Kaufmann Publishers, 2000. + +

+[12] A. Carle, D. Cooper, R. Hood, K. Kennedy, L. Torczon, S. Warren, A Practical Environment for Scientific Programming. +IEEE Computer, Vol 20, No. 11, (1987). p. 75-89. + + + + + + + + + + + + diff --git a/Tools/WAD/Papers/usenix2001.tex b/Tools/WAD/Papers/usenix2001.tex new file mode 100644 index 000000000..6fa05fcec --- /dev/null +++ b/Tools/WAD/Papers/usenix2001.tex @@ -0,0 +1,993 @@ +%template for producing IEEE-format articles using LaTeX. +%written by Matthew Ward, CS Department, Worcester Polytechnic Institute. +%use at your own risk. Complaints to /dev/null. +%make two column with no page numbering, default is 10 point +%\documentstyle{article} +\documentstyle[twocolumn]{article} +%\pagestyle{empty} + +%set dimensions of columns, gap between columns, and space between paragraphs +%\setlength{\textheight}{8.75in} +\setlength{\textheight}{9.0in} +\setlength{\columnsep}{0.25in} +\setlength{\textwidth}{6.45in} +\setlength{\footheight}{0.0in} +\setlength{\topmargin}{0.0in} +\setlength{\headheight}{0.0in} +\setlength{\headsep}{0.0in} +\setlength{\oddsidemargin}{0in} +%\setlength{\oddsidemargin}{-.065in} +%\setlength{\oddsidemargin}{-.17in} +%\setlength{\parindent}{0pc} + +%I copied stuff out of art10.sty and modified them to conform to IEEE format + +\makeatletter +%as Latex considers descenders in its calculation of interline spacing, +%to get 12 point spacing for normalsize text, must set it to 10 points +\def\@normalsize{\@setsize\normalsize{12pt}\xpt\@xpt +\abovedisplayskip 10pt plus2pt minus5pt\belowdisplayskip \abovedisplayskip +\abovedisplayshortskip \z@ plus3pt\belowdisplayshortskip 6pt plus3pt +minus3pt\let\@listi\@listI} + +%need an 11 pt font size for subsection and abstract headings +\def\subsize{\@setsize\subsize{12pt}\xipt\@xipt} + +%make section titles bold and 12 point, 2 blank lines before, 1 after +\def\section{\@startsection {section}{1}{\z@}{24pt plus 2pt minus 2pt} +{12pt plus 2pt minus 2pt}{\large\bf}} + +%make subsection titles bold and 11 point, 1 blank line before, 1 after +\def\subsection{\@startsection {subsection}{2}{\z@}{12pt plus 2pt minus 2pt} +{12pt plus 2pt minus 2pt}{\subsize\bf}} +\makeatother + +\newcommand{\ignore}[1]{} +%\renewcommand{\thesubsection}{\arabic{subsection}.} + +\begin{document} + +%don't want date printed +\date{} + +%make title bold and 14 pt font (Latex default is non-bold, 16 pt) +\title{\Large \bf An Embedded Error Recovery and Debugging Mechanism for Scripting Language Extensions} + +%for single author (just remove % characters) +\author{{David M.\ Beazley} \\ +{\em Department of Computer Science} \\ +{\em University of Chicago }\\ +{\em Chicago, Illinois 60637 }\\ +{\em beazley@cs.uchicago.edu }} + +% My Department \\ +% My Institute \\ +% My City, ST, zip} + +%for two authors (this is what is printed) +%\author{\begin{tabular}[t]{c@{\extracolsep{8em}}c} +% Roscoe Giles & Pablo Tamayo \\ +% \\ +% Department of Electrical, Computer, & Thinking Machines Corp. \\ +% and Systems Engineering & Cambridge, MA~~02142. \\ +% and & \\ +% Center for Computational Science & \\ +% Boston University, Boston, MA~~02215. & +%\end{tabular}} + +\maketitle + +%I don't know why I have to reset thispagesyle, but otherwise get page numbers +\thispagestyle{empty} + + +\subsection*{Abstract} +{\em +In recent years, scripting languages such as Perl, Python, and Tcl +have become popular development tools for the creation of +sophisticated application software. One of the most useful features +of these languages is their ability to easily interact with compiled +languages such as C and C++. Although this mixed language approach +has many benefits, one of the greatest drawbacks is the complexity of +debugging that results from using interpreted and compiled code in +the same application. In part, this is due to the fact that scripting +language interpreters are unable to recover from catastrophic errors in +compiled extension code. Furthermore, traditional C/C++ debuggers do +not provide a satisfactory degree of integration with interpreted +languages. This paper describes an experimental system in which fatal +extension errors such as segmentation faults, bus errors, and failed +assertions are handled as scripting language exceptions. This system, +which has been implemented as a general purpose shared library, +requires no modifications to the target scripting language, introduces +no performance overhead, and simplifies the debugging of mixed +interpreted-compiled application software. +} + +\section{Introduction} + +Slightly more than ten years have passed since John Ousterhout +introduced the Tcl scripting language at the 1990 USENIX technical +conference \cite{ousterhout}. Since then, scripting languages have +been gaining in popularity as evidenced by the wide-spread use of +systems such as Tcl, Perl, Python, Guile, PHP, and Ruby +\cite{ousterhout,perl,python,guile,php,ruby}. + +In part, the success of modern scripting languages is due to their +ability to be easily integrated with software written in compiled +languages such as C, C++, and Fortran. In addition, a wide variety of wrapper +generation tools can be used +to automatically produce bindings between existing code and a +variety of scripting language environments +\cite{swig,sip,pyfort,f2py,advperl,heidrich,vtk,gwrap,wrappy}. As a result, a large number of +programmers are using scripting languages to control +complex C/C++ programs or as a tool for re-engineering legacy +software. This approach is attractive because it allows programmers +to benefit from the flexibility and rapid development of +scripting while retaining the best features of compiled code such as high +performance \cite{ouster1}. + +A critical aspect of scripting-compiled code integration is the way in +which it departs from traditional C/C++ development. Rather than +building large monolithic stand-alone applications, scripting +languages strongly encourage the creation of modular software +components. As a result, scripted software tends to be constructed as +a mix of dynamically loadable libraries, scripts, and third-party +extension modules. In this sense, one might argue that the benefits of +scripting are achieved at the expense of creating a somewhat more +complicated development environment. + +A consequence of this complexity is an increased degree of difficulty +associated with debugging programs that utilize multiple languages, +dynamically loadable modules, and a sophisticated runtime environment. +To address this problem, this paper describes an experimental system +known as WAD (Wrapped Application Debugger) in which an embedded error +recovery and debugging mechanism is added to common scripting +languages. This system converts catastrophic signals such as +segmentation faults and failed assertions to exceptions that can be +handled by the scripting language interpreter. In doing so, it +provides more seamless integration between error handling in +scripting language interpreters and compiled extensions. + +\section{The Debugging Problem} + +Normally, a programming error in a scripted application +results in an exception that describes the problem and the context in +which it occurred. For example, an error in a Python script might +produce a traceback similar to the following: + +\begin{verbatim} +% python foo.py +Traceback (innermost last): + File "foo.py", line 11, in ? + foo() + File "foo.py", line 8, in foo + bar() + File "foo.py", line 5, in bar + spam() + File "foo.py", line 2, in spam + doh() +NameError: doh +\end{verbatim} + +In this case, a programmer might be able to apply a fix simply based +on information in the traceback. Alternatively, if the problem is +more complicated, a script-level debugger can be used to provide more information. In contrast, +a failure in compiled extension code might produce the following result: + +\begin{verbatim} +% python foo.py +Segmentation Fault (core dumped) +\end{verbatim} + +In this case, the user has no idea of what has happened other +than it appears to be ``very bad.'' Furthermore, script-level +debuggers are unable to identify the problem since they also crash +when the error occurs (they usually run in the same process as +the interpreter). A user might be able to narrow the source of the +problem through trial-and-error techniques such as inserting print +statements or commenting out sections of script code. Unfortunately, +neither of these techniques are very attractive for obvious reasons. + +Alternatively, a user could run the application under the control of a +traditional debugger such as gdb \cite{gdb}. Unfortunately, this also has +drawbacks. First, even though the debugger provides information about the error, +the debugger mostly provides information about the internal +implementation of the scripting language interpreter. Needless +to say, this isn't very useful nor does it provide much insight as to +where the error might have occurred within a script. Second, +the structure of a scripted application tends to be much more complex +than a traditional stand-alone program. As a result, a user may not +have a good sense of how to actually attach a C/C++ debugger to their +script. In addition, execution may occur within a +complex run-time environment involving events, threads, and network +connections. Because of this, it can be difficult to reproduce +and identify certain types of catastrophic errors (especially if they +depend on timing or peculiar sequences of events). Finally, this approach +assumes that a programmer has a C/C++ development environment installed on +their machine and that they know how to use a low-level +debugger. Unfortunately, neither of these assumptions may hold in practice. +This is because scripting languages are often used to provide programmability to +applications in which end-users might write scripts, yet would not be expected +to write low-level C code. + +Even if a traditional debugger such as gdb were modified to +provide better integration with scripting languages, it is not clear +that this would be the most natural solution to the problem. +For one, the whole notion of having to run a separate debugging process to debug +extension code is unnatural when no such requirement exists for +a script. Furthermore, even if such a debugger existed, an inexperienced user may not +have the expertise or inclination to use it. Finally, +obscure fatal errors may occur long after an application has been deployed. +Unless the debugger is distributed along with the application in some manner, it will be +extraordinary difficult to obtain useful diagnostics when such errors occur. + +\begin{figure*}[t] +{\small +\begin{verbatim} +% python foo.py +Traceback (most recent call last): + File "", line 1, in ? + File "foo.py", line 16, in ? + foo() + File "foo.py", line 13, in foo + bar() + File "foo.py", line 10, in bar + spam() + File "foo.py", line 7, in spam + doh.doh(a,b,c) + +SegFault: [ C stack trace ] + +#2 0x00027774 in call_builtin(func=0x1c74f0,arg=0x1a1ccc,kw=0x0) in 'ceval.c', line 2650 +#1 0xff083544 in _wrap_doh(self=0x0,args=0x1a1ccc) in 'foo_wrap.c', line 745 +#0 0xfe7e0568 in doh(a=0x3,b=0x4,c=0x0) in 'foo.c', line 28 + +/u0/beazley/Projects/WAD/Python/foo.c, line 28 + + int doh(int a, int b, int *c) { + => *c = a + b; + return *c; + } +\end{verbatim} +} +\caption{Cross language traceback generated for a segmentation fault in a Python extension} +\end{figure*} + +The easiest solution to the debugging problem is +to simply add as much error checking as possible. Although this is never +a bad thing to do, it's usually not enough to completely eliminate the problem. +For one, scripting languages are sometimes used to control hundreds +of thousands to millions of lines of compiled code. In this case, it is improbable +that a programmer will be able to foresee every conceivable error. +Second, scripting languages are often used to put new user interfaces on legacy software. In this +case, scripting may introduce new modes of execution that cause a formerly ``bug-free'' +application to fail in an unexpected manner. Finally, certain types +of errors such as floating-point exceptions can be particularly +difficult to eliminate because they might be generated algorithmically (e.g., +as the result of a numerical method). Therefore, even when a programmer has worked hard to eliminate +crashes, there is always a small probability that a complex application +will fail. + +\section{Embedded Error Recovery} + +Rather than modifying an existing debugger to support scripting +languages, an alternative approach is to add a more powerful error +handling and recovery mechanism to the scripting language interpreter. +This approach has been implemented in the form of an +experimental system known as WAD. WAD +is packaged as dynamically loadable shared library that can either be +loaded as a scripting language extension or linked to existing +extension modules as a library. The core of the system is generic and +requires no modifications to the scripting interpreter or existing +extension modules. Furthermore, the system does not introduce a performance penalty as it +does not rely upon program instrumentation or tracing. + +WAD works by converting fatal signals such as SIGSEGV, +SIGBUS, SIGFPE, and SIGABRT into scripting language exceptions that contain +debugging information collected from the call-stack of compiled +extension code. By handling errors in this manner, the scripting +language interpreter is able to produce a cross-language stack trace that +contains information from both the script code and extension code as +shown for Python and Tcl/Tk in Figures 1 and 2. In this case, the user +is given a very clear idea of what has happened without having +to launch a separate debugger. + +The advantage to this approach is that it provides +more seamless integration between error handling +in scripts and error handling in extensions. In addition, it eliminates +the most common debugging step that a developer is likely to perform +in the event of a fatal error--running a separate debugger on a core +file and typing 'where' to get a stack trace. Finally, this allows +end-users to provide extension writers with useful debugging +information since they can supply a stack trace as opposed to a vague +complaint that the program ``crashed.'' + +\begin{figure*}[t] +\begin{picture}(400,250)(0,0) +\put(50,-110){\special{psfile = tcl.ps hscale = 60 vscale = 60}} +\end{picture} +\caption{Dialogue box with traceback information for a failed assertion in a Tcl/Tk extension} +\end{figure*} + +\section{Scripting Language Internals} + +In order to provide embedded error recovery, it is critical to understand how +scripting language interpreters interface with extension code. Despite the wide variety +of scripting languages, essentially every implementation uses a similar +technique for accessing foreign code. + +The most widely used extension mechanism is a foreign function +interface in which compiled procedures can be called from the scripting language +interpreter. This is accomplished by writing a collection of wrapper functions that conform +to a specified calling convention. The primary purpose of the wrappers are to +marshal arguments and return values between the two languages and to handle errors. +For example, in Tcl, every wrapper +function must conform to the following prototype: + +\begin{verbatim} +int +wrap_foo(ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[]) +{ + /* Convert arguments */ + ... + /* Call a function */ + + result = foo(args); + + /* Set result */ + ... + if (success) { + return TCL_OK; + } else { + return TCL_ERROR; + } +} +\end{verbatim} + +The other extension mechanism is an object/type interface that allows programmers to create new +kinds of fundamental types or attach special properties to objects in +the interpreter. This usually involves setting up tables of function +pointers that define various properties of an object. For example, if +you wanted to add complex numbers to an interpreter, you might fill in a special +data structure with pointers to various methods like this: + +\begin{verbatim} +NumberMethods ComplexMethods { + complex_add, + complex_sub, + complex_mul, + complex_div, + ... +}; +\end{verbatim} + +\noindent +Once registered with the interpreter, the methods in this structure +would be invoked by various interpreter operators such as $+$, +$-$, $*$, and $/$. + +Most interpreters handle errors as a two-step process in which +detailed error information is first registered with the interpreter +and then a special error code is returned. For example, in Tcl, errors +are handled by setting error information in the interpreter and +returning a value of TCL\_ERROR. Similarly in Python, errors are +handled by raising an exception and returning NULL. In both cases, +this triggers the interpreter's error handler---possibly resulting in +a stack trace of the running script. In some cases, an interpreter +might handle errors using a form of the C {\tt longjmp} function. +For example, Perl provides a special function {\tt die} that jumps back +to the interpreter with a fatal error \cite{advperl}. + +The precise implementation details of these mechanisms aren't so +important for our discussion. The critical point is that scripting +languages always access extension code though a well-defined interface +that precisely defines how arguments are to be passed, values are to be +returned, and errors are to be handled. + +\section{Scripting Languages and Signals} + +Under normal circumstances, errors in extension code are handled +through the error-handling API provided by the scripting language +interpreter. For example, if an invalid function parameter is passed, +a program can simply set an error message and return to the +interpreter. Similarly, automatic wrapper generators such as SWIG can produce +code to convert C++ exceptions and other C-related error handling +schemes to scripting language errors \cite{swigexcept}. On the other +hand, segmentation faults, failed assertions, and similar problems +produce signals that cause the interpreter to crash. + +Most scripting languages provide limited support for Unix signal +handling \cite{stevens}. However, this support is not sufficiently advanced to +recover from fatal signals produced by extension code. +First, unlike signals generated for asynchronous events such as I/O, +execution can {\em not} be resumed at the point of a fatal signal. +Therefore, even if such a signal could be caught and handled by a script, +there isn't much that it can do except to print a diagnostic +message and abort before the signal handler returns. Second, +some interpreters block signal delivery while executing +extension code--opting to handle signals at a time when it is more convenient. +In this case, a signal such as SIGSEGV would simply cause the whole application +to freeze since there is no way for execution to continue to a point where +the signal could be delivered. Because of these issues, scripting languages +either ignore the problem or label it as an ``limitation.'' + +\section{Overview of WAD} + +WAD installs a reliable signal handler for +SIGSEGV, SIGBUS, SIGABRT, SIGILL, and SIGFPE using {\tt sigaction} +\cite{stevens}. Since none of these signals are normally used in the implementation +of the scripting interpreter or by any user scripts, this typically does not override any previous +signal handling. Afterwards, when one of these signals occurs, a two-phase +recovery process executes. First, +information is collected about the execution context including a +full stack-trace, symbol table entries, and debugging information. +Second, the current stream of execution is aborted and an error is +returned to the interpreter. This process is illustrated in Figure~3. + +The collection of context and debugging information is a relatively +straightforward process involving the following steps: + +\begin{itemize} +\item The program counter and stack pointer are obtained from +context information passed to the WAD signal handler. + +\item The virtual memory map of the process is obtained from /proc +and used to associate virtual memory addresses with executable files, +shared libraries, and dynamically loaded extension modules \cite{proc}. + +\item The call stack is unwound to collect traceback information. +each step of the stack traceback, symbol table and debugging +information is gathered and stored in a generic data structure for later use +in the recovery process. This data is obtained by memory-mapping +the ELF format object files associated with the process and extracting +symbol table and stabs debugging information \cite{elf,stabs}. +\end{itemize} + +Once debugging information has been collected, the signal handler +enters an error-recovery phase that +attempts to raise an exception and return to a suitable location in the +interpreter. To do this, the following steps are performed: + +\begin{itemize} + +\item The stack trace is examined to see if there are any locations to which +control can be returned. + +\item If a suitable return location is found, the CPU context is modified in +a manner that makes the signal handler return to the interpreter +with an error. This return process is assisted by a small +trampoline function (partially written in assembly language) that arranges a proper +return to the interpreter after the signal handler returns. +\end{itemize} + +\noindent +Of the two phases, the return to the interpreter is of greater interest. Therefore, it +is now described in greater detail. + +\begin{figure*}[t] +\begin{picture}(480,340)(5,60) + +\put(50,330){\framebox(200,70){}} +\put(60,388){\tt >>> {\bf foo()}} +\put(60,376){\tt Traceback (most recent call last):} +\put(70,364){\tt File "", line 1, in ?} +\put(60,352){\tt SegFault: [ C stack trace ]} +\put(60,340){\tt ...} + +\put(55,392){\line(-1,0){25}} +\put(30,392){\line(0,-1){80}} +\put(30,312){\line(1,0){95}} +\put(125,312){\vector(0,-1){10}} +\put(175,302){\line(0,1){10}} +\put(175,312){\line(1,0){95}} +\put(270,312){\line(0,1){65}} +\put(270,377){\vector(-1,0){30}} + +\put(50,285){\framebox(200,15)[c]{[Python internals]}} +\put(125,285){\vector(0,-1){10}} +\put(175,275){\vector(0,1){10}} +\put(50,260){\framebox(200,15)[c]{call\_builtin()}} +\put(125,260){\vector(0,-1){10}} +%\put(175,250){\vector(0,1){10}} +\put(50,235){\framebox(200,15)[c]{wrap\_foo()}} +\put(125,235){\vector(0,-1){10}} +\put(50,210){\framebox(200,15)[c]{foo()}} +\put(125,210){\vector(0,-1){10}} +\put(50,185){\framebox(200,15)[c]{doh()}} +\put(125,185){\vector(0,-1){20}} +\put(110,148){SIGSEGV} +\put(160,152){\vector(1,0){100}} +\put(260,70){\framebox(200,100){}} +\put(310,155){WAD signal handler} +\put(265,140){1. Unwind C stack} +\put(265,125){2. Gather symbols and debugging info} +\put(265,110){3. Find safe return location} +\put(265,95){4. Raise Python exception} +\put(265,80){5. Modify CPU context and return} + +\put(260,185){\framebox(200,15)[c]{return assist}} +\put(365,174){Return from signal} +\put(360,170){\vector(0,1){15}} +\put(360,200){\line(0,1){65}} + +%\put(360,70){\line(0,-1){10}} +%\put(360,60){\line(1,0){110}} +%\put(470,60){\line(0,1){130}} +%\put(470,190){\vector(-1,0){10}} + +\put(360,265){\vector(-1,0){105}} +\put(255,250){NULL} +\put(255,270){Return to interpreter} + +\end{picture} + +\caption{Control Flow of the Error Recovery Mechanism for Python} +\label{wad} +\end{figure*} + +\section{Returning to the Interpreter} + +To return to the interpreter, WAD maintains a table of symbolic names +and return values that correspond to locations within the interpreter responsible for invoking +wrapper functions and object/type methods. For example, Table 1 shows a partial list of +return locations used in the Python implementation. When an error +occurs, the call stack is scanned for the first occurrence of any +symbol in this table. If a match is found, control is returned to that location +by emulating the return of a wrapper function with the error code from the table. If +no match is found, the error handler simply prints a stack trace to +standard output and aborts. + +When a symbolic match is found, WAD invokes a special user-defined +handler function that is written for a specific scripting language. +The primary role of this handler is to take debugging information +gathered from the call stack and generate an appropriate scripting language error. +One peculiar problem of this step is that the generation +of an error may require the use of parameters passed to a +wrapper function. For example, in the Tcl wrapper shown earlier, one +of the arguments was an object of type ``{\tt Tcl\_Interp *}''. +This object contains information specific to the state of the +interpreter (and multiple interpreter objects may exist in a single +application). Unfortunately, no reference to the interpreter object is +available in the signal handler. Furthermore, the interpreter +object may not be available in the context of a function that generated the error. + + +\begin{table}[t] +\begin{center} +\begin{tabular}{ll} +Python symbol & Return value \\ \hline +call\_builtin & NULL \\ +PyObject\_Print & -1 \\ +PyObject\_CallFunction & NULL \\ +PyObject\_CallMethod & NULL \\ +PyObject\_CallObject & NULL \\ +PyObject\_Cmp & -1 \\ +PyObject\_DelAttrString & -1 \\ +PyObject\_DelItem & -1 \\ +PyObject\_GetAttrString & NULL \\ +\end{tabular} +\end{center} +\label{returnpoints} +\caption{A partial list of symbolic return locations in the Python interpreter} +\end{table} + +To work around this problem, WAD implements a feature +known as argument stealing. When examining the call-stack, the signal +handler has full access to all function arguments and local variables. +Therefore, if the handler knows that an error was generated while +calling a wrapper function (as determined by looking at the symbol names), +it can grab the interpreter object from the stack frame of the wrapper and +use it to set an appropriate error code before returning to the interpreter. +Currently, this is managed by allowing the signal handler to steal +arguments from the caller using positional information. +For example, to grab the {\tt Tcl\_Interp *} object from a Tcl wrapper function, +code similar to the following is written: + +\begin{verbatim} +Tcl_Interp *interp; +int err; + +interp = (Tcl_Interp *) wad_steal_outarg( + stack, + "TclExecuteByteCode", + 1, + &err); +if (!err) { + Tcl_SetResult(interp,errtype,TCL_STATIC); + Tcl_AddErrorInfo(interp,errdetails); +} +\end{verbatim} + +In this case, the 2nd argument passed to a wrapper function +is stolen and used to generate an error. Also, the name {\tt TclExecuteByteCode} +refers to the calling function, not the wrapper function itself. +At this time, argument stealing is only applicable to simple types +such as integers and pointers. However, this is adequate for generating +scripting language errors. + +\section{Register Management} + +A final issue concerning the return mechanism has to do with the +precise behavior of the non-local return to the interpreter. Roughly +speaking, this emulates the behavior of the C {\tt longjmp} +library call. However, this is done without the use of a matching +{\tt setjmp} in the interpreter. + +The primary problem with aborting execution and returning to the +interpreter in this manner is that most compilers use a register management technique +known as callee-save \cite{prag}. In this case, it is the responsibility of +the called function to save the state of the registers and to restore +them before returning to the caller. By making a non-local jump, +registers may be left in an inconsistent state due to the fact that +they are not restored to their original values. The {\tt longjmp} function +in the C library avoids this problem by relying upon {\tt setjmp} to save +the registers. Unfortunately, WAD does not have this +luxury. As a result, a return from the signal handler may produce a +corrupted set of registers at the point of return in the interpreter. + +The severity of this problem depends greatly on the architecture and +compiler. For example, on the SPARC, register windows effectively +solve the callee-save problem \cite{sparc}. In this case, each stack frame has its own +register window and the windows are flushed to the stack whenever a +signal occurs. Therefore, the recovery mechanism can examine the stack and +arrange to restore the registers to their proper values when control +is returned. Furthermore, certain conventions of the SPARC ABI resolve several related +issues. For example, floating point registers are caller-saved +and the contents of the SPARC global registers are not guaranteed to be preserved +across procedure calls (in fact, they are not even saved by {\tt setjmp}). + +On other platforms, the problem of register management becomes much +more interesting. One approach is to simply ignore the problem +altogether and return to the interpreter with the registers in an +essentially random state. Surprisingly, this approach actually seems to work (although a considerable degree of +caution might be in order). +This is because the return of an error code tends to trigger +a cascade of procedure returns within the implementation of the interpreter. +As a result, the values of the registers are simply discarded and +overwritten with restored values as the interpreter unwinds itself and prepares to handle an +exception. A better solution to this problem is to modify the recovery mechanism to discover and +restore saved registers from the stack. Unfortunately, there is +no standardized way to know exactly where the registers might have been saved. +Therefore, a heuristic scheme that examines the machine code for each procedure would +have to be used to try and identify stack locations. This approach is used by gdb +and other debuggers when they allow users to inspect register values +within arbitrary stack frames \cite{gdb}. However, this technique has +not yet been implemented in WAD due to its obvious implementation difficulty and the +fact that the WAD prototype has primarily been developed for the SPARC. + +As a fall-back, WAD can be configured to return control to a location +previously specified with {\tt setjmp}. Unfortunately, this either +requires modifications to the interpreter or its extension modules. +Although this kind of instrumentation can be facilitated by automatic +wrapper code generators, it is not a preferred solution and is +not discussed further. + +\section{Implementation Details} + +Currently, WAD is implemented in ANSI C and small amount of assembly +code to assist in the return to the interpreter. The current +implementation supports Python, Tcl, and Perl extensions on SPARC Solaris. An +i386-Linux port has also been developed. The entire implementation contains +approximately 1500 semicolons and most of this code is related to the gathering of debugging +information. Furthermore, due to the hostile environment in which the +recovery process must run, the implementation takes great care not to utilize the +process heap. This allows the signal handler to collect information in situations +where the heap allocator has been corrupted or destroyed in some manner. + +Although there are libraries such as the GNU Binary File Descriptor +(BFD) library that can assist with the manipulation of object files +these are not used in the implementation \cite{bfd}. First, these +libraries tend to be quite large and are oriented more towards +stand-alone tools such as debuggers, linkers, and loaders. Second, +the behavior of these libraries with respect to memory management +would need to be carefully studied before they could be safely used in +an embedded environment. Finally, given the small size of the +implementation, it didn't seem necessary to rely upon such a +heavyweight solution. + +\section{Discussion} + +The primary goal of embedded error recovery is to provide an +alternative approach for debugging scripting language extensions. +Although this approach has many benefits, there are a number +drawbacks and issues that must be discussed. + +First, like the C {\tt longjmp} function, the error recovery mechanism +does not cleanly unwind the call stack. For C++, this means that +objects allocated on stack will not be finalized (destructors will not +be invoked) and that memory allocated on the heap may be +leaked. Similarly, this could result in open files, sockets, and other +system resources. Furthermore, in a multi-threaded environment, +deadlock may occur if a procedure holds a lock when an error occurs. + +Second, the use of signals may interact adversely with both scripting +language signal handling and signal handling in thread libraries. +Since scripting languages ordinarily do not catch signals such as +SIGSEGV, SIGBUS, and SIGABRT, the use of WAD is unlikely to conflict +with any existing signal handling. However, this does not prevent a +module from overriding the error recovery mechanism with its own +signal handler. Threads present a different sort of signal handling problem +due to the fact that thread libraries tend to override default signal handling \cite{thread}. +In this case, the thread library directs fatal signals to the thread in which the problem occurred. +However, first-hand experience has shown that certain implementations +of user threads do not reliably pass signal context information nor do +they universally support advanced signal operations such as {\tt +sigaltstack}. Because of this, the WAD recovery mechanism may not be +compatible with a crippled implementation of user threads on certain +platforms. To further complicate matters, the recovery process itself is +not thread-safe (i.e., it is not possible to concurrently handle fatal errors +occurring different threads). + +Third, certain types of errors may result in an unrecoverable crash. +For example, if an application overwrites the heap, it may destroy +critical data structures within the interpreter. +Similarly, +destruction of the call stack (via buffer overflow) makes it +impossible for the recovery mechanism to create a stack-trace and +return to the interpreter. Although it might be possible to add a heuristic scheme for +recovering a partial stack trace such as backward stack tracing, no such feature has been implemented +\cite{debug}. Finally, memory management problems such as +double-freeing of heap allocated memory can cause a system to fail in +a way that bears little resemblance to the actual source of the +problem. + +Finally, there are a number of issues that pertain +to the interaction of the recovery mechanism with the interpreter. +First, the recovery scheme is unable to return to procedures +that might invoke wrapper functions with conflicting return codes. +This problem manifests itself when the interpreter's virtual +machine is built around a large {\tt switch} statement from which different +types of wrapper functions are called. For example, in Python, certain +internal procedures call a mix of functions where both NULL and -1 are +returned to indicate errors (depending on the function). In this case, there +is no way for WAD to easily determine which return value to use. Second, +the recovery process is extremely inefficient. This is because the +data collection process relies heavily upon {\tt mmap}, file I/O, and linear search +algorithms for finding symbols and debugging information. Therefore, it would +probably not be suitable as a general purpose exception handling mechanism. +Finally, even when an error is successfully returned to the interpreter +and presented to the user, it may not be possible to resume execution of +the application (e.g., even though the interpreter is operational, the extension +module may be corrupted in some manner). + +Despite these limitations, embedded error recovery is applicable to a +wide range of extension-related errors. This is because errors such as +failed assertions, bus errors, and floating point exceptions rarely +result in a situation where the recovery process would be unable to run or the +interpreter would crash. Furthermore, more serious errors such as segmentation faults are more +likely to caused by an uninitialized pointer than a blatant +destruction of the heap or stack. + +\section{Related Work} + +A huge body of literature is devoted to the topic of exception +handling in various languages and systems. Furthermore, the topic +remains one of active interest in the software community. For +instance, IEEE Transactions on Software Engineering recently devoted +two entire issues to current trends in exception handling +\cite{except1,except2}. Unfortunately, very little of this work seems +to be directly related to mixed compiled-interpreted exception +handling, recovery from fatal signals, and problems pertaining to +mixed-language debugging. + +Perhaps the most directly relevant work is that of advanced programming +environments for Common Lisp \cite{lisp}. Not only does CL have a foreign function interface, +debuggers such as gdb have previously been modified to walk the Lisp stack +\cite{ffi,wcl}. Furthermore, certain Lisp development environments have +provided a high degree of integration between compiled code and +the Lisp interpreter\footnote{Note to program committee: I +have been unable to find a suitable reference describing this capability. However, +discussions with Richard Gabriel and other people in the Lisp community seem to indicate that +such work has been done. Please advise.} + +In certain cases, a scripting language module has been used to provide +partial information for fatal signals. For example, the Perl {\tt +sigtrap} module can be used to produce a Perl stack trace when a +problem occurs \cite{perl}. Unfortunately, this module does not +provide any information from the C stack. Similarly, advanced software development +environments such as Microsoft's Visual Studio can automatically launch a C/C++ +debugger when an error occurs. Unfortunately, this doesn't provide any information +about the script that was running. + +In the area of programming languages, a number of efforts have been made to +map signals to exceptions in the form of asynchronous exception handling +\cite{buhr,ml,haskell}. Unfortunately, this work tends to +concentrate on the problem of handling asynchronous signals related to I/O as opposed +to synchronously generated signals caused by software faults. + +With respect to debugging, little work appears to have been done in the area of +mixed compiled-interpreted debugging. Although modern debuggers +certainly try to provide advanced capabilities for debugging within a +single language, they tend to ignore the boundary between languages. +As previously mentioned, debuggers have occasionally been modified to +support other languages such as Common Lisp \cite{wcl}. However, no such work appears +to have been done in the context of modern scripting languages. One system of possible interest +in the context of mixed compiled-interpreted debugging is the R$^{n}$ +system developed at Rice University in the mid-1980's \cite{carle}. This +system, primarily developed for scientific computing, allowed control +to transparently pass between compiled code and an interpreter. +Furthermore, the system allowed dynamic patching of an executable in +which compiled procedures could be replaced by an interpreted +replacement. Although this system does not directly pertain to the problem of +debugging of scripting language extensions, it is one of the few +examples of a system in which compiled and interpreted code have been +tightly integrated within a debugger. + +\section{Future Directions} + +As of this writing, WAD is only an experimental prototype. Because of +this, there are certainly a wide variety of incremental improvements +that could be made to support additional platforms and scripting +languages. In addition, there are a variety of improvements that could be made +to provide better integration with threads and C++. + +A more interesting extension of this work would be to expose a broader +range of debugging capabilities to the scripting interpreter. For example, +rather than simply raising an exception with limited diagnostic +information, the recovery mechanism might be able to provide the +interpreter with a detailed snapshot of the entire call stack +including symbolic debugging information. Using this information, it +might be possible to implement an interactive post-mortem debugger +that allows a programmer to inspect the values of local +variables and other aspects of the application without leaving the +interpreter. Alternatively, it may be possible to integrate this information +into an existing script-level debugger. + +\section{Conclusions and Availability} + +This paper has presented a mechanism by which fatal errors such as +segmentation faults and failed assertions can be handled as scripting +language exceptions. This approach, which relies upon advanced +features of Unix signal handling, allows fatal signals to be caught +and transformed into errors from which interpreters can produce an +informative cross-language stack trace. In doing so, it provides more +seamless integration between scripting languages and compiled +extensions. Furthermore, this has the potential to greatly simplify the +frustrating task of debugging complicated mixed scripted-compiled +software. + +The prototype implementation of this system is available at : + +\begin{center} +{\tt http://systems.cs.uchicago.edu/wad}. +\end{center} + +\noindent +Currently, WAD supports Python, +Tcl, and Perl on SPARC Solaris and i386-Linux systems. Work to +support additional scripting languages and platforms is ongoing. + +\section{Acknowledgments} + +Richard Gabriel and Harlan Sexton provided interesting insights concerning similar capabilities +in Common Lisp. + +\begin{thebibliography}{99} + + +\bibitem{ousterhout} J. K. Ousterhout, {\em Tcl: An Embedable Command Language}, +Proceedings of the USENIX Association Winter Conference, 1990. + +\bibitem{ouster1} J. K. Ousterhout, {\em Scripting: Higher-Level Programming for the 21st Century}, +IEEE Computer, Vol 31, No. 3, p. 23-30, 1998. + +\bibitem{perl} L. Wall, T. Christiansen, and R. Schwartz, {\em Programming Perl}, 2nd. Ed. +O'Reilly \& Associates, 1996. + +\bibitem{python} M. Lutz, {\em Programming Python}, O'Reilly \& Associates, 1996. + +\bibitem{guile} Thomas Lord, {\em An Anatomy of Guile, The Interface to +Tcl/Tk}, USENIX 3rd Annual Tcl/Tk Workshop 1995. + +\bibitem{php} T. Ratschiller and T. Gerken, {\em Web Application Development with PHP 4.0}, +New Riders, 2000. + +\bibitem{ruby} D. Thomas, A. Hunt, {\em Programming Ruby}, Addison-Wesley, 2001. + +\bibitem{swig} D.M. Beazley, {\em SWIG : An Easy to Use Tool for Integrating Scripting Languages with C and C++}, Proceedings of the 4th USENIX Tcl/Tk Workshop, p. 129-139, July 1996. + +\bibitem{sip} P. Thompson, {\em SIP},\\ +{\tt http://www.thekompany.com/projects/pykde}. + +\bibitem{pyfort} P.~F.~Dubois, {\em Climate Data Analysis Software}, 8th International Python Conference, +Arlington, VA., 2000. + +\bibitem{f2py} P. Peterson, J. Martins, and J. Alonso, +{\em Fortran to Python Interface Generator with an application to Aerospace +Engineering}, 9th International Python Conference, submitted, 2000. + +\bibitem{advperl} S. Srinivasan, {\em Advanced Perl Programming}, O'Reilly \& Associates, 1997. + +\bibitem{heidrich} Wolfgang Heidrich and Philipp Slusallek, {\em Automatic Generation of Tcl Bindings for C and C++ Libraries.}, +USENIX 3rd Tcl/Tk Workshop, 1995. + +\bibitem{vtk} K. Martin, {\em Automated Wrapping of a C++ Class Library into Tcl}, +USENIX 4th Tcl/Tk Workshop, p. 141-148, 1996. + +\bibitem{gwrap} C. Lee, {\em G-Wrap: A tool for exporting C libraries into Scheme Interpreters},\\ +{\tt http://www.cs.cmu.edu/\~{ }chrislee/ +Software/g-wrap}. + +\bibitem{wrappy} G. Couch, C. Huang, and T. Ferrin, {\em Wrappy :A Python Wrapper +Generator for C++ Classes}, O'Reilly Open Source Software Convention, 1999. + +\bibitem{gdb} R. Stallman and R. Pesch, {\em Using GDB: A Guide to the GNU Source-Level Debugger}. +Free Software Foundation and Cygnus Support, Cambridge, MA, 1991. + +\bibitem{swigexcept} D.M. Beazley and P.S. Lomdahl, {\em Feeding a +Large-scale Physics Application to Python}, 6th International Python +Conference, co-sponsored by USENIX, p. 21-28, 1997. + +\bibitem{stevens} W. Richard Stevens, {\em UNIX Network Programming: Interprocess Communication, Volume 2}. PTR +Prentice-Hall, 1998. + +\bibitem{proc} R. Faulkner and R. Gomes, {\em The Process File System and Process Model in UNIX System V}, USENIX Conference Proceedings, +January 1991. + +\bibitem{elf} J.~R.~Levine, {\em Linkers \& Loaders.} Morgan Kaufmann Publishers, 2000. + +\bibitem{stabs} Free Software Foundation, {\em The "stabs" debugging format}. GNU info document. + +\bibitem{prag} M.L. Scott. {\em Programming Language Pragmatics}, Morgan Kaufmann Publishers, 2000. + +\bibitem{sparc} D. Weaver and T. Germond, {\em SPARC Architecture Manual Version 9}, +Prentice-Hall, 1993. + +\bibitem{bfd} S. Chamberlain. {\em libbfd: The Binary File Descriptor Library}. Cygnus Support, bfd version 3.0 edition, April 1991. + +\bibitem{thread} F. Mueller, {\em A Library Implementation of POSIX Threads Under Unix}, +USENIX Winter Technical Conference, San Diego, CA., p. 29-42, 1993. + +\bibitem{debug} J. B. Rosenberg, {\em How Debuggers Work: Algorithms, Data Structures, and +Architecture}, John Wiley \& Sons, 1996. + +\bibitem{except1} D.E. Perry, A. Romanovsky, and A. Tripathi, {\em +Current Trends in Exception Handling-Part I}, +IEEE Transactions on Software Engineering, Vol 26, No. 9, p. 817-819, 2000. + +\bibitem{except2} D.E. Perry, A. Romanovsky, and A. Tripathi, {\em +Current Trends in Exception Handling-Part II}, +IEEE Transactions on Software Engineering, Vol 26, No. 10, p. 921-922, 2000. + + +\bibitem{lisp} G.L. Steele Jr., {\em Common Lisp: The Language, Second Edition}, Digital Press, +Bedford, MA. 1990. + +\bibitem{ffi} H. Sexton, {\em Foreign Functions and Common Lisp}, in Lisp Pointers, Vol 1, No. 5, 1988. + +\bibitem{wcl} W. Henessey, {\em WCL: Delivering Efficient Common Lisp Applications Under Unix}, +ACM Conference on Lisp and Functional Languages, p. 260-269, 1992. + +\bibitem{buhr} P.A. Buhr and W.Y.R. Mok, {\em Advanced Exception Handling Mechanisms}, IEEE Transactions on Software Engineering, +Vol. 26, No. 9, p. 820-836, 2000. + +\bibitem{haskell} S. Marlow, S. P. Jones, and A. Moran. {\em +Asynchronous Exceptions in Haskell.} In 4th International Workshop on +High-Level Concurrent Languages, September 2000. + +\bibitem{ml} J. H. Reppy, {\em Asynchronous Signals in Standard ML}. Technical Report TR90-1144, +Cornell University, Computer Science Department, 1990. + +\bibitem{carle} A. Carle, D. Cooper, R. Hood, K. Kennedy, L. Torczon, S. Warren, +{\em A Practical Environment for Scientific Programming.} +IEEE Computer, Vol 20, No. 11, p. 75-89, 1987. + + + + + + +\end{thebibliography} + +\end{document} + + + + + + + +