我的代码中很少出现问题,其中触发了断言,涉及Boost.Thread库。我无法使用一个独立的示例重现此问题,我真的不知道是什么导致它,所以很难提供一个示例案例。我希望任何熟悉boost.thread内部的人都能提供帮助。
以下是我所知道的:
boost::lock_guard<boost::recursive_mutex>
(或unique_lock和普通非递归互斥锁的变体)时会出现问题。io_service::run
的线程,一堆调用Asio回调函数的粘合剂,然后是我的回调函数(由async_write调用触发)。该函数的第一行是导致问题的lock_guard<>
的声明。this
是有效的,并且还没有被删除或类似的东西。调试器显示它指向有效数据。锁定在handle_write
函数中的互斥锁也可以防止删除处理函数使用的内存。lock()
方法(在boost::unique_lock<>
的ctor中),然后在lock()
中调用boost::detail::basic_recursive_mutex_impl
,调用{ {1}} lock()
。在Boost 1.46中,断言(boost::detail::basic_timed_mutex
)位于basic_timed_mutex.hpp的第78行,它调用win32 :: WaitForSingleObject:
BOOST_VERIFY
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);
的代码路径)时,没有其他线程持有互斥锁(至少在断言时)发生,并可以在调试器中检查)。这很奇怪,因为它应该能够获得锁定,而不必等待另一个线程放弃控制。WaitForSingleObject
- 0xdddddddddddddddddddddddddddddddddddddddddddddddddddddddddd。 - 每次崩溃都是一样的。sem
- false 。 lock_acquired
- 0xdddddddddddddddddd 。 old_count
- 看似有效,并且它的地址与持有它的对象(其中this
是一个方法的对象)相匹配。它似乎没有被删除或以任何方式搞乱。handle_write
- 一个负整数,我见过的范围介于-570000000和-580000000之间。this->active_count
- 0xdddddddddddddddddd 。 我很遗憾无法看到this->event
电话的结果。 API函数上的MSDN entry表示四种可能的返回类型,在这种情况下其中两种是不可能的。由于使用无效事件句柄(WaitForSingleObject
= WaitForSingleObject
)调用sem
,因此我假设它返回0xdddddddddddddddd
并且GetLastError将指示已提供无效句柄。< / p>
所以实际问题似乎是0xFFFFFFFF
的{{1}}方法正在返回get_event()
。但是,basic_timed_mutex
0xdddddddddddddddd
(CreateEvent
最终使用)告诉我它返回事件的有效句柄或get_event()
。
同样,这可能是我能提供的问题的最佳描述,因为它不能在此特定应用程序之外可靠地再现。我希望有人能够了解导致这种情况的原因!
答案 0 :(得分:3)
我想要对您的问题给出一个精确的答案是非常困难的,但似乎您有一个堆损坏问题,您是否尝试过使用正常的pageheap启用AppVerifier? 如果然后将调试器附加到进程并且存在堆损坏,那么当遇到损坏的堆块时,它肯定会中断,您甚至可以查看分配代码的callstack。
编辑:如果使用WinDbg你也可以在WaitForSingleObject(或任何其他函数)上放置条件断点,只有在调用失败时才会中断,然后检查最后一个错误,例如: bp kernel32 !WaitForSingleObject“gu; .if(eax == 0){g}” - &gt;这将告诉调试器在断点处i)运行到函数结束(gu)和ii)检查返回值(存储在EAX寄存器中)并继续执行(g)如果一切正常。如果返回错误,您可以使用!gle 扩展命令检查GetLastError()的值。