0
votes

I've got an first chance exception in ppltasks.h's _ContextCallback that I just don't understand.

My project is a mixed WinRT/native application. The application is made up of multiple sub-projects, one of them uses WinRT. The WinRT code is in a static library running in a different thread from the main thread (and it's not in my power to change that). The WinRT code is copied from a generated Direct3D metro app in Visual Studio 2012 RC.

The code attempts to load one of the simple shaders:

void CubeRenderer::CreateDeviceResources()
{
    Direct3DBase::CreateDeviceResources();

    // going to crash while attempting to load a file.
    auto loadVSTask = DX::ReadDataAsync("SimpleVertexShader.cso");

The file exists, at the correct location, and proven to work.

The code crashes here. _M_context._M_pContextCallback is invalid.

   void _Reset()
    {
        if (_M_context._M_captureMethod != _S_captureDeferred && _M_context._M_pContextCallback != nullptr)
        {
            _M_context._M_pContextCallback->Release();
        }
    }

Output window gives: First-chance exception at 0x00E34C89 in MyApplication.exe: 0xC0000005: Access violation reading location 0xCDCDCDCD.

Stack trace looks like:

MyApplication.exe!Concurrency::details::_ContextCallback::_Reset() Line 620 C++ MyApplication.exe!Concurrency::details::_ContextCallback::operator=(const Concurrency::details::_ContextCallback & _Src) Line 563 C++ MyApplication.exe!Concurrency::task_continuation_context::operator=(const Concurrency::task_continuation_context & __that) C++ MyApplication.exe!Concurrency::task::_ContinuationTaskHandle,std::integral_constant,Concurrency::details::_TypeSelectorAsyncOperation>::_ContinuationTaskHandle,std::integral_constant,Concurrency::details::_TypeSelectorAsyncOperation>(const std::shared_ptr > & _AncestorImpl, const std::shared_ptr > & ContinuationImpl, const DX::ReadDataAsync::_l3:: & _Func, const Concurrency::task_continuation_context & _Context, Concurrency::details::_TaskInliningMode _InliningMode) Line 3292 C++ MyApplication.exe!Concurrency::task::ThenImpl >(const DX::ReadDataAsync::_l3:: & _Func, Concurrency::details::_CancellationTokenState * _PTokenState, const Concurrency::task_continuation_context & _ContinuationContext, bool _Aggregating, Concurrency::details::_TaskInliningMode InliningMode) Line 3584 C++ MyApplication.exe!Concurrency::task::then< >(const DX::ReadDataAsync::_l3:: & _Func) Line 2882 C++ MyApplication.exe!DX::ReadDataAsync(Platform::String ^ filename) Line 42 C++ MyApplication.exe!CubeRenderer::[Direct3DBase]::CreateDeviceResources() Line 30 C++

So there's something wrong with the _ContextCallback, and that's where I get stuck.

  • What is this context callback? It seems to have something to do with passing from a task to another.
  • If it's invalid, how could that have happened?
  • If it's simply just not setup properly, how to I properly set it up?

I can get it to work, but it involves changing all the sub-projects in the application to use WinRT. Unfortunately this is not considered an acceptable solution as the code in those other sub-projects are also outside of my control. I also would like to try to understand what's actually going on here.

Any insights or ideas? Thanks!

2

2 Answers

0
votes

I've added a reference to ppltasks.h in my main cpp file. It makes the problem go away, but I have no idea why.

-1
votes

On my setup, if you include header in two projects, one which is winrt and one normal, you get a detect mismatch called: "_PPLTASKS_WITH_WINRT" which I'm guessing newer versions of the headers or tools show instead of a horrible runtime crash you were getting.

It seems from this that you can't mix static libraries which use ppl (or the vs2012 async libraries which use PPL under the hood) if you've got winrt enabled for some and not others.

I can't find any official documentation for this. I've fixed the same issue in my app by only using ppl/std::async in libraries with winrt switched off. I assume this wont be a good long term solution though. Note just including the header and friends is enough to hit this issue.