应用程序在线程退出时崩溃 - C++

发布于 2024-10-04 19:52:05 字数 2814 浏览 3 评论 0原文

我的应用程序在退出线程函数时崩溃。这是我的线程的初始化方式:

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();
}

这是我的线程函数的执行部分:

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 会给出以下错误消息:

Windows 已在 CppTestConsole.exe 中触发断点。

这可能是由于堆损坏造成的,这表明 CppTestConsole.exe 或其加载的任何 DLL 中存在错误。

这也可能是由于用户在 CppTestConsole.exe 获得焦点时按了 F12。

输出窗口可能有更多诊断信息。

输出窗口没有任何特别有用的东西。仅有的...

线程“NotifyWindowThreadFn”(0x414) 已退出,代码为 0 (0x0)。

然后显示一堆DLL被卸载了。当我单击“Break”按钮时,PC 位于 dbgheap.c 中的 _CrtIsValidHeapPointer 的末尾。有谁知道为什么我的应用程序在线程退出时崩溃?我不应该直接从线程函数中返回吗?谢谢。

My application is crashing when it exits the thread function. This is how my thread is initialized:

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();
}

This is the portion of my thread function that gets executed:

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

When the application crashes, Visual Studio gives me this error message:

Windows has triggered a breakpoint in CppTestConsole.exe.

This may be due to a corruption of the heap, which indicates a bug in CppTestConsole.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while CppTestConsole.exe has focus.

The output window may have more diagnostic information.

The output window doesn't have anything especially useful. Only...

The thread 'NotifyWindowThreadFn' (0x414) has exited with code 0 (0x0).

Then it shows that a bunch of DLLs are unloaded. When I click the Break button, the PC is at the end of _CrtIsValidHeapPointer in dbgheap.c. Does anyone have any ideas as to why my application is crashing when the thread exits? Should I not be returning directly from within a threaded function? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

生寂 2024-10-11 19:52:05

我可能是错的,但看起来你正在尝试从工作线程创建一个窗口。不要这样做。 Windows 需要消息泵才能运行,而您的应用程序中只有一个消息泵——它位于主线程中。

I might be wrong, but it seems like you're trying to create a window from a worker thread. Don't do this. Windows need the message pump in order to function, and there's only one message pump in your application -- it's in the main thread.

懒猫 2024-10-11 19:52:05

您应该将您的函数声明和定义为: DWORD WINAPI NotifyWindowThreadFn( void * pParam )

you should declare and define you function as : DWORD WINAPI NotifyWindowThreadFn( void * pParam )

为你拒绝所有暧昧 2024-10-11 19:52:05

尝试使用 _beginthreadex 而不是 CreateThread:

可执行文件中调用的线程
C 运行时库 (CRT) 应该
使用 _beginthreadex 和
_endthreadex 函数用于线程管理而不是 CreateThread
和退出线程;这需要使用
的多线程版本
显像管。如果使用创建的线程
CreateThread调用CRT,CRT
可能会终止该进程
内存不足的情况。

Try using _beginthreadex instead of CreateThread:

A thread in an executable that calls
the C run-time library (CRT) should
use the _beginthreadex and
_endthreadex functions for thread management rather than CreateThread
and ExitThread; this requires the use
of the multi-threaded version of the
CRT. If a thread created using
CreateThread calls the CRT, the CRT
may terminate the process in
low-memory conditions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文