[Boost-bugs] [Boost C++ Libraries] #6978: Crash in rbtree_algorithms::rebalance_after_erasure, new in 1.49

Subject: [Boost-bugs] [Boost C++ Libraries] #6978: Crash in rbtree_algorithms::rebalance_after_erasure, new in 1.49
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2012-06-10 23:09:24


#6978: Crash in rbtree_algorithms::rebalance_after_erasure, new in 1.49
----------------------------------------------+-----------------------------
 Reporter: jeff-boosttrac@… | Owner: igaztanaga
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: intrusive
  Version: Boost 1.49.0 | Severity: Regression
 Keywords: |
----------------------------------------------+-----------------------------
 The code below crashes with boost 1.49.

 This is because of a change in 1.49 to return references from
 node_traits::get* and take references as parameters to all tree
 algorithms.

 The code gets a reference to header.left with
 node_traits::get_left(header), and passes that reference into
 rbtree_algorithms::erase.

 tree_algorithms::erase does a node_traits::set_left(header, ...) at some
 point, and since z is a reference to header.left, the z pointer changes
 halfway through tree_algorithms::erase, and passing the wrong z pointer to
 rebalance_after_erasure after that causes the crash.

 {{{
 #include <iostream>
 #include "boost/intrusive/options.hpp"
 #include "boost/intrusive/rbtree_algorithms.hpp"
 #include "boost/intrusive/rbtree.hpp"

 struct my_type : public boost::intrusive::set_base_hook<>
 {
     my_type(int i) : i_(i) {}
     int i_;
 };

 typedef boost::intrusive::rbtree<my_type>::node_traits my_traits;

 struct Compare
 {
     bool operator()(my_traits::const_node_ptr a, my_traits::const_node_ptr
 b) { return static_cast<const my_type*>(a)->i_ < static_cast<const
 my_type*>(b)->i_; }
 };

 int main()
 {
     std::cout << "if i wrap the pointer ref... " << std::endl;
     {
         my_traits::node header;
 boost::intrusive::rbtree_algorithms<my_traits>::init_header(&header);
         for (int i = 0; i < 20; ++i)
 boost::intrusive::rbtree_algorithms<my_traits>::insert_equal(&header,
 &header, new my_type(i), Compare());
         for (int i = 0; i < 20; ++i)
             boost::intrusive::rbtree_algorithms<my_traits>::erase(&header,
 my_traits::node_ptr(my_traits::get_right(&header)));
     }
     std::cout << " OK!" << std::endl;
     std::cout << "if i don't wrap the pointer ref... " << std::endl;
     {
         my_traits::node header;
 boost::intrusive::rbtree_algorithms<my_traits>::init_header(&header);
         for (int i = 100; i < 120; ++i)
 boost::intrusive::rbtree_algorithms<my_traits>::insert_equal(&header,
 &header, new my_type(i), Compare());
         for (int i = 0; i < 20; ++i)
 boost::intrusive::rbtree_algorithms<my_traits>::insert_equal(&header,
 &header, new my_type(i), Compare());
         for (int i = 0; i < 20; ++i)
             boost::intrusive::rbtree_algorithms<my_traits>::erase(&header,
 my_traits::get_left(&header));
     }
     std::cout << " OK!" << std::endl; // not really OK, it'll crash before
 it gets here
     return 0;
 }

 }}}

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/6978>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:09 UTC