私のプログラムは、再現できる小さなシナリオでランダムにクラッシュしますが、ntdll.dllのmlock.c(これはVC++ランタイムファイルです)で発生します。スタックトレース。私はそれが私のスレッド関数のいずれかで起こることを知っています。VC++ 2010:奇妙なクリティカルセクションエラー
void __cdecl _unlock (
int locknum
)
{
/*
* leave the critical section.
*/
LeaveCriticalSection(_locktable[locknum].lock);
}
エラー「指定された無効なハンドル」です:
これは、プログラムがクラッシュしmlock.cコードです。 locknumを見ると、_locktableのサイズよりも大きい数字なので、これは意味があります。
これはクリティカルセクションの使用に関連しているようです。私は、CCriticalSectionラッパークラスとそれに関連するRAIIガード、CGuardを介して、自分のスレッドでCRITICAL_SECTIONSを使用します。より多くの乱雑さを避けるために、両方ともの定義はhereです。
これはクラッシュのスレッド機能である:
unsigned int __stdcall CPlayBack::timerThread(void * pParams) {
#ifdef _DEBUG
DRA::CommonCpp::SetThreadName(-1, "CPlayBack::timerThread");
#endif
CPlayBack * pThis = static_cast<CPlayBack*>(pParams);
bool bContinue = true;
while(bContinue) {
float m_fActualFrameRate = pThis->m_fFrameRate * pThis->m_fFrameRateMultiplier;
if(m_fActualFrameRate != 0 && pThis->m_bIsPlaying) {
bContinue = (::WaitForSingleObject(pThis->m_hEndThreadEvent, static_cast<DWORD>(1000.0f/m_fActualFrameRate)) == WAIT_TIMEOUT);
CImage img;
if(pThis->m_bIsPlaying && pThis->nextFrame(img))
pThis->sendImage(img);
}
else
bContinue = (::WaitForSingleObject(pThis->m_hEndThreadEvent, 10) == WAIT_TIMEOUT);
}
::GetErrorLoggerInstance()->Log(LOG_TYPE_NOTE, "CPlayBack", "timerThread", "Exiting thread");
return 0;
}
CCriticalSection
がでてくるのでしょうか?すべてのCImage
オブジェクトにはCGuard
RAIIロックで使用するCCriticalSection
オブジェクトが含まれています。さらに、CImage
にはそれぞれ、参照カウントを実装するCSharedMemory
オブジェクトが含まれています。そのために、2つのCCriticalSection
も含まれています.1つはデータ用、もう1つは参照カウンタ用です。これらの相互作用の良い例は、デストラクタで見られる最高です。この種のエラーにぶつかっ
CImage::~CImage() {
CGuard guard(m_csData);
if(m_pSharedMemory != NULL) {
m_pSharedMemory->decrementUse();
if(!m_pSharedMemory->isBeingUsed()){
delete m_pSharedMemory;
m_pSharedMemory = NULL;
}
}
m_cProperties.ClearMin();
m_cProperties.ClearMax();
m_cProperties.ClearMode();
}
CSharedMemory::~CSharedMemory() {
CGuard guardUse(m_cs);
if(m_pData && m_bCanDelete){
delete []m_pData;
}
m_use = 0;
m_pData = NULL;
}
誰ですか?なにか提案を?
を編集します。コールスタックを確認する必要があります。呼び出しは〜CSharedMemoryから行われます。だから、そこにいくつかの競合状態
編集がなければならない。もっとCSharedMemoryコードhere
メモリ破損? –
2つのクラス自体は上手く見えます。あなたはそれらをどのように使用しているかに関するいくつかのコードを表示できますか?コンストラクタが正しく使用される前に適切に呼び出されていることを確認してください(コンストラクタのスレッド競合はありませんか?)。動的に(何らかの理由で)割り当てられていますか? – Chad
あなたのクラスはCRTコードとは何の関係もなく、Windowsを使用しています。スレッドレースとヒープの破損をデバッグすることは決して楽しいことではありません。 –