Subject: Re: [Boost-bugs] [Boost C++ Libraries] #11053: The attached code results in a R6025 - pure virtual function call in run_thread_exit_callbacks
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-02-28 20:53:14
#11053: The attached code results in a R6025 - pure virtual function call in
run_thread_exit_callbacks
-------------------------------+----------------------
Reporter: swebb3@⦠| Owner: viboes
Type: Bugs | Status: assigned
Milestone: To Be Determined | Component: thread
Version: Boost 1.55.0 | Severity: Problem
Resolution: | Keywords:
-------------------------------+----------------------
Description changed by viboes:
Old description:
> Caused when deallocating a thread specific pointer in a object that is
> inside thread specific data.
> I suggest changing the code in run_thread_exit_callbacks from
>
> {{{
> for(std::map<void const*,detail::tss_data_node>::iterator
> next=current_thread_data->tss_data.begin(),
> current,
> end=current_thread_data->tss_data.end();
> next!=end;)
> {
> current=next;
> ++next;
> if(current->second.func && (current->second.value!=0))
> {
> (*current->second.func)(current->second.value);
> }
> current_thread_data->tss_data.erase(current);
> }
> }}}
> to
>
> {{{
> while (!current_thread_data->tss_data.empty())
> {
> std::map<void const*,detail::tss_data_node>::iterator current
> = current_thread_data->tss_data.begin()
> if(current->second.func && (current->second.value!=0))
> {
> (*current->second.func)(current->second.value);
> }
> current_thread_data->tss_data.erase(current);
> }
>
> }}}
>
> Code to reproduce the problem:
> {{{
> #include <boost/thread.hpp>
> #include <boost/thread/tss.hpp>
> #include <boost/shared_ptr.hpp>
> #include <iostream>
>
> struct A
> {
> void DoWork()
> {
> std::cout << "A: doing work\n";
> if (!m_ptr.get())
> m_ptr.reset(new WorkSpace());
> // do not very much
> for (size_t i = 0; i < 10; ++i)
> m_ptr->a += 10;
> }
>
> private:
> struct WorkSpace
> {
> int a;
> WorkSpace() : a(0) {}
> };
> boost::thread_specific_ptr<WorkSpace> m_ptr;
> };
>
> struct B
> {
> void DoWork()
> {
> std::cout << "B: doing work\n";
> if (!m_ptr.get())
> m_ptr.reset(new A());
> m_ptr->DoWork();
> }
> private:
> boost::thread_specific_ptr<A> m_ptr;
> };
>
> struct C
> {
> void DoWork()
> {
> std::cout << "C: doing work\n";
> if (!m_ptr.get())
> m_ptr.reset(new B());
> m_ptr->DoWork();
> }
> private:
> boost::thread_specific_ptr<B> m_ptr;
> };
>
> int main(int ac, char** av)
> {
> std::cout << "test starting\n";
> boost::shared_ptr<C> p_C(new C);
> boost::thread cWorker(&C::DoWork, p_C);
> cWorker.join();
> std::cout << "test stopping\n";
> }
> }}}
>
> Compiler visual studio 2012
New description:
Caused when deallocating a thread specific pointer in a object that is
inside thread specific data.
I suggest changing the code in run_thread_exit_callbacks from
{{{
for(std::map<void const*,detail::tss_data_node>::iterator
next=current_thread_data->tss_data.begin(),
current,
end=current_thread_data->tss_data.end();
next!=end;)
{
current=next;
++next;
if(current->second.func && (current->second.value!=0))
{
(*current->second.func)(current->second.value);
}
current_thread_data->tss_data.erase(current);
}
}}}
to
{{{
while (!current_thread_data->tss_data.empty())
{
std::map<void const*,detail::tss_data_node>::iterator current
= current_thread_data->tss_data.begin();
if(current->second.func && (current->second.value!=0))
{
(*current->second.func)(current->second.value);
}
current_thread_data->tss_data.erase(current);
}
}}}
Code to reproduce the problem:
{{{
#include <boost/thread.hpp>
#include <boost/thread/tss.hpp>
#include <boost/shared_ptr.hpp>
#include <iostream>
struct A
{
void DoWork()
{
std::cout << "A: doing work\n";
if (!m_ptr.get())
m_ptr.reset(new WorkSpace());
// do not very much
for (size_t i = 0; i < 10; ++i)
m_ptr->a += 10;
}
private:
struct WorkSpace
{
int a;
WorkSpace() : a(0) {}
};
boost::thread_specific_ptr<WorkSpace> m_ptr;
};
struct B
{
void DoWork()
{
std::cout << "B: doing work\n";
if (!m_ptr.get())
m_ptr.reset(new A());
m_ptr->DoWork();
}
private:
boost::thread_specific_ptr<A> m_ptr;
};
struct C
{
void DoWork()
{
std::cout << "C: doing work\n";
if (!m_ptr.get())
m_ptr.reset(new B());
m_ptr->DoWork();
}
private:
boost::thread_specific_ptr<B> m_ptr;
};
int main(int ac, char** av)
{
std::cout << "test starting\n";
boost::shared_ptr<C> p_C(new C);
boost::thread cWorker(&C::DoWork, p_C);
cWorker.join();
std::cout << "test stopping\n";
}
}}}
Compiler visual studio 2012
-- -- Ticket URL: <https://svn.boost.org/trac/boost/ticket/11053#comment:2> 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:18 UTC