2010-11-30 26 views
0

スレッド関数を終了すると、アプリケーションがクラッシュしています。スレッド終了時にアプリケーションがクラッシュする - C++

DWORD NotifyWindowThreadFn(void * pParam) 
{ 
    static CNotifyWindow * pobjNotifyWindow = NULL; 
    CSerialPort * pobjSerialPort = reinterpret_cast<CSerialPort *>(pParam); 

    // Create notify window to handle surprize removal/insertion events... 
    try 
    { 
     pobjNotifyWindow = new CNotifyWindow(); 
    } 
    catch (DWORD error) 
    { 
     return error;    // 1. PC gets here 
    } 
    catch (long error) 
    { 
     return error; 
    } 
    catch (...) 
    { 
     return ERROR_CANNOT_MAKE; 
    } 

    /* Other stuff that is not executed due to return. */ 

}          // 2. PC then gets here 

アプリケーションがクラッシュしたが、Visual Studioが私にこのエラーメッセージが表示できます::

をこれが実行されます私のスレッド関数の部分がある

LPTHREAD_START_ROUTINE pThreadStart = (LPTHREAD_START_ROUTINE)NotifyWindowThreadFn; 
void * pvThreadData = reinterpret_cast<void *>(_pobjSerialPort); 

// Create the exit notify window thread event handle. 
_hNotifyWindowThreadExitEvent = ::CreateEvent(
    NULL,       // No security 
    TRUE,       // Create a manual-reset event object 
    FALSE,       // Initial state is non-signaled 
    NULL       // No name specified 
    ); 

if (_hNotifyWindowThreadExitEvent == NULL) 
{ 
    TRACE(_T("CreateNotifyWindow : Failed to get a handle for the exit message-only window event.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__); 
    return ::GetLastError(); 
} 

// Create the notify window thread to begin execution on its own. 
_hNotifyWindowThread = ::CreateThread(
    NULL,       // No security attributes. 
    0,        // Use default initial stack size. 
    pThreadStart,     // Function to execute in new thread. 
    pvThreadData,     // Thread parameters. 
    0,        // Use default creation settings. 
    NULL       // Thread ID is not needed. 
    ); 

if (_hNotifyWindowThread == NULL) 
{ 
    TRACE(_T("CreateNotifyWindow : Failed to create handle for message-only window thread.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), ::GetLastError(), __WFILE__, __LINE__); 
    return ::GetLastError(); 
} 

:これは私のスレッドが初期化されている方法です

WindowsがCppTestConsole.exeでブレークポイントを起動しました。

ヒープが破損している可能性があります。これは、CppTestConsole.exeまたは読み込んだDLLにバグがあることを示しています。

これは、CppTestConsole.exeにフォーカスがある間にユーザーがF12キーを押したことが原因である可能性もあります。

出力ウィンドウには、より多くの診断情報が含まれている場合があります。

出力ウィンドウには特に便利なものはありません。のみ...

スレッド 'NotifyWindowThreadFn'(0x414)がコード0(0x0)で終了しました。

次に、一連のDLLがアンロードされることを示します。 [中断]ボタンをクリックすると、PCはdbgheap.cの_CrtIsValidHeapPointerの末尾にあります。スレッドが終了したときに私のアプリケーションがクラッシュする理由は誰にも分かりますか?私はスレッド関数内から直接戻りませんか?ありがとう。

答えて

3

私は間違っているかもしれませんが、ワーカースレッドからウィンドウを作成しようとしているようです。これをしないでください。 Windowsは機能するためにメッセージポンプが必要です。アプリケーションにはメッセージポンプが1つしかありません。メインスレッドにあります。

+0

それがメッセージを受信したときに 'WndProc'機能はまだ実行しますか?私は 'CreateWindow'は新しいスレッドでウィンドウを起動しないと思った。それを作成したスレッドで実行されます。 –

+0

私は「信頼してください」と言って自分自身を笑った。もし誰かが私に言った、私は、 "ええ、右のようになるだろう。とにかく、ウィンドウをワーカースレッドで実行させたいと思う理由を説明し、それについて議論することができます。 –

+0

基本的には、驚きのUSB削除と挿入イベントを処理するためにのみウィンドウが作成されています。ユーザーインターフェイスはありません。これらのイベントが発生すると、WndProcを非同期的に実行してUSBデバイスの状態を残りのアプリケーションASAPにフラグを立て、USBポートを使用したシリアルI/Oを最小限の影響で中断または再開できるようにする必要がありますデータの損失)を可能な限りアプリケーションに提供します。 –

0

のCreateThreadの代わり_beginthreadexを使用してみてください:

Cランタイムライブラリ(CRT)を呼び出し、実行中のスレッドを スレッド管理よりもむしろのCreateThread ため_beginthreadexと _endthreadex関数を使用する必要がありますおよびExitThread。これには、 CRTのマルチスレッドバージョンの を使用する必要があります。 CreateThreadを使用して作成されたスレッドがCRTを呼び出した場合、CRT は、メモリが不足している状態で のプロセスを終了させる可能性があります。

+0

@ Jim Fellはこの問題を引き起こすanythignをしているようには見えません。さらに、CRTを使用するスレッドでCreateThread()を使用することによって発生する問題のほとんど(すべてではない)が修正されています。これはおそらく問題ではありません。 –

+0

おそらく、新しいオブジェクトを作成しても、ヒープ/スタックを(ウィンドウであっても)ゴミ箱に入れてはいけません。私はエドウィンが問題を見つけたと思う。 (または少なくとも* a *問題。いくつかあります:)。 –

1

あなたのようにあなたが機能宣言と定義すべきである:DWORD WINAPI NotifyWindowThreadFn(void *型pParam)

+0

+1これ。実際には、関数ポインタをまったくキャストする必要はありません。何かが間違っていることを示す必要があります。 –

+0

と恐ろしい、不要で危険なキャストontheそれを削除する –

+0

@レオDavidson:よくない完全に。 COMのためのCのプログラムなら、あなたはそれらをwthouできません(私は考えました)。 –

関連する問題