Safer STL

CS 509 - Advanced Programming II, Spring 2004


Table of Contents

What is it?

Safer STL is a modified version of the STL; the modifications involve adding checks to STL code to catch common programming errors. Safer STL is based on the STLPort implementation of the STL; the modifications are based on those implemented by Cay Horstman in his SafeSTL. I have extended Horstman's set of checks to include more errors, and applied them wherever an error is allowed to occur by the STL.

Why do I care?

You should care about Safer STL because I'm going to use it when I compile your code for testing. If Safer STL blows up during testing, you're going to lose points.

How do I use it?

Unfortunately, using Safer STL more complicated than using the regular STL. I'm trying to figure out how to make it simpler, but for now, the best way to go about it is to break the process up into two steps: compiling the source and linking the objects.

There are a few things you should know before tackling Safer STL:

With the preliminaries out of the way, here's how to you get your program to use Safer STL instead of the default STL:

  1. Compiling the source. When compiling your source into .o object files, make sure the compiler picks up the Safer STL versions of the include files by using the -I command-line option to add the Safer STL include directory /export/home/class/util:

    $ g++ -gstabs -c -I/export/home/class/util/include/stlport your-file-here.cc
    

    If you do not use the -I option to specify the Safer STL include directory, the compiler will use the default STL.

    You cannot mix Safer STL and the default STL in the same program; you must either compile all your files to use Safer STL or to use the default STL.

    The -gstabs command-line option generates extra information useful for debugging code. You do not have to specify -gstabs, but you probably should. If you do use the -gstabs option, make sure you use it for all the files you compile.

    You do not have to change your #include statements to switch between Safer STL and the default STL. Switching between the two is done by the the -I option as described above.

  2. Linking the objects. Once you have all your source files compiled into object files, you can link them together to produce an executable. The linking command you should use will look like this:

    $ g++ -gstabs your-files-here.o /export/home/class/util/lib/saferstl.a
    

    The saferstl.a file is a library containing code implementing various features of Safer STL, including the iostream classes. This file should be listed last after all other object files on the command line.

    If you compiled your source with the -gstabs option, you should link them with the -gstabs option as shown. If you didn't use -gstabs during compilation, you can skip it during linking. Once your progam is linked to produce an executable, you can run it as you normally would.

Makefiles can make compiling and linking less onerous; see the example makefile in /export/home/class/util/misc.

My Program Crashed. Now What?

If Safer STL detects a problem, it will print an error message and abort the program with a coredump contained in a file named core.

$ ./a.out
Accessing element 1 in an empty vector.
Abort(coredump)

$ 

Assuming you used the g++ compiler and the -gstabs option, you can use the gdb debugger to find out where your code went wrong:

  1. Start the debugger using the command line gdb your-program core:

    $ gdb a.out core
    GNU gdb 5.2
    Copyright 2002 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB.  Type "show warranty" for details.
    This GDB was configured as "sparc-sun-solaris2.8"...
    Core was generated by ./a.out.
    Program terminated with signal 6, Aborted.
    Reading symbols from /usr/local/lib/libstdc++.so.5...done.
    Loaded symbols for /usr/local/lib/libstdc++.so.5
    Reading symbols from /usr/lib/libm.so.1...done.
    Loaded symbols for /usr/lib/libm.so.1
    Reading symbols from /usr/local/lib/libgcc_s.so.1...done.
    Loaded symbols for /usr/local/lib/libgcc_s.so.1
    Reading symbols from /usr/lib/libc.so.1...done.
    Loaded symbols for /usr/lib/libc.so.1
    Reading symbols from /usr/lib/libdl.so.1...done.
    Loaded symbols for /usr/lib/libdl.so.1
    Reading symbols from /usr/platform/SUNW,Ultra-5_10/lib/libc_psr.so.1...done.
    Loaded symbols for /usr/platform/SUNW,Ultra-5_10/lib/libc_psr.so.1
    #0  0xff21a3dc in _libc_kill () from /usr/lib/libc.so.1
    (gdb) 
    

  2. At the (gdb) command prompt, type the where command. This produces the stack trace of your program that existed when it crashed:

    (gdb) where
    #0  0xff21a3dc in _libc_kill () from /usr/lib/libc.so.1
    #1  0xff1b5324 in abort () from /usr/lib/libc.so.1
    #2  0x0003fdc4 in _STL::vector<int, _STL::allocator<int>
        >::_M_range_check(unsigned) const (this=0xffbee778, __n=1) at
        /export/home/class/cs-509/include/stlport/stl/_vector.h:175 
    #3  0x0003fc1c in _STL::vector<int, _STL::allocator<int>
        >::operator[](unsigned) (this=0xffbee778, __n=1) at
        /export/home/class/cs-509/include/stlport/stl/_vector.h:203
    #4  0x00035f74 in main () at t.cc:6
    (gdb) 
    

    Read the stack trace from the bottom up, starting at main(), looking for the point at which you stop recognizing subroutine names. The last subroutine name you recognize is probably the place you should start looking for the problem.

    In this example, the problem occured in main() at line 6 in file t.cc.

You can also use ddd (dynamic data debugger), which is a graphical front-end to gdb.

What errors does Safer STL detect?


This page last modified on 21 January 2004.