我的代碼中有一個很少發生的問題,其中觸發了一個斷言,涉及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