我的代码中有一个很少发生的问题,其中触发了一个断言,涉及Boost.Thread库。我无法使用独立示例重现此问题,但我不知道是什么造成了这一问题,因此很难提供示例。我希望任何熟悉boost.thread的内部人员都可以提供帮助。win32中的Boost.Thread声明/ Windows崩溃:: WaitForSingleObject
这是我所知道的:
- 当
boost::lock_guard<boost::recursive_mutex>
(或unique_lock和正常的非递归互斥体的变化)宣布出现问题。 - 它发生在Boost.Asio的处理函数中。在堆栈上的线程是
io_service::run
,一堆胶水来调用Asio回调函数,后面跟着我的回调函数(由async_write调用触发)。该函数的第一行是导致该问题的lock_guard<>
的声明。 this
我的函数里面是有效的,并没有被删除或类似的东西。调试器显示它指向有效的数据。被锁定在我的handle_write
函数中的互斥锁还可以防止删除处理函数使用的内存。- 这工作正常,我会说万分之九9,999次,重的多线程使用继续。如果我将应用程序使用的线程数调低至仅处理Asio run()调用的一个线程以及主UI线程,则问题会以相同的频率出现。
- 的我的第一行代码调用互斥的
lock()
方法(在boost::unique_lock<>
的构造函数),然后调用在boost::detail::basic_recursive_mutex_impl
,它调用的boost::detail::basic_timed_mutex
的lock()
方法lock()
。 在升压1.46,断言(
BOOST_VERIFY
)是basic_timed_mutex.hpp的78行,调用的Win32 :: WaitForSingleObject的:do { BOOST_VERIFY(win32::WaitForSingleObject( sem,::boost::detail::win32::infinite)==0); clear_waiting_and_try_lock(old_count); lock_acquired=!(old_count&lock_flag_value); } while(!lock_acquired);
- 在Boost.Thread代码正在等待获取的锁定时(这个代码路径使用
WaitForSingleObject
)做的,没有其他线程持有互斥体(至少在断言发生时,并且可以在调试器中检查)。这很奇怪,因为它应该能够获得锁而不必等待另一个线程放弃控制权。 - 事情看起来很奇怪,检查互斥体的成员。这些都是本地和成员变量的值(除非另有说明,它们是相同的这种情况每次):
sem
- 0xdddddddddddddddd - 这是永远不变的,在每一个崩溃。lock_acquired
- false。old_count
- 0xdddddddddddddddd。this
- 看起来有效,它的地址与它所持有的对象的地址(其对象handle_write
是一种方法)相匹配。它似乎没有以任何方式被删除或混淆。this->active_count
- 一个负整数,我见过的范围一直在-570000000和-580000000之间。this->event
- 0xdddddddddddddddd。
我很遗憾无法看到WaitForSingleObject
调用的结果。 API函数MSDN entry指示了四种可能的返回类型,其中两种在这种情况下是不可能的。由于WaitForSingleObject
正在使用无效事件句柄(sem
= 0xdddddddddddddddd
)进行调用,因此我假定它返回0xFFFFFFFF
,并且GetLastError表示提供了无效句柄。
因此,实际问题似乎是basic_timed_mutex
的get_event()
方法正在返回0xdddddddddddddddd
。但(get_event()
最终使用)的MSDN entry告诉我,它返回一个有效的事件句柄或NULL
。
同样,这可能是我可以提供的问题的最佳描述,因为它不可靠地在此特定应用程序之外可靠地重现。我希望有人对可能造成这种情况的想法有所了解!
堆腐败是我的猜测,这就是它最终成为 - 一个界限溢出。在预感上,我将少数几个使用char []的地方之一切换到了bounds-checked boost :: array,并找到了问题。我不知道AppVerifier,谢谢!然而,我无法让它与我的应用程序一起工作。 – 2011-03-05 22:33:20