其他线程堆栈上的无效内存释放
invalid free of memory on other thread's stack
我正在尝试正确中断使用共享内存的线程,但这并不是那么简单。我正在使用 Boost.lockfree 和 Boost.Thread。这是我创建的 类:
typedef std::shared_ptr<Parameters_parser> sh_params_t;
typedef std::shared_ptr<Shared_objects> sh_obj_t;
class Abstract_thread {
public:
Abstract_thread(sh_params_t params, sh_obj_t sh_obj):
params(params), sh_obj(sh_obj) {}
virtual ~Abstract_thread() = 0;
virtual void launch() = 0;
protected:
/** The shared parameters of the execution. */
sh_params_t params;
/** The Shared_objects containing all queues. */
sh_obj_t sh_obj;
};
inline Abstract_thread::~Abstract_thread(){
cout << "Abstract_thread destructor with params: "
<< params.use_count() << " and sh_obj: " <<
sh_obj.use_count() << endl;
}
class Interface_sniffer : public Abstract_thread {
Interface_sniffer(sh_params_t params, sh_obj_t sh_obj):
Abstract_thread(params, sh_obj) {}
~Interface_sniffer(){
cout << "Good bye from Interface_sniffer1 !" << endl;
}
void launch(){
try {
while(true)
interruption_point();
} catch(thread_interrupted const& e) {
disable_interruption di;
delete this;
}
}
};
然后,主要是:
void main(int argc, char* argv[]) {
sh_obj_t sh_obj = std::make_shared<Shared_objects>();
sh_params_t params = std::make_shared<Parameters_parser>();
Interface_sniffer sniffer1(params, sh_obj);
boost::thread t1(bind(&Interface_sniffer::launch, &sniffer1));
boost::this_thread::sleep_for(boost::chrono::seconds(5));
cout << "trying to stop 1" << endl;
t1.interrupt();
t1.join();
}
Parameters_parser
和 Shared_objects
是基本的 类,包含仅由我的线程或 boost::lockfree::queue 读取的字段,这应该不是问题。
所以当我 运行 它时,valgrind 告诉我:
trying to stop 1
Good bye from Interface_sniffer1 !
Abstract_thread destructor with params: 2 and sh_obj: 2
==2095== Thread 2:
==2095== Invalid free() / delete / delete[] / realloc()
==2095== at 0x4C2F24B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2095== by 0x41A1C1: Interface_sniffer::~Interface_sniffer() (interface_sniffer.cpp:34)
==2095== by 0x41A6DC: Interface_sniffer::launch() (interface_sniffer.cpp:69)
==2095== by 0x44D1E8: void std::_Mem_fn_base<void (Interface_sniffer::*)(), true>::operator()<, void>(Interface_sniffer*) const (in somewhere)
==2095== by 0x44D162: void std::_Bind<std::_Mem_fn<void (Interface_sniffer::*)()> (Interface_sniffer*)>::__call<void, , 0ul>(std::tuple<>&&, std::_Index_tuple<0ul>) (in somewhere)
==2095== by 0x44D115: void std::_Bind<std::_Mem_fn<void (Interface_sniffer::*)()> (Interface_sniffer*)>::operator()<, void>() (in somewhere)
==2095== by 0x44CB9B: boost::detail::thread_data<std::_Bind<std::_Mem_fn<void (Interface_sniffer::*)()> (Interface_sniffer*)> >::run() (thread.hpp:116)
==2095== by 0x50C95D4: ??? (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.58.0)
==2095== by 0x604D6B9: start_thread (pthread_create.c:333)
==2095== by 0x636A3DC: clone (clone.S:109)
==2095== Address 0xfff000240 is on thread 1's stack
==2095== in frame #3, created by main (main.cpp:23)
==2095==
所以它假装我正在删除位于主线程堆栈上的东西(我假设 params
和 sh_obj
),但这不是真的,因为 [=33= 指向的对象] 在堆上。我能做什么 ?我应该将 shared_ptr<>*
传递给我的线程,并在析构函数中手动调用 params->reset()
和 sh_obj->reset()
吗?
Interface_sniffer
包含此代码:
delete this;
并且 main()
包含此代码:
Interface_sniffer sniffer1(params, sh_obj);
所以你正在删除一个堆栈分配的对象,正如 valgrind 所说。这是未定义的行为。
由于 delete this
非常不寻常(尽管有时有效甚至有用),最好重新考虑为什么以及是否需要它。从您的代码中看不出您确实需要它。
我正在尝试正确中断使用共享内存的线程,但这并不是那么简单。我正在使用 Boost.lockfree 和 Boost.Thread。这是我创建的 类:
typedef std::shared_ptr<Parameters_parser> sh_params_t;
typedef std::shared_ptr<Shared_objects> sh_obj_t;
class Abstract_thread {
public:
Abstract_thread(sh_params_t params, sh_obj_t sh_obj):
params(params), sh_obj(sh_obj) {}
virtual ~Abstract_thread() = 0;
virtual void launch() = 0;
protected:
/** The shared parameters of the execution. */
sh_params_t params;
/** The Shared_objects containing all queues. */
sh_obj_t sh_obj;
};
inline Abstract_thread::~Abstract_thread(){
cout << "Abstract_thread destructor with params: "
<< params.use_count() << " and sh_obj: " <<
sh_obj.use_count() << endl;
}
class Interface_sniffer : public Abstract_thread {
Interface_sniffer(sh_params_t params, sh_obj_t sh_obj):
Abstract_thread(params, sh_obj) {}
~Interface_sniffer(){
cout << "Good bye from Interface_sniffer1 !" << endl;
}
void launch(){
try {
while(true)
interruption_point();
} catch(thread_interrupted const& e) {
disable_interruption di;
delete this;
}
}
};
然后,主要是:
void main(int argc, char* argv[]) {
sh_obj_t sh_obj = std::make_shared<Shared_objects>();
sh_params_t params = std::make_shared<Parameters_parser>();
Interface_sniffer sniffer1(params, sh_obj);
boost::thread t1(bind(&Interface_sniffer::launch, &sniffer1));
boost::this_thread::sleep_for(boost::chrono::seconds(5));
cout << "trying to stop 1" << endl;
t1.interrupt();
t1.join();
}
Parameters_parser
和 Shared_objects
是基本的 类,包含仅由我的线程或 boost::lockfree::queue 读取的字段,这应该不是问题。
所以当我 运行 它时,valgrind 告诉我:
trying to stop 1
Good bye from Interface_sniffer1 !
Abstract_thread destructor with params: 2 and sh_obj: 2
==2095== Thread 2:
==2095== Invalid free() / delete / delete[] / realloc()
==2095== at 0x4C2F24B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2095== by 0x41A1C1: Interface_sniffer::~Interface_sniffer() (interface_sniffer.cpp:34)
==2095== by 0x41A6DC: Interface_sniffer::launch() (interface_sniffer.cpp:69)
==2095== by 0x44D1E8: void std::_Mem_fn_base<void (Interface_sniffer::*)(), true>::operator()<, void>(Interface_sniffer*) const (in somewhere)
==2095== by 0x44D162: void std::_Bind<std::_Mem_fn<void (Interface_sniffer::*)()> (Interface_sniffer*)>::__call<void, , 0ul>(std::tuple<>&&, std::_Index_tuple<0ul>) (in somewhere)
==2095== by 0x44D115: void std::_Bind<std::_Mem_fn<void (Interface_sniffer::*)()> (Interface_sniffer*)>::operator()<, void>() (in somewhere)
==2095== by 0x44CB9B: boost::detail::thread_data<std::_Bind<std::_Mem_fn<void (Interface_sniffer::*)()> (Interface_sniffer*)> >::run() (thread.hpp:116)
==2095== by 0x50C95D4: ??? (in /usr/lib/x86_64-linux-gnu/libboost_thread.so.1.58.0)
==2095== by 0x604D6B9: start_thread (pthread_create.c:333)
==2095== by 0x636A3DC: clone (clone.S:109)
==2095== Address 0xfff000240 is on thread 1's stack
==2095== in frame #3, created by main (main.cpp:23)
==2095==
所以它假装我正在删除位于主线程堆栈上的东西(我假设 params
和 sh_obj
),但这不是真的,因为 [=33= 指向的对象] 在堆上。我能做什么 ?我应该将 shared_ptr<>*
传递给我的线程,并在析构函数中手动调用 params->reset()
和 sh_obj->reset()
吗?
Interface_sniffer
包含此代码:
delete this;
并且 main()
包含此代码:
Interface_sniffer sniffer1(params, sh_obj);
所以你正在删除一个堆栈分配的对象,正如 valgrind 所说。这是未定义的行为。
由于 delete this
非常不寻常(尽管有时有效甚至有用),最好重新考虑为什么以及是否需要它。从您的代码中看不出您确实需要它。