简体   繁体   English

释放模式错误,但不在调试模式下

[英]release mode error, but not in debug mode

My code runs fine in debug mode but fails in release mode. 我的代码在调试模式下运行良好,但在发布模式下运行失败。

Here's a snippet of my code where it fails: 这是我的代码片段在失败的地方:

LOADER->AllocBundle(&m_InitialContent);
while(!m_InitialContent.isReady())
{
    this->LoadingScreen();
}

AllocBundle() will load the content contained in m_InitialContent and set it's ready status to true when it is done. AllocBundle()将加载m_InitialContent中包含的内容,并在完成后将其就绪状态设置为true。 This is implemented using multithreading. 这是使用多线程实现的。

this->LoadingScreen() should render a loading screen, however at the moment that is not implemented yet so the function has an empty body. this->LoadingScreen()应该呈现一个加载屏幕,但是目前尚未实现,因此该函数的主体为空。

Apparently this might be the cause of the error: If I give the function LoadingScreen() one line of code: std::cout<<"Loading"<<std::endl; 显然这可能是导致错误的原因:如果我给函数LoadingScreen()一行代码: std::cout<<"Loading"<<std::endl; then it will run fine. 那么它将运行正常。

If I don't, then the code gets stuck at while(!m_InitialContent.isReady()) It never even jumps to the code between the brackets ( this->LoadingScreen(); ). 如果我不这样做,则代码将停留在while(!m_InitialContent.isReady())它甚至不会跳转到括号之间的代码( this->LoadingScreen(); )。 And apparently neither does it update the expression in the while statement because it stays stuck there forever. 而且显然它也不会更新while语句中的表达式,因为它永远都停留在那里。

Does anyone have any ideas what might be causing this? 有谁知道这可能是什么原因? And if so, what might the problem be? 如果是这样,可能是什么问题? I'm completely puzzled. 我完全不解。


EDIT: Additional code on request 编辑:根据要求的其他代码

member of ContentLoader: details::ContentBundleAllocator m_CBA; ContentLoader的成员: details::ContentBundleAllocator m_CBA;

    void ContentLoader::AllocBundle(ContentBundle* pBundle)
    {
        ASSERT(!(m_CBA.isRunning()), "ContentBundleAllocator is still busy");
        m_CBA.Alloc(pBundle, m_SystemInfo.dwNumberOfProcessors);
    }

void details::ContentBundleAllocator::Alloc(ContentBundle* pCB, UINT numThreads)
{
    m_bIsRunning = true;
    m_pCB = pCB;
    pCB->m_bIsReady = false;


    m_NumRunningThrds = numThreads;
    std::pair<UINT,HANDLE> p;
    for (UINT i = 0; i < numThreads; ++i)
    {
        p.second = (HANDLE)_beginthreadex(NULL,
                                          NULL,
                                          &details::ContentBundleAllocator::AllocBundle,
                                          this,
                                          NULL,&p.first);
        SetThreadPriority(p.second,THREAD_PRIORITY_HIGHEST);
        m_Threads.Insert(p);
    }
}

unsigned int __stdcall details::ContentBundleAllocator::AllocBundle(void* param)
{
//PREPARE
    ContentBundleAllocator* pCBA = (ContentBundleAllocator*)param;

//LOAD STUFF [collapsed for visibility+]

   //EXIT===========================================================================================================
        pCBA->m_NumRunningThrds -= 1;
        if (pCBA->m_NumRunningThrds == 0)
        {
            pCBA->m_bIsRunning = false;
            pCBA->m_pCB->m_bIsReady = true;
            pCBA->Clear();
    #ifdef DEBUG
            std::tcout << std::endl;
    #endif
            std::tcout<<_T("exiting allocation...")<<std::endl;
        }

    std::tcout<<_T("exiting thread...")<<std::endl;
    return 0;
}

bool isReady() const {return m_bIsReady;}

When you compile your code in Debug mode, the compiler does a lot of stuff behind the scenes that prevents many mistakes made by the programmer from crashing the application. 在“调试”模式下编译代码时,编译器会在后台进行很多操作,以防止程序员犯下的许多错误导致应用程序崩溃。 When you run in Release, all bets are off. 当您在Release中运行时,所有投注均关闭。 If your code is not correct, you're much more likely to crash in Release than in Debug. 如果您的代码不正确,则在Release中崩溃的可能性要比在Debug中崩溃的可能性大。

A few things to check: 需要检查的几件事:

  1. Make sure all variables are properly intialized 确保正确设置了所有变量
  2. Make sure you do not have any deadlocks or race conditions 确保您没有任何僵局或竞赛条件
  3. Make sure you aren't passing around pointers to local objects that have been deallocated 确保您没有传递指向已释放的本地对象的指针
  4. Make sure your strings are properly NULL-terminated 确保您的字符串正确以NULL结尾
  5. Don't catch exceptions that you're not expecting and then continue running as if nothing had happened. 不要catch您没有想到的异常,然后继续运行,就好像什么都没发生一样。

You are accessing the variable m_bIsReady from different threads without memory barriers. 您正在从没有内存障碍的其他线程访问变量m_bIsReady This is wrong, as it may be cached by either optimizer or processor cache. 这是错误的,因为它可能被优化器或处理器缓存所缓存。 You have to protect this variable from simultaneous access with a CriticalSection, or mutex, or whatever synchronization primitive is available in your library. 您必须使用CriticalSection,互斥量或库中可用的任何同步原语来保护此变量,以防止同时访问该变量。

Note that there might be further mistakes, but this one is definitely a mistake, too. 请注意,可能还会有其他错误,但这绝对也是一个错误。 As a rule of thumb: each variable which is accessed from different threads has to be protected with a mutex/critical section/whatever. 根据经验:从不同线程访问的每个变量都必须使用互斥/关键部分/任何内容进行保护。

快速m_NumRunningThrds似乎并不能防止同时访问,因此if (pCBA->m_NumRunningThrds == 0)可能永远无法满足。

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

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