简体   繁体   English

VS2008 中的断言,但 VS2005 中没有

[英]Assertion in VS2008 but not in VS2005

After switching from VS2005 to VS2008 SP1, I found an issue that I can't explain.从 VS2005 切换到 VS2008 SP1 后,我发现了一个我无法解释的问题。
A program works fine under VS2005 in both release and debug mode.一个程序在 VS2005 下在发布和调试模式下都能正常工作。 Under VS2008, when entering the debugger an assert is raised.在 VS2008 下,当进入调试器时,会引发一个断言。
If I let the program run (in debug or release mode), no assertion at all.如果我让程序运行(在调试或发布模式下),则根本没有断言。

I spent almost two days on this and I don't understand what I do wrong.我花了将近两天的时间,我不明白我做错了什么。

Description of the program: I have a MFC dialog based program that creates a user thread (CWinThread) that creates the main dialog of the application.程序描述:我有一个基于 MFC 对话框的程序,它创建了一个用户线程 (CWinThread),该线程创建了应用程序的主对话框。
A worker thread loops infinitely and posts each second a message to the dialog.工作线程无限循环并每秒向对话框发布一条消息。 The message is processed in the gui thread.消息在 gui 线程中处理。

Some parts of my code:我的代码的某些部分:

The InitInstance of the gui thread: gui线程的InitInstance:

BOOL CGraphicalThread::InitInstance()
{
    CGUIThreadDlg* pDlg = new CGUIThreadDlg();
    pDlg->Create(CGUIThreadDlg::IDD);
    m_pMainWnd = pDlg;
    AfxGetApp()->m_pMainWnd = pDlg;
    return TRUE;
}

The worker thread:工作线程:

UINT ThreadProc(LPVOID pVoid)
{
    do
    {
        AfxGetApp()->m_pMainWnd->PostMessage(WM_APP+1, (WPARAM)new CString("Hello"), NULL);
        Sleep(1000);
    }
    while(!bStopThread);

    return 0;
}

The dialog message handler is like this:对话消息处理程序是这样的:

LRESULT CGUIThreadDlg::OnMsg(WPARAM wp, LPARAM lp)
{
    CListBox* pList = (CListBox*)GetDlgItem(IDC_LIST1);
    CString* ps = (CString*)wp;
    pList->InsertString(-1, *ps);
    delete ps;
    return 1L;
}

This works perfectly fine with VS2005.这与 VS2005 完美配合。 But with VS2008, but as soon as a put a breakpoint and enter the debugging mode, I have an assertion raised???但是用VS2008,但是只要下断点并进入调试模式,我就提出了一个断言???
wincore.cpp line 906 wincore.cpp 第 906 行

CObject* p=NULL;
if(pMap)
{
      ASSERT( (p = pMap->LookupPermanent(m_hWnd)) != NULL ||
              (p = pMap->LookupTemporary(m_hWnd)) != NULL);
}
ASSERT((CWnd*)p == this);   // must be us
// Note: if either of the above asserts fire and you are
// writing a multithreaded application, it is likely that
// you have passed a C++ object from one thread to another
// and have used that object in a way that was not intended.
// (only simple inline wrapper functions should be used)
//
// In general, CWnd objects should be passed by HWND from
// one thread to another.  The receiving thread can wrap
// the HWND with a CWnd object by using CWnd::FromHandle.
//
// It is dangerous to pass C++ objects from one thread to
// another, unless the objects are designed to be used in
// such a manner.

If I remove the GUI thread and create the dialog into the CWinApp thread, the problem doesn't occur anymore.如果我删除 GUI 线程并将对话框创建到 CWinApp 线程中,则问题不再发生。

Does anybody have any idea?有人知道吗?
Am I doing something wrong?难道我做错了什么?

Thank you谢谢

// Note: if either of the above asserts fire and you are
// writing a multithreaded application, it is likely that
// you have passed a C++ object from one thread to another
// and have used that object in a way that was not intended.
// (only simple inline wrapper functions should be used)
//
// In general, CWnd objects should be passed by HWND from
// one thread to another.  The receiving thread can wrap
// the HWND with a CWnd object by using CWnd::FromHandle.
//
// It is dangerous to pass C++ objects from one thread to
// another, unless the objects are designed to be used in
// such a manner.

@Ismael: I had already tried that the assert is still fired. @Ismael:我已经尝试过断言仍然被解雇。 The only way I found to remove the assert is to create the dialog into the CWinApp thread.我发现删除断言的唯一方法是在 CWinApp 线程中创建对话框。 But this doesn't explain what happens since there's still the worker thread that post to the dialog every second.但这并不能解释会发生什么,因为仍然有工作线程每秒发布到对话框。 Anyway, thanks.总之感谢。

@daanish.rumani: I've checked the wincore.cpp and the CWnd::AssertValid() is exactly the same (but there's of lot of differences in the rest of the files). @daanish.rumani:我检查了 wincore.cpp 和 CWnd::AssertValid() 完全相同(但文件的 rest 有很多差异)。

I would accept that a piece of code works with VS2005 and not VS2008, but我会接受一段代码适用于 VS2005 而不是 VS2008,但是

  1. I can't see what I do wrong.我看不出我做错了什么。 If I do something wrong, what is the correct way to proceed?如果我做错了什么,正确的方法是什么?
  2. Why the assert is only fired when a breakpoint is hit and I step over the Sleep call?为什么只有在遇到断点并且我跳过 Sleep 调用时才会触发断言? I can run the program fine, even when its compiled in debug mode, as long as I don't enter the debugger.我可以很好地运行程序,即使它在调试模式下编译,只要我不进入调试器。 Could it be a bug in the debugger?这可能是调试器中的错误吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM