c++ Run-Time Check Failure #0 - ESP 的值未正确保存在...检查简单工作线程的点
Posted
技术标签:
【中文标题】c++ Run-Time Check Failure #0 - ESP 的值未正确保存在...检查简单工作线程的点【英文标题】:c++ Run-Time Check Failure #0 - The value of ESP was not properly saved across ... Points to check for simple worker thread 【发布时间】:2014-06-13 16:03:47 【问题描述】:我有一个对话框。在这个对话框 ::OnInitDialog() 我创建了一个线程 AfxBeginThread((AFX_THREADPROC)MyThreadProc, NULL);当我关闭运行时检查失败的对话框时它崩溃,它指向 thrdcore.cpp 文件(Microsoft Foundation Classes C++ 库)
// first -- check for simple worker thread
DWORD nResult = 0;
if (pThread->m_pfnThreadProc != NULL)
nResult = (*pThread->m_pfnThreadProc)(pThread->m_pThreadParams);
ASSERT_VALID(pThread);
我有一个代码可以杀死线程 OnClose 函数,但它不能解决问题。有人可以帮忙吗,我错过了什么?我的代码
HANDLE m_hExit;
DWORD dwResult = 0;
unsigned threadID = 0;
...
OnInitDialog()
...
m_hExit = (HANDLE)AfxBeginThread((AFX_THREADPROC)MyThreadProc, NULL);
OnClose()
dwResult = WaitForSingleObject(m_hExit, 0);
if (dwResult == WAIT_TIMEOUT)
printf("The thread is still running...\n");
else
printf("The thread is no longer running...\n");
Sleep(10000);
dwResult = WaitForSingleObject(m_hExit, 0);
if (dwResult == WAIT_TIMEOUT)
printf("The thread is still running...\n");
else
printf("The thread is no longer running...\n");
CDialog::OnClose();
线程函数很大((((
【问题讨论】:
堆或栈损坏,杀死线程并不能解决问题。您显示的代码很好,我怀疑错误在线程函数中,请粘贴代码。 您对 AFX_THREADPROC 的强制转换表明您的线程函数可能没有所需的签名。它必须具有记录的线程函数返回类型和参数。 我的函数定义 UINT WINAPI MyThreadProc(LPVOID pParam) thrdcore.cpp 中定义 UINT APIENTRY _AfxThreadEntry(void* pParam) 如果我不关闭它,它会在线程函数中崩溃 xx.Format("%c%c%c%c%c%c%c", *(p + 5 )、*(p + 6)、*(p + 7)、*(p + 8)、*(p + 9)、*(p + 10)、*(p + 11)); 【参考方案1】:AfxBeginThread
是 documented,因为要求 threadproc 是
UINT __cdecl MyControllingFunction( LPVOID pParam );
你的评论说你的功能是
UINT WINAPI MyThreadProc( LPVOID pParam )
WINAPI 定义为_stdcall
(见here)
所以你的调用约定不匹配。正如其他人已经评论的那样,演员阵容很可疑。事实上,这是您的代码正在编译的唯一原因。如果您删除强制转换,编译器应该会显示错误。
解决方案是删除强制转换,然后修复函数的调用约定。一旦该代码在没有强制转换的情况下正确编译,它应该可以正常运行而不会损坏堆栈。
【讨论】:
Raymond Chen 的文章详细介绍了这个问题:blogs.msdn.com/b/oldnewthing/archive/2004/01/15/58973.aspx 以及他关于使用强制转换关闭编译器的相关文章:blogs.msdn.com/b/oldnewthing/archive/2009/10/23/9911891.aspx 在我删除函数调用中的强制转换后,您对强制转换是正确的,这导致编译器抱怨。然后我更改了函数定义,它停止抱怨并编译正常。虽然没有解决我的问题。我的应用程序仍然崩溃。在我之前展示的地方。我在这个函数中有一个 while(1) 循环。它在 xx.Format("%c%c%c%c%c%c%c", *(p + 5), *(p + 6), *(p + 7), * (p + 8)、*(p + 9)、*(p + 10)、*(p + 11));这里出了什么问题。如果函数能够多次循环,为什么它会崩溃? @user2001019 我没有足够的信息来告诉你,但既然你说它只发生在循环的 4 次迭代之后,这个问题可能也涉及其他代码。也许某些东西正在将 p 设置为无效值或将其递增,直到它超出缓冲区的末尾。 是的,你是对的,条件失败,因为它是 = Null。并且程序没有检查它并尝试访问它的地址。非常感谢以上是关于c++ Run-Time Check Failure #0 - ESP 的值未正确保存在...检查简单工作线程的点的主要内容,如果未能解决你的问题,请参考以下文章
Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.
Loadrunder脚本篇——Run-time Settings之Preferences
通过 Twitter 对用户进行身份验证时出现 ERROR_WEB_USER_INTERACTION_FAILURE (Firebase - Swift)