[Boost-bugs] [Boost C++ Libraries] #13283: boost log crash during thread termination

Subject: [Boost-bugs] [Boost C++ Libraries] #13283: boost log crash during thread termination
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2017-11-02 14:15:41


#13283: boost log crash during thread termination
-----------------------------------------------+---------------------
 Reporter: Marco Strohner <marco.strohner@…> | Owner: (none)
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: None
  Version: Boost 1.64.0 | Severity: Problem
 Keywords: |
-----------------------------------------------+---------------------
 I'm using boost 1.64 on iOS and Android. Adding trivial log causes a crash
 during thread termination.

 Removing more and more code produces the follwing example code for
 reproducing the issue. In the default settings in XCode it randomly
 crashed.

 Enabling all memory related helper in the Scheme (memory guards, ...)
 helps because it crashes more reproducible and procudes better callstacks.

 My result of debugging is:

 1. the first executed log line -> creates a thread local storage object
 with the severity - this severity is stored in ''severity_level_holder''
 which creates a thread local storage with an automatic deleter
 (''boost::this_thread::at_thread_exit(boost::bind(checked_deleter<
 uintmax_t >(), p));'') - saw this in ''severity_level.cpp''
 2. normal Code -> logging works
 3. thread terminates
 4. the destructor of the TestClass is called and adds a result to the
 internal promise -> logging works
 5. the automatic deleter is called and frees the memory block for the
 severity.
 6. the TestClass of the internal promise is destroyed -> logging crashes
 because it tries to read the destroyed severity memory block.

 {{{
 #include <memory>

 #ifndef BOOST_THREAD_PROVIDES_FUTURE
 #define BOOST_THREAD_PROVIDES_FUTURE
 #endif

 #ifndef BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
 #define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
 #endif

 #include <boost/thread/thread.hpp>
 #include <boost/thread/future.hpp>
 #include <boost/log/trivial.hpp>

 class TestClass {
 public:
   TestClass(bool shouldSet) : shouldSet_(shouldSet) {}

   virtual ~TestClass() {
     if (shouldSet_) {
       BOOST_LOG_TRIVIAL(warning) << "crashes here";
       promise_.set_value(std::unique_ptr<TestClass>(new
 TestClass(false)));
     }
   }

   bool shouldSet_;
   boost::promise<std::unique_ptr<TestClass>> promise_;
 };

 int main(int, char **) {
 #define N 1

   auto wait_future = boost::async([](){
     auto task = []() {
       for (int i=0;i<1000;i++) {
         BOOST_LOG_TRIVIAL(warning) << "Create event #" << i;
         std::shared_ptr<TestClass> event = std::shared_ptr<TestClass>(new
 TestClass(false));
         boost::future<std::unique_ptr<TestClass>> future =
 event->promise_.get_future();
 future.then([i](boost::future<std::unique_ptr<TestClass>>){BOOST_LOG_TRIVIAL(warning)
 << "event handled #" << i; });
         boost::async([event, i](){
           event->promise_.set_value(std::unique_ptr<TestClass>(new
 TestClass(true)));
           BOOST_LOG_TRIVIAL(warning) << "Destroy event #" << i;
         }).wait();
       }
     };
     boost::future<void> f[N];

     for(int j=0; j<N; j++){
       f[j] = boost::async(task);
     }
     for(int j=0; j<N; j++){
       f[j].wait();
     }

   });

   wait_future.wait_for(boost::chrono::seconds(10));
   return 0;
 }
 }}}

-- 
Ticket URL: <https://svn.boost.org/trac10/boost/ticket/13283>
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-11-02 14:22:10 UTC