| WAD (Wrapped Application Debugger) |
| |
| Author(s): |
| David M. Beazley (beazley@cs.uchicago.edu) |
| |
| Copyright (C) 2001 |
| University of Chicago |
| |
| This library is free software; you can redistribute it and/or |
| modify it under the terms of the GNU Lesser General Public |
| License as published by the Free Software Foundation; either |
| version 2.1 of the License, or (at your option) any later version. |
| |
| This library is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public |
| License along with this library; if not, write to the Free Software |
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| |
| See the file COPYING for a complete copy of the LGPL. |
| |
| $Id$ |
| |
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
| !!!!!!!! DISCLAIMER !!!!!!!! |
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
| |
| THIS IS EXPERIMENTAL UNMAINTAINED RESEARCH SOFTWARE THAT REPRESENTS |
| WORK IN PROGRESS. IT IS NOT PORTABLE, IT HAS NOT BEEN EXHAUSTIVELY |
| TESTED, AND IT MIGHT NOT WORK AT ALL. PLEASE KEEP AWAY FROM SMALL |
| CHILDREN, PETS, NUCLEAR REACTORS, AIR-TRAFFIC CONTROL, AND VOTING |
| MACHINES. |
| |
| 0. Supported Platforms |
| |
| This software is currently only known to work with 32-bit applications |
| on Sun Sparc Solaris 2.8 and recent i386-Linux systems. In addition, |
| there are numerous issues concerning the interaction of this software |
| with signal handling, thread libraries, and compilers. Please read |
| this entire document before proceeding. |
| |
| 1. Introduction |
| |
| WAD is an embedded error-recovery mechanism that attempts to convert |
| fatal errors such as SIGSEGV, SIGBUS, and SIGFPE into sensible error |
| messages and exceptions. It is primarily designed to support |
| scripting language extension programming although it can also be used |
| with stand-alone C programs. |
| |
| The primary goal of this system is to explore an alternative approach |
| to mixed scripting-compiled debugging. It requires no modifications |
| or recompilation of existing software. Therefore, it should be |
| relatively easy to try out. Feedback is welcome. Contributions and |
| modifications are even more welcome. |
| |
| 2. Compilation and Installation |
| |
| WAD is not particularly portable and at this time, only two platforms |
| are supported: Sun Sparc Solaris and i386-Linux. |
| |
| Installation is as follows: |
| |
| ./configure |
| make |
| make install |
| |
| The build process creates the following shared libraries: |
| |
| libwad.so - Standalone WAD. Can be linked with C/C++ |
| programs. |
| |
| libwadpy.so - Python WAD. Can be linked to Python extension |
| modules or imported on its own as 'import libwadpy' |
| |
| libwadtcl.so - Tcl WAD. Can be linked to Tcl extension |
| modules or loaded as 'load libwadtcl.so'. |
| |
| libwadpl.so - Perl WAD. Can be linked to Perl extension |
| modules or loaded as 'libwadpl'. |
| |
| To install the libraries, simply type 'make install'. This copies the libraries |
| to /usr/local/lib (unless you modify the makefile). |
| |
| Notes: |
| |
| - The Sun version of WAD has only been tested when compiled with the |
| Sun Workshop C/C++ compilers. However WAD works with other programs |
| that have been compiled with gcc. If gcc is installed on your |
| machine, you may want to set the following environment variables |
| before running configure: |
| |
| setenv CC cc |
| setenv CXX CC |
| ./configure |
| |
| - You may need to modify the Makefile to point to the installed locations |
| of various scripting language libraries if you have installed |
| them in non-traditional locations. |
| |
| - The Linux version has only been tested with 2.2-12 and 2.2-14 kernels |
| and the RedHat 6.x distribution. Your mileage may vary. There |
| may be some compatibility issues related to glibc and other parts |
| of the system as well. |
| |
| 3. Using WAD |
| |
| WAD has no functional API nor does it have any command line options so |
| it's pretty easy to describe---simply link the appropriate WAD library with |
| your C code. For example: |
| |
| % cc blah.c -lwad |
| |
| Once linked, fatal errors will now produce stack traces. For example: |
| |
| % ./a.out seg |
| starting. |
| Segmentation fault. |
| #2 0x400571eb in __libc_start_main() in 'libc-start.c', line 90 |
| #1 0x08048b39 in main(argc=0x2,argv=0xbffffce4) in 'debug.c', line 62 |
| #0 0x080489b3 in seg_crash(n=0x0) in 'debug.c', line 9 |
| |
| /r0/beazley/Projects/WAD/Wad/debug.c, line 9 |
| |
| int *a = 0; |
| if (n > 0) seg_crash(n-1); |
| => *a = 3; |
| return 1; |
| } |
| |
| For scripting languages, WAD works in a similar manner--simply link |
| your scripting language extension module with the appropriate WAD library |
| (wadpy, wadtcl, wadpl). For example: |
| |
| % ld -G $(OBJS) -lwadpy -o pymodule.so |
| |
| When the scripting module is loaded into the interpreter, WAD should |
| automatically initialize. |
| |
| 4. Debugging Modes |
| |
| Due to WAD's experimental nature, a number of debugging modes can be set |
| through the use of environment variables. These variables control WAD's |
| runtime behavior and cause the system to dump debugging information for |
| various stages of error recovery. A lot of this data is pretty ugly and |
| probably only of interest to you if you are trying to debug WAD itself. |
| |
| WAD_DEBUG_SEGMENT - Displays information about the virtual memory |
| map and mapping of addresses to segments. |
| |
| WAD_DEBUG_SYMBOL - Symbol table mapping. |
| |
| WAD_DEBUG_OBJECT - Loading/Unloading of object files. |
| |
| WAD_DEBUG_FILE - Loading/Unloading of raw files. |
| |
| WAD_DEBUG_HOLD - Freezes WAD before it returns from the signal handler. |
| Useful if you need to attach a debugger to WAD itself. |
| |
| WAD_DEBUG_STABS - Display stabs data. |
| |
| WAD_DEBUG_RETURN - Display information about WAD return points. |
| |
| WAD_DEBUG_SYMBOL_SEARCH - Display all symbols in the symbol table that are |
| searched. |
| |
| WAD_DEBUG_UNWIND - Display information about stack unwinding. |
| |
| WAD_DEBUG_SIGNAL - Display information about signal handling. |
| |
| WAD_DEBUG_INIT - Print initialization information. |
| |
| WAD_NOSTACK - Do NOT use an alternative signal handling stack. |
| This may be necessary on certain Linux systems when |
| threads are being used. |
| |
| WAD_ONESHOT - Disable WAD signal handler after first signal has |
| been received. |
| |
| WAD_DEBUG_MEMORY - Print information about WAD memory use. |
| |
| WAD_DEBUG_STRINGS - Print information about WAD string manager. |
| |
| 5. Platform Specific Issues |
| |
| General: |
| |
| - WAD does not gracefully recover from errors that corrupt the call |
| stack (i.e., buffer overlow). |
| |
| - Errors that destroy the process heap may or may not be recoverable |
| depending on what has been destroyed. |
| |
| - WAD does not currently support 64 bit applications on any platform. |
| |
| - If executables have been stripped, their symbol tables might not |
| have enough information to recover from errors. Therefore, if you |
| are using Python, Tcl, or Perl from a binary distribution, you |
| may want to rebuild non-stripped versions of these packages yourself. |
| |
| - WAD only works with programs that utilize the ELF32 linking format |
| and stabs debugging data. Newer formats such as DWARF2 are not |
| supported at this time. |
| |
| - WAD does not correctly report argument values for structures or |
| floating point numbers yet. |
| |
| - Overly aggressive compiler optimization may lead to very strange |
| WAD output. |
| |
| Solaris: |
| |
| - WAD is extremely slow at collecting debugging information |
| from large applications. |
| |
| Linux: |
| |
| - The interaction of threads and signals are particularly problematic |
| on this platform and may cause WAD not to work at all. Here are |
| some specific thread-based issues that may arise: |
| |
| 1. WAD causes the program to crash immediately upon startup. |
| This appears to be caused by a bug in in the implementation |
| of sigaction() and the initialization of signals. This |
| only occurs if WAD is directly linked to an executable |
| using threads. It does not occur when WAD is dynamically |
| loaded into a threaded application. |
| |
| 2. Programs may lock up when an error occurs. This is sometimes |
| caused by an apparently broken implementation of sigaltstack(). |
| One solution to this is to set the following environment |
| variable: |
| |
| setenv WAD_NOSTACK |
| |
| in which case the WAD signal handler will use the same |
| stack as the thread/process that generates the error. |
| |
| 3. WAD just crashes altogether and doesn't seem to do anything. |
| It appears that some versions of Linux threads do *not* |
| pass CPU context information correctly to signal handlers |
| defined in threaded programs. There is no known fix to |
| this at this time. Upgrade your system. |
| |
| - WAD does not work if it is compiled as PIC code. The WAD libraries |
| should be compiled *without* the -fpic option. |
| |
| - WAD has to rely upon a heuristic register recovery scheme when it |
| returns to scripting language interpreters. It seems to |
| work, but it relies upon a very specific compiler code generation |
| convention for saving registers in function prologues. It also |
| relies upon the register save conventions described in the Linux |
| Assembly HOWTO. |
| |
| - If you are using WAD with pre-installed binaries for Python, Tcl, |
| and other scripting languages, it may not work correctly due to |
| stripped symbol tables. Most Linux installs such as Redhat strip |
| symbol tables from executables. This makes it difficult for WAD |
| to determine context correctly (although it may still work since |
| the dynamic loading symbol table is still available in most cases). |
| |
| 6. Language specific issues |
| |
| If WAD is linked with a normal C/C++ program, errors simply produce a stack trace |
| that is printed on standard error. |
| |
| Python: |
| |
| WAD tries to raise a Python exception and return. At this time, the exception |
| merely contains a traceback string. However, in future versions, it may be |
| possible to access a complete exception object. |
| |
| Tcl: |
| |
| WAD returns a Tcl and places the stack trace into the Tcl variable $errorInfo. |
| The wish shell uses this to dump error information. |
| |
| Perl: |
| |
| Perl doesn't seem to have a very well-defined exception handling |
| mechanism. Standard functions tend to just exit. The WAD handler |
| produces a C stack trace and produces a Perl stack trace using some |
| code derived from the sigtrap module. |
| |
| Note: 3/23/01 - Perl support is currently broken. |
| |
| 7. Testing and Examples |
| |
| The Test directory contains some very simple code for testing WAD. In the |
| most simple form, compile the stand-along test program 'debug' as follows: |
| |
| % cd Test |
| % make |
| |
| Now, running it: |
| |
| % debug |
| WAD debug program. |
| |
| Usage: debug type |
| seg - Fail with an uninitialized pointer. |
| bus - Fail with a bus error. |
| abort - Fail with an assertion error. |
| math - Fail with a math error. |
| heap - Blow the process heap. |
| overflow - Buffer overflow on the stack. |
| |
| % debug seg |
| WAD debug program. |
| Segmentation fault. |
| #2 0x400581eb in __libc_start_main() in 'libc-start.c', line 90 |
| #1 0x08048b61 in main(argc=0x2,argv=0xbffffc54) in 'debug.c', line 85 |
| #0 0x080489d0 in seg_crash() in 'debug.c', line 15 |
| |
| /r0/beazley/Projects/WAD/Test/debug.c, line 15 |
| |
| int seg_crash() { |
| int *a = 0; |
| => *a = 3; |
| return 1; |
| } |
| |
| Additional targets 'make python', 'make tcl', and 'make perl' are also available. |
| The scripts debug.py, debug.tcl, debug.pl can be used to test these extensions. |
| |
| 8. Documentation |
| |
| No official documentation exists at this time. However, details |
| of WAD's design and implementation can be found in papers presented |
| at the Ninth International Python Conference and the 2000 USENIX |
| Technical Conference. Both papers can be obtained at: |
| |
| http://systems.cs.uchicago.edu/wad |
| |
| |
| 9. To-Do |
| |
| If you find WAD to be interesting or useful, there are a variety of |
| ways to contribute. Here is the short to-do list: |
| |
| - Better register management. Try to implement in a more portable |
| way. Add some support code for recovering local variables |
| that happen to be stored in registers. |
| |
| - Add heuristic for recovering functions called through an |
| -fomit-frame-pointer compiler optimization scheme. This |
| can probably be determined by looking at the function preamble |
| machine code. Then one can back-trace to the calling function |
| and look at it's preamble. |
| |
| - Continued clean up and modularization of the core. Many of the |
| internal APIs could be greatly improved. |
| |
| - Support for ELF64 linking format. |
| |
| - Support for DWARF2 debugging data. |
| |
| - Improved support for stack-overflow and heap-corruption. Although WAD |
| probably won't be able to recover, it still might be able to produce some |
| informative diagnostics. |
| |
| - Removal of printf() and other high-level library calls which may not |
| operate with a corrupted heap. |
| |
| - Better integration with scripting languages. |
| |
| - Support for new platforms. |
| |
| - Support for new scripting languages. |
| |
| Please contact me if you are interested in working on any of these projects. |
| |
| Dave Beazley (beazley@cs.uchicago.edu) |
| June 24, 2001 |