| 
        STLport : Debug Mode
         by Boris Fomitchev 
        Abstract
        Debug mode lets you find very obscure bugs in application code which uses STL iterators and algorithms.  
        It performs runtime checking of iterator validity and ownership and algorithm
        preconditions.  
        When debug check reveals the bug,  it terminates the program
        with detailed diagnostics. 
        STLport in debug mode is as much exception-safe and
        thread-safe as in release mode. 
        Debugging facilities provided
        
          - "Safe iterators" for all STL containers. 
 
            They report detailed diagnostics when being used in invalid ways. 
         
        
          - Checking of preconditions for algorithms and container methods.
            STLport checks the following reasonable set of preconditions:
 
          
            - Range preconditions for random-access iterators
 
            - Iterator's ownership, validity and deferenceability
 
            - Container-specific preconditions for methods
 
           
         
        Implementation
        Checked iterators keep track of their container while the container
        keeps track of them. The idea was introduced in Cay
        Horstmann's "Safe STL". 
        
          - If the container goes out of scope, its iterators are being
            invalidated;
 
          - If certain iterators are being invalidated because of mutating
            operation, all instances of this iterator are invalidated.
 
         
        Usage
        To turn on the debug mode, you should somehow #define _STLP_DEBUG
        macro before including any STL header. You can either supply the
        definition via compiler command-line or within CXXFLAGS in your makefile: 
        $> CC -g -D_STLP_DEBUG foo.cpp 
        Naturally, you may also wrap it into your project configuration
        header : 
        # ifdef _NDEBUG 
        # undef _STLP_DEBUG 
        # else 
        # define _STLP_DEBUG 1 
        # endif 
        Important : you must recompile your project after changing _STLP_DEBUG
        definition. 
        Examples
        Here are some error examples with corresponding runtime output: 
        char string[23] = "A string to be copied."; 
        char result[23];  
        copy(string+20, string+10, result);  
        _debug.h:168 STL error : Range [first,last) is invalid  
        algobase.h:369 STL assertion failure: __check_range(first, last) 
        vector<char>::iterator i;  
        char ii = *i;  
        stldebug.h:152 STL error : Uninitialized or invalidated (by
        mutating operation) iterator used 
        vector.h:158 STL assertion failure: __check_dereferenceable(*this) 
        vector<char>::iterator i=v2.begin();  
        v2.insert(v2.begin(),'!');  
        char ii = *i;  
        _debug.h:152 STL error : Uninitialized or invalidated (by
        mutating operation) iterator used 
        vector.h:158 STL assertion failure: __check_dereferenceable(*this) 
        vector<int> v; v.pop_back(); 
        vector.h:482 STL error : Trying to extract an object out from
        empty container  
        vector.h:482 STL assertion failure: !empty() 
        vector <int> v1(10); 
        for(int i = 0; i < v1.size(); i++)  
        v1[i] = i; vector <int> v2(10);  
        copy(v1.begin(), .end(), v2.begin()); 
        _debug.h:61 STL error : Iterators used in expression are from
        different owners 
        vector.h:182 STL assertion failure: __check_same_owner(*this,y) 
        list<int> l1(array1, array1 + 3);  
        l1.erase(l1.end());  
        list.h:398 STL error : Past-the-end iterator could not be erased  
        list.h:398 STL assertion failure: position.node!=node  
        list<int> l1(array1, array1 + 3);  
        list<int> l2(array2, array2 + 2);  
        l1.erase(l2.begin());  
        _debug.h:70 STL error : Container doesn't own the iterator  
        list.h:397 STL assertion failure: __check_if_owner(node,position)  
        Notes
        
          - Application code using T* to store vector::iterator
            would not compile in debug mode. Such code should be fixed - the
            standard does not specify vector::iterator, so different implementations
            can use different types for it.
 
          - Miscellanous stuff used by debug engine (_debug.h) is
            not documented on purpose. Never explicitly include or otherwise use
            it in your code - it's non-standard and is subject to change.
 
          - The ability to throw exceptions instead of calling abort()
            is provided since 3.2. Please comment out _STLP_NO_DEBUG_EXCEPTIONS switch which 
            disables it as default.
 
          -  If those two defaults do not match your debugging needs,
you may force all failed assertions to be executed through user-defined global function:
  void __stl_debug_terminate(void). This allows you to take control of assertion behavior for debugging purposes. 
          - You can control the way the debug checking messages are being printed out by defining 
your own debug output function. To do so, you should define _STLP_DEBUG_MESSAGE switch in stl_user_config.h and
provide your function with the following signature :
 
void __stl_debug_message(const char * format_str, ...). The parameters are printf()-like. 
STLport will then use it to format debug message output. 
          - Some preconditions that cannot be checked without partial class
            template specialization still left alone. (example : for
            copy(InputIterator first, InputIterator last, OutputIterator result)
            algorithm, result should not be in range [first,last). )
 
          - Unfortunately, the file/line pairs reported by debug engine always
            point to STL code, not to application code. I see no way to fix that
            ( although the diagnostic certainly may be refined ). There's
            no substitute for good debugger to walk up the stack and locate the
            error.
 
         
 |