I am trying to use Azure storage sdk C++ library with Unreal Engine 4 to upload images to the Azure cloud. Library is built with vcpkg and dlls are linked dynamically. Here is a simplified example of the code I use.
THIRD_PARTY_INCLUDES_START
#pragma warning(disable:4668)
#pragma warning(disable:4005) // 'TEXT': macro redefinition
#include <was/storage_account.h>
#include <was/blob.h>
#include <cpprest/filestream.h>
#include <cpprest/containerstream.h>
THIRD_PARTY_INCLUDES_END
const utility::string_t storage_connection_string(U("DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=MyAccountKey;EndpointSuffix=core.windows.net"));
void AAwsTest2GameModeBase::StartPlay() {
try
{
// Retrieve storage account from connection string.
azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
// Create the blob client.
azure::storage::cloud_blob_client blob_client = storage_account.create_cloud_blob_client();
// Retrieve a reference to a container.
azure::storage::cloud_blob_container container = blob_client.get_container_reference(U("image-container"));
azure::storage::cloud_block_blob blockBlob = container.get_block_blob_reference(U("28bbcdb0b3e5417b207572e292ae98412cd9d931eae6266f7c4fd788ad8544a20.jpg"));
concurrency::streams::istream input_stream = concurrency::streams::file_stream<uint8_t>::open_istream(U("image.jpg")).get();
blockBlob.upload_from_stream(input_stream);
input_stream.close().wait();
}
catch (const std::exception& e)
{
std::wcout << U("Error: ") << e.what() << std::endl;
}
}
Build.cs content
public class Program : ModuleRules
{
public Program(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
//I tried to use ansi allocator but it did not help
//PublicDefinitions.Add("FORCE_ANSI_ALLOCATOR");
PublicIncludePaths.Add(Path.Combine(DependencyFolderWin, "include"));
PublicAdditionalLibraries.Add(Path.Combine(DependencyFolderWin, "lib", "wastorage.lib"));
PublicAdditionalLibraries.Add(Path.Combine(DependencyFolderWin, "lib", "cpprest_2_10.lib"));
PublicAdditionalLibraries.Add(Path.Combine(DependencyFolderWin, "lib", "brotlicommon.lib"));
PublicAdditionalLibraries.Add(Path.Combine(DependencyFolderWin, "lib", "brotlidec.lib"));
PublicAdditionalLibraries.Add(Path.Combine(DependencyFolderWin, "lib", "brotlienc.lib"));
PublicAdditionalLibraries.Add(Path.Combine(DependencyFolderWin, "lib", "zlib.lib"));
}
private string DependencyFolderWin
{
get
{
string moduleDir = Path.GetFullPath(ModuleDirectory);
return Path.Combine(moduleDir, "./../../deps");
}
}
}
The problem is that it successfully uploads image and crashes right after return from this function (in this case StartPlay() or Upload() as in the callstack) with this callstack:
UE4Editor-Core.dll!00007ff9e620ff1b() Unknown
UE4Editor-Core.dll!00007ff9e62109e3() Unknown
UE4Editor-Core.dll!00007ff9e6211592() Unknown
UE4Editor-Core.dll!00007ff9e5e95277() Unknown
[Inline Frame] UE4Editor-MsgQueuePlugin.dll!operator delete(void *) Line 31 C++
[Inline Frame] UE4Editor-MsgQueuePlugin.dll!std::_Deallocate(void * _Ptr, unsigned __int64 _Bytes) Line 207 C++
[Inline Frame] UE4Editor-MsgQueuePlugin.dll!std::allocator<wchar_t>::deallocate(wchar_t * const) Line 992 C++
UE4Editor-MsgQueuePlugin.dll!std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >::_Tidy_deallocate() Line 3992 C++
[Inline Frame] UE4Editor-MsgQueuePlugin.dll!std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >::{dtor}() Line 2460 C++
UE4Editor-MsgQueuePlugin.dll!web::uri::~uri() C++
UE4Editor-MsgQueuePlugin.dll!azure::storage::cloud_blob::~cloud_blob() C++
UE4Editor-MsgQueuePlugin.dll!AzureUploader::Upload(TArray<unsigned char,FDefaultAllocator> file, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & path, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & fileName) Line 37 C++
Callstack with Editor debug symbols:
[Inline Frame] UE4Editor-Core.dll!__TBB_machine_cmpswp1(volatile void *) Line 69 C++
[Inline Frame] UE4Editor-Core.dll!__TBB_TryLockByte(unsigned char &) Line 917 C++
UE4Editor-Core.dll!__TBB_LockByte(unsigned char & flag) Line 924 C++
[Inline Frame] UE4Editor-Core.dll!MallocMutex::scoped_lock::{ctor}(MallocMutex &) Line 66 C++
UE4Editor-Core.dll!rml::internal::Block::freePublicObject(rml::internal::FreeObject * objectToFree) Line 1382 C++
[Inline Frame] UE4Editor-Core.dll!rml::internal::internalPoolFree(rml::internal::MemoryPool * memPool, void *) Line 2571 C++
UE4Editor-Core.dll!rml::internal::internalFree(void * object) Line 2595 C++
UE4Editor-Core.dll!FMemory::Free(void * Original) Line 76 C++
[External Code]
UE4Editor-MsgQueuePlugin.dll!AzureUploader::Upload(TArray<unsigned char,FDefaultAllocator> file, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & path, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & fileName) Line 37 C++
Looks like it crashes while deleting uri from some structure. Probably, the problem is with unreal memory management. I tried to use ansi allocator but it did not help. Any ideas how to make it work properly?
Thank you
Finally, it was solved by using UE4 plugin from this example. It is not the solution I wanted but at least it works. There are statically linked libraries and hardcoded compiler version which may bring problems in the future.
Related
Hello stackoverflow community,
first time asking.
I'm working on a prototype for modeling CAD data in VR with the Unreal Engine.
I have managed to get my Unreal project to build with my CAD System Siemens NX, or rather the API NXOpen.
Overall the API works and I can call NXOpen functions and can create basic objects
But some operations cause crashes and my guess is that it has something to do with memory management.
I cant wrap my head around what exactly is happening.
For example I have code that creates a NX block feature that works fine.
Afterwards I'll need a body object that is stored inside the block feature. The access also works, but when 'bodies' runs out of scope, it crashes.
Similar crashes happen when accessing all kinds of data within NX features. This dummy code triggers the crash quite often:
// 'block' gets created here
if (block) {
std::vector<NXOpen::Body*> bodies = block->GetBodies();
if (bodies.size() > 0) {
NXOpen::Body* body = bodies.front();
}
} // <-- this line crashes
Exception thrown: read access violation.
**flag** was 0xFFFFFFFFFFFFFFFF. occurred
[Inline Frame] UE4Editor-Core.dll!__TBB_machine_cmpswp1(volatile void *) Line 69 C++
> [Inline Frame] UE4Editor-Core.dll!__TBB_TryLockByte(unsigned char &) Line 917 C++
UE4Editor-Core.dll!__TBB_LockByte(unsigned char & flag) Line 924 C++
[Inline Frame] UE4Editor-Core.dll!MallocMutex::scoped_lock::{ctor}(MallocMutex &) Line 66 C++
UE4Editor-Core.dll!rml::internal::Block::freePublicObject(rml::internal::FreeObject * objectToFree) Line 1382 C++
[Inline Frame] UE4Editor-Core.dll!rml::internal::internalPoolFree(rml::internal::MemoryPool * memPool, void *) Line 2571 C++
UE4Editor-Core.dll!rml::internal::internalFree(void * object) Line 2595 C++
UE4Editor-Core.dll!FMemory::Free(void * Original) Line 76 C++
UE4Editor-GestEnUE-Win64-DebugGame.dll!operator delete(void * Ptr, unsigned __int64 Size) Line 6 C++
[External Code]
UE4Editor-GestEnUE-Win64-DebugGame.dll!UNXConnection::AddPointSetsToBody(const FString & name) Line 268 C++
UE4Editor-GestEnUE-Win64-DebugGame.dll!ANXPart::AddCylinder(FVector pos, FVector axis, float height, float diameter, bool WorldSpace) Line 103 C++
UE4Editor-GestEnUE-Win64-DebugGame.dll!ANXPart::execAddCylinder(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 18 C++
UE4Editor-CoreUObject.dll!UFunction::Invoke(UObject * Obj, FFrame & Stack, void * const Z_Param__Result) Line 4643 C++
UE4Editor-CoreUObject.dll!UObject::CallFunction(FFrame & Stack, void * const Z_Param__Result, UFunction * Function) Line 904 C++
[Inline Frame] UE4Editor-CoreUObject.dll!FFrame::Step(UObject *) Line 319 C++
UE4Editor-CoreUObject.dll!UObject::ProcessContextOpcode(FFrame & Stack, void * const Z_Param__Result, bool bCanFailSilently) Line 2314 C++
[Inline Frame] UE4Editor-CoreUObject.dll!FFrame::Step(UObject *) Line 319 C++
UE4Editor-CoreUObject.dll!UObject::execLetObj(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 2136 C++
[Inline Frame] UE4Editor-CoreUObject.dll!FFrame::Step(UObject *) Line 319 C++
UE4Editor-CoreUObject.dll!ProcessLocalScriptFunction(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 974 C++
UE4Editor-CoreUObject.dll!ProcessScriptFunction<void (__cdecl*)(UObject *,FFrame &,void *)>(UObject * Context, UFunction * Function, FFrame & Stack, void * const Z_Param__Result, void(*)(UObject *, FFrame &, void *) ExecFtor) Line 809 C++
UE4Editor-CoreUObject.dll!ProcessLocalFunction(UObject * Context, UFunction * Fn, FFrame & Stack, void * const Z_Param__Result) Line 1033 C++
[Inline Frame] UE4Editor-CoreUObject.dll!FFrame::Step(UObject *) Line 319 C++
UE4Editor-CoreUObject.dll!ProcessLocalScriptFunction(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 974 C++
UE4Editor-CoreUObject.dll!ProcessScriptFunction<void (__cdecl*)(UObject *,FFrame &,void *)>(UObject * Context, UFunction * Function, FFrame & Stack, void * const Z_Param__Result, void(*)(UObject *, FFrame &, void *) ExecFtor) Line 809 C++
UE4Editor-CoreUObject.dll!ProcessLocalFunction(UObject * Context, UFunction * Fn, FFrame & Stack, void * const Z_Param__Result) Line 1033 C++
[Inline Frame] UE4Editor-CoreUObject.dll!FFrame::Step(UObject *) Line 319 C++
UE4Editor-CoreUObject.dll!UObject::ProcessContextOpcode(FFrame & Stack, void * const Z_Param__Result, bool bCanFailSilently) Line 2314 C++
[Inline Frame] UE4Editor-CoreUObject.dll!FFrame::Step(UObject *) Line 319 C++
UE4Editor-CoreUObject.dll!ProcessLocalScriptFunction(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 974 C++
UE4Editor-CoreUObject.dll!ProcessScriptFunction<void (__cdecl*)(UObject *,FFrame &,void *)>(UObject * Context, UFunction * Function, FFrame & Stack, void * const Z_Param__Result, void(*)(UObject *, FFrame &, void *) ExecFtor) Line 809 C++
UE4Editor-CoreUObject.dll!ProcessLocalFunction(UObject * Context, UFunction * Fn, FFrame & Stack, void * const Z_Param__Result) Line 1033 C++
[Inline Frame] UE4Editor-CoreUObject.dll!FFrame::Step(UObject *) Line 319 C++
UE4Editor-CoreUObject.dll!ProcessLocalScriptFunction(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 974 C++
UE4Editor-CoreUObject.dll!UObject::ProcessInternal(UObject * Context, FFrame & Stack, void * const Z_Param__Result) Line 1058 C++
UE4Editor-CoreUObject.dll!UFunction::Invoke(UObject * Obj, FFrame & Stack, void * const Z_Param__Result) Line 4643 C++
UE4Editor-CoreUObject.dll!UObject::ProcessEvent(UFunction * Function, void * Parms) Line 1464 C++
UE4Editor-Engine.dll!AActor::ProcessEvent(UFunction * Function, void * Parameters) Line 769 C++
UE4Editor-GestEnUE-Win64-DebugGame.dll!ABuilderBase::commit() Line 37 C++
UE4Editor-GestEnUE-Win64-DebugGame.dll!AGestEnLeapPawn::Tick(float DeltaTime) Line 138 C++
UE4Editor-Engine.dll!AActor::TickActor(float DeltaSeconds, ELevelTick TickType, FActorTickFunction & ThisTickFunction) Line 970 C++
UE4Editor-Engine.dll!FActorTickFunction::ExecuteTick(float DeltaTime, ELevelTick TickType, ENamedThreads::Type CurrentThread, const TRefCountPtr<FGraphEvent> & MyCompletionGraphEvent) Line 164 C++
[Inline Frame] UE4Editor-Engine.dll!FTickFunctionTask::DoTask(ENamedThreads::Type) Line 285 C++
UE4Editor-Engine.dll!TGraphTask<FTickFunctionTask>::ExecuteTask(TArray<FBaseGraphTask *,FDefaultAllocator> & NewTasks, ENamedThreads::Type CurrentThread) Line 842 C++
[Inline Frame] UE4Editor-Core.dll!FBaseGraphTask::Execute(TArray<FBaseGraphTask *,FDefaultAllocator> & CurrentThread, ENamedThreads::Type) Line 511 C++
UE4Editor-Core.dll!FNamedTaskThread::ProcessTasksNamedThread(int QueueIndex, bool bAllowStall) Line 686 C++
UE4Editor-Core.dll!FNamedTaskThread::ProcessTasksUntilQuit(int QueueIndex) Line 582 C++
[Inline Frame] UE4Editor-Core.dll!FTaskGraphImplementation::ProcessThreadUntilRequestReturn(ENamedThreads::Type) Line 1406 C++
UE4Editor-Core.dll!FTaskGraphImplementation::WaitUntilTasksComplete(const TArray<TRefCountPtr<FGraphEvent>,TInlineAllocator<4,FDefaultAllocator> > & Tasks, ENamedThreads::Type CurrentThreadIfKnown) Line 1457 C++
UE4Editor-Engine.dll!FTickTaskSequencer::ReleaseTickGroup(ETickingGroup WorldTickGroup, bool bBlockTillComplete) Line 557 C++
UE4Editor-Engine.dll!FTickTaskManager::RunTickGroup(ETickingGroup Group, bool bBlockTillComplete) Line 1505 C++
UE4Editor-Engine.dll!UWorld::RunTickGroup(ETickingGroup Group, bool bBlockTillComplete) Line 789 C++
UE4Editor-Engine.dll!UWorld::Tick(ELevelTick TickType, float DeltaSeconds) Line 1568 C++
UE4Editor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1618 C++
UE4Editor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 403 C++
UE4Editor-Win64-DebugGame.exe!FEngineLoop::Tick() Line 3967 C++
[Inline Frame] UE4Editor-Win64-DebugGame.exe!EngineTick() Line 62 C++
UE4Editor-Win64-DebugGame.exe!GuardedMain(const wchar_t * CmdLine, HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, int nCmdShow) Line 168 C++
UE4Editor-Win64-DebugGame.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) Line 261 C++
If I understand the callstack correctly the error occurs when the object is deleted. But why can that be the problem?
Could it be that both Unreal and the NX third party lib try to manage the memory?
Has anyone an idea what could cause these crashed and even an idea how to solve it?
I'm happy to give more information if necessary.
Greetings,
LaRanaRica
I found that using the debug runtime library often can cause memory errors when using NXOpen.
You can change this with the linker setting /MD (indstead of /MDd).
I know this is late, but I have a much better solution than to build in Release mode instead of Debug mode, because I've had this issue many times before and solved it using the same simple solution.
I don't know exactly why this occurs with NX Open C++, but it only happens when using std::vector (which some NX Open C++ APIs return) and Debug mode, together. You can fix it by adding this line to the top of your C++ source file, before all the #includes:
#define _ITERATOR_DEBUG_LEVEL 0
The complete code is more than 400 line. You can find it here: http://hostcode.sourceforge.net/view/4122 or if you have wxwidgets installed then under WX_WIDGETS_ROOT\samples\wizard\wizard.cpp.
I tried to compile it but get
"error C2065: 'm_bitmap' : undeclared identifier" on line 122.
Then I commented that line and it compiles ok. But when I run it and select one of these menu commands:
File >> Run wizard modal
File >> Run wizard withour sizer
File >>
Run wizard modeless
it goes to MyWizard constructor and crashes on m_page1 = new... line.
MyWizard::MyWizard(wxFrame *frame, bool useSizer)
: wxWizard(frame,wxID_ANY,_T("Absolutely Useless Wizard"),
wxBitmap(wiztest_xpm),wxDefaultPosition,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
// a wizard page may be either an object of predefined class
m_page1 = new wxWizardPageSimple(this);<---------------- HERE
and gave this error:
Unhandled exception at 0x004425ec in wizard.exe: 0xC0000005: Access
violation reading location 0xcdcdcdd1.
I checked in debugger and saw that it goes to
void wxWizardPage::Init()
{
m_bitmap = wxNullBitmap;<--- HERE
}
and then a few inner calls later trying to access m_refData->m_count where m_refData contains garbage m_refData = 0xcdcdcdcd {m_count=??? } and then crashed.
void wxObject::UnRef()
{
if ( m_refData )
{
wxASSERT_MSG( m_refData->m_count > 0, _T("invalid ref data count") );<----- HERE
if ( --m_refData->m_count == 0 )
delete m_refData;
m_refData = NULL;
}
}
Here is call stack if it will be useful:
wizard.exe!wxObject::UnRef() Line 346 + 0x6 bytes C++
wizard.exe!wxObject::Ref(const wxObject & clone) Line 335 C++
wizard.exe!wxObject::operator=(const wxObject & other) Line 428 C++
wizard.exe!wxGDIObject::operator=(const wxGDIObject & __that) + 0x13
bytes C++ wizard.exe!wxGDIImage::operator=(const wxGDIImage &
__that) + 0x13 bytes C++ wizard.exe!wxBitmap::operator=(const wxBitmap & __that) + 0x13 bytes C++
wizard.exe!wxWizardPage::Init() Line 126 C++ wizard.exe!wxWizardPage::wxWizardPage() Line 50 + 0x46 bytes C++
wizard.exe!wxWizardPageSimple::wxWizardPageSimple(wxWizard * parent,
wxWizardPage * prev, wxWizardPage * next, const wxBitmap & bitmap,
const char * resource) Line 113 + 0x2e bytes C++
wizard.exe!MyWizard::MyWizard(wxFrame * frame, bool useSizer) Line
376 + 0x31 bytes C++
I have the source code f a qt application which was written by somebody else who is not with my company anymore.
I managed to compile the code using qt 4.8.4. I found that original version used qt 4.7.3.
When I run application it crashes just after start-up inside one of the qt DLL.
I am developing on windows7 x64, but target is x86. I am using VS 2012 and compiled qt using VS 2012.
Do I need to set anything environment variable for QT to work properly?
Do I need to install any other software (such as opengl or any other library that qt relays on them)?
Edit 1
The stack after crashing is:
QtOpenGLd4.dll!QGLContextPrivate::extensionFuncs(const QGLContext * ctx) Line 467 C++
QtOpenGLd4.dll!qt_resolve_glsl_extensions(QGLContext * ctx) Line 257 C++
QtOpenGLd4.dll!QGLShaderPrivate::create() Line 227 C++
QtOpenGLd4.dll!QGLShader::QGLShader(QFlags<enum QGLShader::ShaderTypeBit> type, const QGLContext * context, QObject * parent) Line 342 C++
QtOpenGLd4.dll!QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext * context) Line 191 C++
QtOpenGLd4.dll!QGLContextGroupResource<QGLEngineSharedShaders>::value(const QGLContext * context) Line 777 C++
QtOpenGLd4.dll!QGLShaderStorage::shadersForThread(const QGLContext * context) Line 63 C++
QtOpenGLd4.dll!QGLEngineSharedShaders::shadersForContext(const QGLContext * context) Line 74 C++
QtOpenGLd4.dll!QGLEngineShaderManager::QGLEngineShaderManager(QGLContext * context) Line 467 C++
QtOpenGLd4.dll!QGL2PaintEngineEx::begin(QPaintDevice * pdev) Line 2150 C++
QtGuid4.dll!QPainter::begin(QPaintDevice * pd) Line 1881 C++
QtGuid4.dll!QPainter::QPainter(QPaintDevice * pd) Line 1508 C++
myapp.exe!SViewer::paintEvent(QPaintEvent * __formal) Line 187 C++
QtGuid4.dll!QWidget::event(QEvent * event) Line 8533 C++
QtOpenGLd4.dll!QGLWidget::event(QEvent * e) Line 4408 C++
QtGuid4.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 4562 C++
QtGuid4.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 4527 C++
QtCored4.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 946 C++
QtCored4.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 234 C++
QtGuid4.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore) Line 5598 C++
QtGuid4.dll!QWidgetPrivate::repaint_sys(const QRegion & rgn) Line 1659 C++
QtGuid4.dll!QWidgetPrivate::syncBackingStore() Line 1894 C++
QtGuid4.dll!QWidget::event(QEvent * event) Line 8680 C++
QtOpenGLd4.dll!QGLWidget::event(QEvent * e) Line 4408 C++
QtGuid4.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 4562 C++
QtGuid4.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 4527 C++
QtCored4.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 946 C++
QtCored4.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 231 C++
QtCored4.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data) Line 1570 C++
QtCored4.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned int wp, long lp) Line 496 C++
user32.dll!75ce62fa() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]
user32.dll!75ce6d3a() Unknown
user32.dll!75ce6ce9() Unknown
user32.dll!75ce77c4() Unknown
user32.dll!75ce788a() Unknown
QtCored4.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 810 C++
QtGuid4.dll!QGuiEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 1204 C++
QtCored4.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 150 C++
QtCored4.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 204 C++
QtGuid4.dll!QDialog::exec() Line 555 C++
myapp.exe!MainWindow::actionWelcomeDialog() Line 1078 C++
myapp.exe!MainWindow::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 92 C++
QtCored4.dll!QMetaCallEvent::placeMetaCall(QObject * object) Line 524 C++
QtCored4.dll!QObject::event(QEvent * e) Line 1194 C++
QtGuid4.dll!QWidget::event(QEvent * event) Line 8845 C++
QtGuid4.dll!QMainWindow::event(QEvent * event) Line 1479 C++
QtGuid4.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 4562 C++
QtGuid4.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 4527 C++
QtCored4.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 946 C++
QtCored4.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 231 C++
QtCored4.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data) Line 1570 C++
QtCored4.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned int wp, long lp) Line 496 C++
user32.dll!75ce62fa() Unknown
user32.dll!75ce6d3a() Unknown
user32.dll!75ce6ce9() Unknown
user32.dll!75ce77c4() Unknown
user32.dll!75ce788a() Unknown
QtCored4.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 810 C++
QtGuid4.dll!QGuiEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 1204 C++
QtCored4.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 150 C++
QtCored4.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 204 C++
QtCored4.dll!QCoreApplication::exec() Line 1218 C++
QtGuid4.dll!QApplication::exec() Line 3824 C++
myapp.exe!main(int argc, char * * argv) Line 26 C++
myapp.exe!WinMain(HINSTANCE__ * instance, HINSTANCE__ * prevInstance, char * __formal, int cmdShow) Line 131 C++
myapp.exe!__tmainCRTStartup() Line 528 C
myapp.exe!WinMainCRTStartup() Line 377 C
kernel32.dll!758333aa() Unknown
ntdll.dll!77d59ef2() Unknown
ntdll.dll!77d59ec5() Unknown
I had the same problem with my own QT-Application using Qt 4.8.3 with OpenGL.
I found out that the crash is due to the using OpenGL paint engine. The engine type should automatically be set to OnegGL2 if the OpenGL driver reports that it supports OpenGL 2.0. This seems to be failing in my case.
To fix the problem I set the OpenGL preferred paint engine by adding the following code before constructing my QT-Application:
QGL::setPreferredPaintEngine(QPaintEngine::OpenGL);
Okay... here is your laundry list:
Make sure that you are building with the MSVS compiler, and compiling for win32.
If your application is surrounded by dll's built for mingw, or win64, you may have just entered "DLL he**". Make sure that you don't have any dll's sitting right next to your application's exe, or in the working directory (probably your folder that your source is in).
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682586(v=vs.85).aspx#search_order_for_desktop_applications
Now go and check your system and user environment variables. Make sure that there isn't a listing for some Qt folder that you aren't building for.
Also go and make sure that Qt Creator or Visual Studio is pointing that the version of Qt you are building for.
Do a build clean on your project, and rebuild the whole thing. Be sure to read the "Compile Output" and "Build Output" folders.
Try building and running your program in debug. Then also try building and running your program in release. Make note of the application output, and the compile output.
If you are still crashing on startup, go and start putting in debug statements throughout your code to see where it is dying, or break points when you are running you debug version in debug mode. For example: qDebug() << Q_FUNC_INFO; at the top of your main function.
Also when it crashes, make note of the return code. Searching the return code in Google can also tell you a lot about what is going on.
Also check the paths that your program relies on.
Go and check your .pro file for any dependencies that you weren't aware of.
And beyond that you will probably need to give more info to get more help from me. :)
Hope that helps.
Is static local variables safe for a class that creates/uses std::threads?
Because when I use something like this:
logger& logger::get_instance(void)
{
static logger lg;
return lg;
}
And try to exit (force close) the executable, it crashes/exits improperly (somethings the Visual Studio 2012 debugger even crashes).
When I don't do that, the program exits gracefully when i force close.
Here's the stack call when it crashes
ntdll.dll!77c10dbd() Unknown
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!77b7bfdc() Unknown
kernel32.dll!75b55bab() Unknown
> msvcr110d.dll!__crtCreateThreadpoolWait(void (_TP_CALLBACK_INSTANCE *, void *, _TP_WAIT *, unsigned long) * pfnwa, void * pv, _TP_CALLBACK_ENVIRON_V1 * pcbe) Line 569 C
msvcr110d.dll!Concurrency::details::RegisterAsyncWaitAndLoadLibrary(void * waitingEvent, void (_TP_CALLBACK_INSTANCE *, void *, _TP_WAIT *, unsigned long) * callback, void * data) Line 675 C++
msvcr110d.dll!Concurrency::details::ExternalContextBase::PrepareForUse(bool explicitAttach) Line 120 C++
msvcr110d.dll!Concurrency::details::ExternalContextBase::ExternalContextBase(Concurrency::details::SchedulerBase * pScheduler, bool explicitAttach) Line 52 C++
msvcr110d.dll!Concurrency::details::SchedulerBase::GetExternalContext(bool explicitAttach) Line 1579 C++
msvcr110d.dll!Concurrency::details::SchedulerBase::AttachExternalContext(bool explicitAttach) Line 1527 C++
msvcr110d.dll!Concurrency::details::SchedulerBase::CreateContextFromDefaultScheduler() Line 569 C++
msvcr110d.dll!Concurrency::details::SchedulerBase::CurrentContext() Line 402 C++
msvcr110d.dll!Concurrency::details::LockQueueNode::LockQueueNode(unsigned int timeout) Line 616 C++
msvcr110d.dll!Concurrency::critical_section::lock() Line 1017 C++
msvcp110d.dll!mtx_do_lock(_Mtx_internal_imp_t * * mtx, const xtime * target) Line 65 C++
msvcp110d.dll!_Mtx_lock(_Mtx_internal_imp_t * * mtx) Line 144 C++
escobar.exe!std::_Mtx_lockX(_Mtx_internal_imp_t * * _Mtx) Line 68 C++
escobar.exe!std::_Mutex_base::lock() Line 43 C++
escobar.exe!std::unique_lock<std::mutex>::unique_lock<std::mutex>(std::mutex & _Mtx) Line 228 C++
escobar.exe!escobar::utilities::blocking_queue<escobar::logging::log_message *>::interrupt() Line 71 C++
escobar.exe!escobar::logging::log_worker::~log_worker() Line 17 C++
escobar.exe!escobar::logging::log_worker::`scalar deleting destructor'(unsigned int) C++
escobar.exe!escobar::logging::logger::close() Line 72 C++
escobar.exe!escobar::logging::logger::~logger() Line 27 C++
escobar.exe!`escobar::logging::logger::get_instance'::`2'::`dynamic atexit destructor for 'lg''() C++
msvcr110d.dll!doexit(int code, int quick, int retcaller) Line 585 C
msvcr110d.dll!_cexit() Line 410 C
msvcr110d.dll!__CRTDLL_INIT(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 296 C
msvcr110d.dll!_CRTDLL_INIT(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 210 C
ntdll.dll!77bb2846() Unknown
ntdll.dll!77bb2893() Unknown
ntdll.dll!77bc09c8() Unknown
ntdll.dll!77bc08ad() Unknown
KernelBase.dll!75525bbb() Unknown
KernelBase.dll!75525c51() Unknown
kernel32.dll!75b58543() Unknown
ntdll.dll!77bbac69() Unknown
ntdll.dll!77bbac3c() Unknown
Here are a couple of the functoin
log_worker::~log_worker(void)
{
this->queue.interrupt();
service.join();
}
void log_worker::run(void)
{
while (true)
{
log_message* msg;
if (this->queue.dequeue(msg) == false)
break;
this->lg->print_log_message(msg);
delete msg;
}
}
bool dequeue(T& item)
{
std::unique_lock<std::mutex> lock(m);
// handles spurious wakeups
while (!this->data_available && !this->interrupted)
cv.wait(lock);
if (this->interrupted)
return false;
item = std::move(this->front());
this->pop();
if (this->empty())
this->data_available = false;
return true;
}
void interrupt(void)
{
std::unique_lock<std::mutex> lock(m);
this->interrupted = true;
cv.notify_all();
printf("notified threads...\n");
}
Looks like you have a detached thread SchedulerBase(could be any scheduled thread which still uses logger) which is still running while your application is stopped and logger is destroyed which caused the crash.
And log_worker is dynamically allocated in the logger class.
You need to make sure all threads who use logger instance are shutdown properly before logger is destroyed
delete log_worker in logger destructor
I simply had to stop deleting things on shutdown. When you close the console using the 'X' button, it's not a proper shutdown, so It's pointless trying to shutdown threads.
I have a function called PreProcessSource, which allocates a boost::wave::context and does some preprocessing; nothing fancy at all.
std::string PreProcessSource(const std::string& instring, const std::string& defines)
{
typedef boost::wave::cpplexer::lex_token<> token_type;
typedef boost::wave::cpplexer::lex_iterator<token_type> lex_iterator_type;
typedef boost::wave::context<std::string::iterator, lex_iterator_type> context_type;
std::string source = instring;
context_type ctx(source.begin(), source.end()); // DEADLOCK here
ctx.set_language(boost::wave::enable_emit_line_directives(ctx.get_language(), true));
if(!defines.empty())
{
std::vector<std::string> tokens;
Split<std::string>(defines, tokens, ",");
std::vector<std::string>::const_iterator cit = tokens.begin();
for (;cit != tokens.end(); ++cit)
ctx.add_macro_definition(*cit);
}
context_type::iterator_type first = ctx.begin();
context_type::iterator_type last = ctx.end();
std::string outstring;
while (first != last)
{
const token_type::string_type& value = (*first).get_value();
std::copy(value.begin(), value.end(), std::back_inserter(outstring));
++first;
}
return outstring;
}
In the past (this project is being modernized so it was broken for a long time) it used to work fine in the same setup:
Library A is a DLL that hosts the PreProcess source function, executable B uses the DLL A and can call PreProcess source, and DLL A can also sometimes call the function itself.
But right now this is no longer the case: whenever DLL A calls the function itself, or DLL A calls another function, which in turn calls back into DLL A PreProcess source, it deadlocks.
Here's an example that works just fine from my unit testing:
BOOST_AUTO_TEST_CASE(Preprocessor)
{
std::stringstream sstream;
sstream << "void main(inout float4 vtxInput : POSITION) { }" << std::endl << std::endl;
std::string source = sstream.str();
std::string defines = "";
try
{
std::string shaderCode = Nitro::PreProcessSource(source, defines);
} catch (boost::wave::preprocess_exception& pe)
{
std::cerr << pe.what() << std::endl;
}
}
And here is the weird bit, if DO_DEADLOCK is defined to 1 in the following piece of code, the deadlock will happen:
class Tutorial00 : public Game
{
public:
// ...
Tutorial00()
: Game()
{
#if !DO_DEADLOCK
std::stringstream sstream;
sstream << "void main(inout float4 vtxInput : POSITION) { }" << std::endl << std::endl;
std::string source = sstream.str();
std::string defines = "";
std::string shaderCode = Nitro::PreProcessSource(source, defines);
#endif
}
void LoadContent()
{
#if DO_DEADLOCK
std::stringstream sstream;
sstream << "void main(inout float4 vtxInput : POSITION) { }" << std::endl << std::endl;
std::string source = sstream.str();
std::string defines = "";
std::string shaderCode = Nitro::PreProcessSource(source, defines);
#endif
// Original code that deadlocks too.
// Calls in the DLL, which will call PreProcessSource.
// effect->Initialize(device, source, "DX11");
}
// ...
};
#if 1
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
#else
int main(int argc, char* argv[])
#endif
{
Tutorial00 app;
app.Run();
return 0;
}
Note that the constructor is called directly from the executable, whereas LoadContent is called from the DLL:
// In the DLL
void Game::Run()
{
try
{
// ...
LoadContent();
// ...
} catch(/* ... */) { }
}
The code is compiled for x64 and in debug mode.
I compile boost myself into a DLL (using bcp to get the files for the libraries I use) with the following options:
Preprocessor:
WIN32
BOOST_ALL_NO_LIB
BOOST_ALL_DYN_LINK
BOOST_THREAD_BUILD_DLL
_DLL
_DEBUG
_WINDOWS
_USRDLL
Code Generation:
C++ Exceptions (/EHsc)
Multi-threaded Debug DLL (/MDd)
Function-level linking (/Gy)
Streaming SIMD Extensions 2 (/arch:SSE2) (/arch:SSE2)
Fast floating point model (/fp:fast)
DLL A uses the same options except for BOOST_ALL_DYN_LINK, BOOST_THREAD_BUILD_DLL and the string pooling option.
The Boost unit test library is build separately as a static library.
Here is the stack trace of the working version:
Nitro.dll!boost::call_once<void (__cdecl*)(void)>(boost::once_flag & flag, void (void)* f) Line 200 C++
Nitro.dll!boost::call_once(void (void)* func, boost::once_flag & flag) Line 28 C++
Nitro.dll!boost::spirit::classic::static_<boost::thread_specific_ptr<boost::weak_ptr<boost::spirit::classic::impl::grammar_helper ... Line 72 + 0x13 bytes C++
Nitro.dll!boost::spirit::classic::impl::get_definition<boost::wave::util::time_conversion::time_conversion_grammar, ... Line 241 + 0x17 bytes C++
Nitro.dll!boost::spirit::classic::impl::grammar_parser_parse<0,boost::wave::util::time_conversion::time_conversion_grammar, ... Line 296 + 0xa bytes C++
Nitro.dll!boost::spirit::classic::grammar<boost::wave::util::time_conversion::time_conversion_grammar, ... Line 55 + 0x3c bytes C++
Nitro.dll!boost::spirit::classic::grammar<boost::wave::util::time_conversion::time_conversion_grammar, ... Line 65 + 0x75 bytes C++
Nitro.dll!boost::spirit::classic::impl::phrase_parser<boost::spirit::classic::space_parser>::parse<char const * __ptr64,boost::wave::util::time_conversion::time_conversion_grammar> ... Line 136 C++
Nitro.dll!boost::spirit::classic::parse<char const * __ptr64,boost::wave::util::time_conversion::time_conversion_grammar, ... Line 155 + 0x3a bytes C++
Nitro.dll!boost::spirit::classic::parse<char,boost::wave::util::time_conversion::time_conversion_grammar, ... Line 173 + 0x23 bytes C++
Nitro.dll!boost::wave::util::time_conversion::time_conversion_helper::time_conversion_helper(const char * act_time) Line 123 C++
Nitro.dll!boost::wave::util::predefined_macros::predefined_macros() Line 196 + 0x38 bytes C++
...
Nitro.dll!Nitro::PreProcessSource(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & instring, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & defines) Line 51 + 0xa0 bytes C++
NitroCoreUnitTests.exe!Preprocessor::test_method() Line 16 C++
NitroCoreUnitTests.exe!Preprocessor_invoker() Line 7 + 0x1f bytes C++
...
NitroCoreUnitTests.exe!boost::unit_test::unit_test_main(boost::unit_test::test_suite * (int, char * *)* init_func, int argc, char * * argv) Line 187 C++
NitroCoreUnitTests.exe!main(int argc, char * * argv) Line 238 C++
NitroCoreUnitTests.exe!__tmainCRTStartup() Line 555 + 0x19 bytes C
NitroCoreUnitTests.exe!mainCRTStartup() Line 371 C
kernel32.dll!00000000766a652d()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
ntdll.dll!0000000076d9c521()
And here is the stack trace of the deadlock:
ntdll.dll!0000000076dc135a()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
KernelBase.dll!000007fefd4f10dc()
Nitro.dll!boost::call_once<void (__cdecl*)(void)>(boost::once_flag & flag, void (void)* f) Line 197 + 0x18 bytes C++
Nitro.dll!boost::call_once(void (void)* func, boost::once_flag & flag) Line 28 C++
Nitro.dll!boost::spirit::classic::static_<boost::thread_specific_ptr<boost::weak_ptr<boost::spirit::classic::impl::grammar_helper ... Line 72 + 0x13 bytes C++
Nitro.dll!boost::spirit::classic::impl::get_definition<boost::wave::util::time_conversion::time_conversion_grammar, ... Line 241 + 0x17 bytes C++
Nitro.dll!boost::spirit::classic::impl::grammar_parser_parse<0,boost::wave::util::time_conversion::time_conversion_grammar, ... Line 296 + 0xa bytes C++
Nitro.dll!boost::spirit::classic::grammar<boost::wave::util::time_conversion::time_conversion_grammar, ... Line 55 + 0x3c bytes C++
Nitro.dll!boost::spirit::classic::grammar<boost::wave::util::time_conversion::time_conversion_grammar, ... Line 65 + 0x75 bytes C++
Nitro.dll!boost::spirit::classic::impl::phrase_parser<boost::spirit::classic::space_parser>::parse<char const * __ptr64,boost::wave::util::time_conversion::time_conversion_grammar> ... Line 136 C++
Nitro.dll!boost::spirit::classic::parse<char const * __ptr64,boost::wave::util::time_conversion::time_conversion_grammar, ... Line 155 + 0x3a bytes C++
Nitro.dll!boost::spirit::classic::parse<char,boost::wave::util::time_conversion::time_conversion_grammar, ... Line 173 + 0x23 bytes C++
Nitro.dll!boost::wave::util::time_conversion::time_conversion_helper::time_conversion_helper(const char * act_time) Line 123 C++
Nitro.dll!boost::wave::util::predefined_macros::predefined_macros() Line 196 + 0x38 bytes C++
...
Nitro.dll!Nitro::PreProcessSource(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & instring, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & defines) Line 51 + 0xa0 bytes C++
Tutorial01.exe!Tutorial01::LoadContent() Line 70 + 0x33 bytes C++
Nitro.dll!Nitro::Game::Run() Line 40 C++
Tutorial01.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 149 C++
Tutorial01.exe!__tmainCRTStartup() Line 547 + 0x42 bytes C
Tutorial01.exe!wWinMainCRTStartup() Line 371 C
kernel32.dll!00000000766a652d()
ntdll.dll!0000000076d9c521()
It seems boost::wave is trying to parse some time stamp, and by doing so instantiates a grammar and that's when things seem to go South.
Thanks in advance for any help :)
I found the following ticket opened on boost's trac: boost::call_once not re-entrant (at least in win32)
It says that call_once is not re-entrant, and shouldn't be called recursively. Thus the code that I am employing is undefined behavior; the ticket was marked as "will not fix".
The solution I've taken was to create a separate DLL that only contains the PreProcessSource function.