title: boost python threading segmentation fault
body: <p>Consider the following straightforward python extension. When <code>start()-ed</code>, <code>Foo</code> will just add the next sequential integer to a <code>py::list</code>, once a second:</p>
  
  <pre><code>#include &lt;boost/python.hpp&gt;
  #include &lt;thread&gt;
  #include &lt;atomic&gt;
  
  namespace py = boost::python;
  
  struct Foo {
      Foo() : running(false) { } 
      ~Foo() { stop(); }   
  
      void start() {
          running = true;
          thread = std::thread([this]{
              while(running) {
                  std::cout &lt;&lt; py::len(messages) &lt;&lt; std::end;
                  messages.append(py::len(messages));
                  std::this_thread::sleep_for(std::chrono::seconds(1));
              }
          });
      }   
  
      void stop() {
          if (running) {
              running = false;
              thread.join();
          }
      }   
  
      std::thread thread;
      py::list messages;
      std::atomic&lt;bool&gt; running;
  };
  
  BOOST_PYTHON_MODULE(Foo)
  {
      PyEval_InitThreads();
  
      py::class_&lt;Foo, boost::noncopyable&gt;("Foo",
          py::init&lt;&gt;())
          .def("start", &amp;Foo::start)
          .def("stop", &amp;Foo::stop)
      ;   
  }
  </code></pre>
  
  <p>Given the above, the following simple python script segfaults all the time, never even printing anything:</p>
  
  <pre><code>&gt;&gt;&gt; import Foo
  &gt;&gt;&gt; f = Foo.Foo()
  &gt;&gt;&gt; f.start()
  &gt;&gt;&gt; Segmentation fault (core dumped)
  </code></pre>
  
  <p>With the core pointing to:</p>
  
  <pre><code>namespace boost { namespace python {
  
      inline ssize_t len(object const&amp; obj)
      {   
          ssize_t result = PyObject_Length(obj.ptr());
          if (PyErr_Occurred()) throw_error_already_set(); // &lt;==
          return result;
      }   
  
  }} // namespace boost::python
  </code></pre>
  
  <p>Where:</p>
  
  <pre><code>(gdb) inspect obj
  $1 = (const boost::python::api::object &amp;) @0x62d368: {&lt;boost::python::api::object_base&gt; = {&lt;boost::python::api::object_operators&lt;boost::python::api::object&gt;&gt; = {&lt;boost::python::def_visitor&lt;boost::python::api::object&gt;&gt; = {&lt;No data fields&gt;}, &lt;No data fields&gt;}, m_ptr = []}, &lt;No data fields&gt;}
  (gdb) inspect obj.ptr()
  $2 = []
  (gdb) inspect result
  $3 = 0
  </code></pre>
  
  <p>Why does this fail when run in a thread? <code>obj</code> looks fine, <code>result</code> gets set correctly. Why does <code>PyErr_Occurred()</code> happen? Who sets that?</p>