I am learning C++ and Direct3D11/Direct2D (on top of UWP) for fun, but am struggling getting my little test program to run. It throws an access violation (see below for exact exception) when I call CreateSwapChainForCoreWindow.
I used the D3D Device for other calls and they worked so I don't think that is the issue. The swap chain description is relatively straight-forward and the swap chain itself will be set in the call. So, I assume that the exception is because I am passing an incorrect pointer to the window but I can't solve it.
Exception:
Exception thrown at 0x00007FF8FE44F4E0 (Windows.UI.dll) in UWP D2D example v3.exe: 0xC0000005: Access violation executing location 0x00007FF8FE44F4E0.
Code snippet (https://github.com/cwebb95/Direct2D_cppwinrt):
ComPtr<IDXGISwapChain1> swapChain = nullptr;
DX::ThrowIfFailed(dxgiFactory->CreateSwapChainForCoreWindow(m_d3dDevice.Get(),
reinterpret_cast<IUnknown*>(&CoreWindow::GetForCurrentThread()),
&swapChainDescription,
NULL,
&swapChain));
I was able to solve my problem by changing the second parameter to:
static_cast<::IUnknown*>(winrt::get_abi(CoreWindow::GetForCurrentThread()))
from:
reinterpret_cast<IUnknown*>(&CoreWindow::GetForCurrentThread())
I am not knowledge enough yet to know why that fixed the problem, but I will research and hopefully figure it out (any leads on that question would be much appreciated).
I have read this blogpost http://www.ics.com/blog/qt-tips-and-tricks-part-1 and tried to enable plugin debugging as described.
I've put this line in my main.cpp:
qputenv(QT_DEBUG_PLUGINS, 1);
But if I try to compile I'm getting this error:
.../src/main.cpp:14: error: 'QT_DEBUG_PLUGINS' was not declared in this scope
qputenv(QT_DEBUG_PLUGINS, -1);
What is the problem here and how do I have to do it right?
qputenv("QT_DEBUG_PLUGINS", QByteArray("1"));
But I don't get any additional output.
I'm using Qt5.5.1 with QtCreator 3.6 under KUbuntu 15.10.
You're supposed to set env variable from outside your program, not from inside! It's very likely the plugin loading you're interested into already happened by the time you reach that line. Try putting it before creating a Q*Application object.
– peppe
That's it. It was definitely set before plugin loading, but it seems to be important to set it before creating Q*Application as you wrote. Thank you.
– avb
auto task = create_task(Windows::Storage::KnownFolders::PicturesLibrary->GetFilesAsync(Windows::Storage::Search::CommonFileQuery::OrderBySearchRank));
task.then([&sstrpath](Windows::Foundation::Collections::IVectorView<Windows::Storage::StorageFile^>^ files)
{
CCLog("num of files detected %d",files->Size);
Platform::String^ pathstr = files->GetAt(0)->Path;
OutputDebugStringW(pathstr->Data());
auto task2 = create_task(files->GetAt(0)->OpenAsync(Windows::Storage::FileAccessMode::Read));
task2.then([](Windows::Storage::Streams::IRandomAccessStream^ filestream)
{
Windows::UI::Xaml::Media::Imaging::BitmapImage^ bmp = ref new Windows::UI::Xaml::Media::Imaging::BitmapImage();
bmp->SetSource(filestream);
}
);
}
);
This was done on a Win8 RTM with a VS express RTM in C++ (cocos2dx framework). I am trying to load an image from the Picture library and create a BitmapImage out of it. Next was to somehow use the BitmapImage for CCSprite in cococs2dx, but that's not the issue here. The program was able to run all the way into task2 but then crash at when I try to ref new the BitmmapImage. The following was in the output console
First-chance exception at 0x75004B32 in myGame.exe: Microsoft C++ exception:
Platform::WrongThreadException ^ at memory location 0x02D1D794. HRESULT:0x8001010E
First-chance exception at 0x75004B32 in myGame.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000.
First-chance exception at 0x75004B32 in myGame.exe: Microsoft C++ exception:
Platform::WrongThreadException ^ at memory location 0x02D1E5F0. HRESULT:0x8001010E
Unhandled exception at 0x622C9AD1 (msvcr110d.dll) in PixBlitz.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.
I am not really sure what I have done wrong as most tutorials out there are Javascript or XAML based for Win8 app development.
Creating tasks like that moves code onto different threads. You're getting Platform::WrongThreadException when you access an object from the wrong thread. You have to access GUI components from the same thread every time.
I believe if you RunAsync onto the Dispatcher, that will get the threading right. Pass a delegate to RunAsync, and have that delegate include creating the BitmapImage, and whatever else you want to do with the BitmapImage.
As requested, an example.
I'm not familiar with Win8 development, though I am familiar with the WPF that it's based on. (If C++/CLI supports lambdas now, I'll have to go back and revise some old answers on the subject.)
I believe this is what you want. I may have some of the syntax slightly off on that delegate.
Stream^ filesteam = files->GetAt(0)->Open(FileAccessMode::Read); // we're already on a background thread, no need for a Task if we're not going to call 'then'.
// I'm assuming 'this' is a subclass of Windows.UI.Xaml.Window, or something similar.
this->Dispatcher->RunAsync(CoreDispatcherPriority::Low, []()
{
BitmapImage^ bmp = ref new BitmapImage();
bmp->SetSource(filestream);
}
);
In Visual C++ 2008, I want to "catch" an exception generated as shown here:
try {
int foo = 20;
::fgetpos(0, (fpos_t*)&foo);
}
//...
Here are adjustments I've made to attempt a successful catch:
SEH is activated (/eha)
I've added a catch(...)
I've added a _set_se_translator vector.
I've added/adjusted to SEH syntax: __try / __except(EXCEPTION_EXECUTE_HANDLER)
In short, I've tried "everything in the book" and I still can't catch the exception. If I replace the call to ::fgetpos with int hey = foo / 0 then suddenly all of the above techniques work as expected. So the exception I'm dealing with from ::fgetpos is somehow "extra special."
Can someone explain why this ::fgetpos error seems uncatchable, and how to work around it?
update When executed in the VS IDE, the output window doesn't name an exception. All it says is this:
Microsoft Visual Studio C Runtime Library has detected a fatal error in MyProgram.exe.
Not very helpful. When I run the console app from the command line, I get a crash dialogue. The "problem details" section of the dialogue includes this information:
Problem Event Name: BEX
Exception Offset:0002fd30
Exception Code: c0000417
Exception Data: 00000000
Additional Information 1:69ad
Additional Information 2:69addfb19767b2221c8e3e7a5cd2f4ae
Additional Information 3:b1ff
Additional Information 4:b1ffca30cadddc78c19f19b6d150997f
Since the code in your dump corresponds to STATUS_INVALID_CRUNTIME_PARAMETER, try _set_invalid_parameter_handler
Most likely, the runtime catches it for you and issues a debug dialog without returning or propagating the exception- that is a CRT call and they may add whatever exception catching code in there they like. It's well within Visual Studio's rights to catch a hardware exception inside a library function, especially if you are running from within the IDE or in debug mode, then it is expected of the runtime.
Of course, when you divide by zero, then there is no library call here to write that extra catching code.
I've figured out what caused the problem but I still don't know why - it happened when I started using fmod, and it must have something to do with how the linker decides to bring in and execute static libraries and .dll's. My code under test is a static lib; it refers to fmodex_vc, another static lib, which at some point (though I know not when) decides to load in its fmodex.dll. (Which is in the same directory as everything else, so I don't know why it wouldn't find it.) As far as I know, the code under test absolutely does not call the fmod initialization functions, but maybe fmod has some static global initializers that initialize themselves and load in the dll? And that code only gets pulled in if code in a module that uses it gets...used?
I'm testing unmanaged C++ code using the Visual Studio test framework and when I started using fmod it stopped working: Every test, even "test" tests that do nothing, would report (wrapped for readability):
Unable to get type SlidersTest.UnitTest1, SlidersTest.
Error: System.IO.FileNotFoundException:
The specified module could not be found.
(Exception from HRESULT: 0x8007007E)
After a lot of trial and error, excluding .cpp files and re-adding them, I discovered that only one of the test files elicits the problem; and it only does if this line is called:
EntityMgr::Init();
Interestingly, all the tests start failing with that message if that line is in the code. EntityMgr::Init() is a function that does very little:
EntityMgr* EntityMgr::instG = null;
and
void EntityMgr::Init()
{
instG = new EntityMgr;
}
and
class EntityMgr
{
private:
static EntityMgr* instG;
public:
EntityMgr() // does nothing beyond the default
{
}
static void Init();
static EntityMgr* Inst() { return instG; }
...
vector<Entity> entitiesG;
};
Entity, FWIW, is a pretty vanilla class with no pointers, just various floats for its fields.
No matter how I run the tests (from test view, run selected, run all, run from the command line, from the test menu) I get the error.
Attempting to step into the test with the debugger fails - the test fails before the debugger gets to step in. Setting the debugger to break on System exceptions did nothing as well.
The code under test is a static .lib. CLR support is /clr.
Oh, and this just in: if I call a static Entity member function, same deal. If I move said static function outside of the class, same deal. But, if I move that function to another module, it's fine.
If I set the debugger to break on any exception, I do get something interesting:
First-chance exception at 0x7c812aeb in vstesthost.exe: Microsoft C++ exception: HRException at memory location 0x05129890..
There's no source code at that location, of course. Here's the call stack:
kernel32.dll!7c812aeb()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
kernel32.dll!7c812aeb()
[External Code]
msvcr80.dll!78158ed7()
msvcr80.dll!78158e34()
msvcr80.dll!78158047()
msvcr80.dll!7815850e()
msvcr80.dll!78158872()
msvcr80.dll!78158a57()
msvcr80.dll!78158b11()
ntdll.dll!7c9032a8()
ntdll.dll!7c90327a()
ntdll.dll!7c92a9ef()
ntdll.dll!7c90e46a()
kernel32.dll!7c812aeb()
kernel32.dll!7c812aeb()
kernel32.dll!7c812aeb()
msvcr80.dll!78139c4d()
msvcr80.dll!781323ff()
msctf.dll!74755764()
msctf.dll!74721557()
ws2_32.dll!71ab12bb()
ntdll.dll!7c90118a()
ntdll.dll!7c91b084()
ntdll.dll!7c90de7c()
ntdll.dll!7c90d04c()
ntdll.dll!7c90e43f()
kernel32.dll!7c80b713()
And here's the stack trace that mstest reports - I don't get anything useful out of it.
Unable to get type SlidersTest.game_EntityMgr_test, SlidersTest. Error: System.IO.FileNotFoundException: The specified module could not be found. (Exception from HRESULT: 0x8007007E)
at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
at System.Reflection.Assembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, StackCrawlMark& stackMark)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
at Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestExecuter.GetType(UnitTestElement unitTest, String type)
at Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestExecuter.ResolveMethods().
Why is fmod doing this?
I suggest running your application under Dependency Walker's Profile mode (http://www.dependencywalker.com/). It can record all attempts to load DLLs and EXEs, along with the resulting error codes - it sounds likely that the File not Found error is coming from an indirect dependency - perhaps being pulled in from linking FMod.
If this is the case, profiling your application with Dependency Walker will show one or more failed attempts to load a library. One of them will be the one responsible for the error.
Maybe some property was modified for that file? Probably already looked at this, but make sure that all the settings are from "Inherit from parent" in Visual Studio.
Jay
My best guess, from what you've posted so-far is that the exception is being thrown somewhere inside the CLR type loader — it looks like an assembly that you're indirectly dependent on either isn't in the GAC, or isn't being copied to the test directory.
Is there an actual stack trace in the test results? That might help narrow down what type(s) its trying to load.
Since you say that this started happening all of a sudden, I assume that tests with this line of code were working just fine previously. This may be a radical choice, but in the absence of another solution, perhaps you would consider reinstalling visual studio (a long procedure to be sure)
Can you set Visual Studio to break on all exceptions, regardless of where they come from during debugging?
It sounds as if cosmic rays or a faulty hard drive have caused a test .dll to become corrupt, or the dll you're building is corrupt (consistently). Before re-installing all of Visual Studio, you may want to ask it to do a repair, which should check for inconsistencies between your current install and what's on your installation medium.
How is the FMod .dll getting into your test directory? Do you have it set up to copy it to wherever mstest wants the test to occur? Note that "Copy to Output Directory" doesn't actually accomplish this. There's some other method, though I can't remember quite what it is.
I'd run it in a debugger and check the run output - in particular the "loading path\fmodex.dll" line to see if it's loading the right dll.
I've seen similar errors when mixing dlls from different configurations.