I have the following classes in my code.
In other words, There is a static object (singletone) which creates thread in CTor, and when its DTor is called, it has some work to be done in the context of this thread (DTor puts some jobs for the thread).
The problem that i face is that when the DTor of B is called there are no other threads running in the process - seems like this thread is killed by process cleanup before calling the destructor of class B.
Anyone knows why this happens? and how to avoid it?
UPD: The problems occures only when Singleton is created from DLL. All works fine when Singleton is created from the same executable.
I am using VS2017
Singleton.dll (A.h + A.cpp)
A.h -->
#pragma once
#include <thread>
class __declspec(dllexport) A
{
public:
static A* instance();
A();
~A();
private:
bool stopFlag;
std::thread mThread;
};
A.cpp
#include "stdafx.h"
#include <thread>
#include "A.h"
using namespace std;
A::A()
{
mThread = std::thread([this] { while (stopFlag == false) { } });
}
A::~A()
{
stopFlag = true;
mThread.join();
}
A* A::instance()
{
static A self;
return &self;
}
================================================================================
Executable which uses DLL
main.cpp
#include "stdafx.h"
#include "A.h"
int main()
{
auto a = A::instance();
return 0;
}
Updated with the compilable code. Now if you compile the first two files as DLL, and then put breakpoint in A's destructor, you will see that thread with lambda function does not exists....
UPDATE: Found an answer by myslef. In Windows, static object from DLL are unloaded ay very last point when all threads are already cleaned up
https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx
Found an answer by myslef. In Windows, static object from DLL are unloaded ay very last point when all threads are already cleaned up https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx
Related
I am using VS2019
Trying to call a thread in DLL. to run two executables simultaneously with detach
following threads worked when I Run a normal c++ program
I get error
Error C3867 'myClass::runexeone': non-standard syntax; use '&' to create a pointer to member myGateway C:\Users\user\Downloads\Demo\myGateway\myplugin.cpp 21
plugin header
#include <windows.h>
#include <iostream>
#include <thread>
#define MYPLUGIN_EXPORT __declspec(dllexport)
extern "C"
{
MYPLUGIN_EXPORT void WINAPI OnStart();
}
pluging.cpp
#include "plugin.h"
using namespace std;
class myClass
{
public:
myClass()
{
}
~myClass()
{
}
void onStart()
{
std::thread(runexeone).detach();
std::thread(runexetwo).detach();
}
void runexeone()
{
int exerunpne = system("cmd /C \"%MY_ROOT%\\bin\\Mytest.exe\" -ORBEndpoint iiop://localhost:12345 -d");
}
void runexetwo()
{
int exeruntwo = system("cmd /C \"%MY_ROOT%\\bin\\Mytest_2.exe\" -ORBEndpoint iiop://localhost:12345 -d");
}
};
myClass& getmyclass()
{
static myClass myclass;
return myclass;
}
MYPLUGIN_EXPORT void WINAPI OnStart()
{
getmyClass().onStart();
}
The problem is that runexeone is an unqualified name of a member function, and std::thread needs something executable. runexeone isn't. VC++ tries to guess from context what you mean, but the suggestion isn't enough. Even if you had written &myClass::runexeone, it still wouldn't have worked, because myClass::runexeone also needs a this pointer. You can fix the latter problem by making it static.
Compiler suggestions work best when there's just one problem.
As MSalters already mentioned, you provided the wrong data type for the functor for std::thread. If you cannot make the method static (which you can actually at least for the current state of your code, but to let this not be unstated here), you can do this
void onStart()
{
std::thread(std::bind(&myClass::runexeone, this)).detach();
}
But be careful about the lifetime/existence of your object/this!
So I've got this interface class that I include, both in the dll and the client project
// InterfaceClass.h
#pragma once
class InterfaceClass
{
public:
virtual void Update() = 0;
};
This is the dll class that calls one of its own methods inside update
// DLLClassThatDoesSomething.cpp
#include "InterfaceClass.h"
#include <iostream>
#include <string>
class __declspec(dllexport) DLLClass : public InterfaceClass
{
public:
void Update()
{
std::cout << this->GetString();
}
std::string& GetString()
{
std::string thestring = "bruhmoment";
return thestring;
}
};
extern "C"
{
__declspec(dllexport) InterfaceClass* CreateInstance()
{
return new DLLClass();
}
}
And this is the "Client" project
// main.cpp
#include "InterfaceClass.h"
#include <Windows.h>
typedef InterfaceClass* (__cdecl *Class) ();
int main()
{
HINSTANCE dll = LoadLibrary(L"DLLClass.dll");
Class klass = (Class)GetProcAddress(dll, "CreateInstance");
InterfaceClass* IKlass = klass();
IKlass->Update();
FreeLibrary(dll);
return 0;
}
The moment I call IKlass->Update() I get an exception for Access Memory Violation because of the DLLClass calling its own method.
I haven't tried anything since I barely know how to load a DLL on runtime and I've used this nifty tutorial
How can I let it call the method and not get thrown an exception? I'm trying to let ppl that will create mods for my game create their own mods with their custom classes for bosses, mobs and etc. in DLLs.
EDIT:
Turns out it was a syntax mistake on my end. Instead of return new DLLClass;, it had to be return new DLLClass();. After fixing it, it works as intended.
You return a reference to a local variable thestring, and by the time you try to access it in
std::cout << this->GetString(), referenced data is already destroyed. In fact, it is destroyed right after the end of enclosing scope of compound statement where the variable was declared.
It may "appear" to work sometimes due to the stack not being overwritten yet, but eventually it will fail miserably like it did in your case. This triggers UB (undefined behavior).
I, for some reason, need to have a global object in a .dll, which manages a std::thread. It is implemented in a following way:
#include "Header.h"
#include <thread>
#include <condition_variable>
#include <mutex>
class Foo
{
public:
Foo () : m_closeThread (false)
{
m_thread = std::thread (&Foo::ThreadProc, this);
}
~Foo ()
{
{
std::unique_lock<std::mutex> lock (m_mutex);
m_closeThread = true;
}
m_cv.notify_one ();
m_thread.join ();
}
private:
void ThreadProc ()
{
while (true)
{
std::unique_lock<std::mutex> lock (m_mutex);
m_cv.wait (lock, [this] () { return m_closeThread; });
if (m_closeThread)
break;
}
}
private:
bool m_closeThread;
std::thread m_thread;
std::condition_variable m_cv;
std::mutex m_mutex;
};
Foo& GetFoo ()
{
static Foo foo;
return foo;
}
extern "C" void Function ()
{
auto& foo = GetFoo ();
}
However, when, the application is closed, before the ~Foo is executed, all worker threads, of the .dll, get killed, or as the output window of MSVS2015 says:
The thread 0x1040 has exited with code 0 (0x0).
And, due to this fact (Source0, Source1), the application blocks on m_cv.notify_one (); call, if one uses Windows 7 (doesn't block on Windows 8 and above).
The fact, that it blocks on one particular version of Windows, while not on others, makes me think, that some sort of UB is to blame (such as DLL unload ordering related issue, since such issue is not reproducible if such object is not in a .dll), but I fail to think of solution, that allows me to gracefully shutdown the thread, while having the object global (since, one would need to do major application restructuring, to make it not global).
So, can one shutdown the thread gracefully, before it is killed by the Windows platform?
Side note 0:
For the sake of example completeness,
this is the DLLMain:
#include <Windows.h>
BOOL APIENTRY DllMain (HMODULE, DWORD, LPVOID) { return TRUE; }
This is the Header of the .dll:
#pragma once
extern "C" void Function ();
This is the Console application, that uses said .dll:
#include "..\Test\Header.h"
#include <chrono>
#include <thread>
int main ()
{
Function ();
using namespace std::chrono_literals;
std::this_thread::sleep_for (2s);
}
Side note 1:
I am, currently limited to using, at most, C++11 (or, whatever functionality is present in MSVS 2015).
When WinMain returns, the runtime calls ExitProcess. The first thing that does is "1. All of the threads in the process, except the calling thread, terminate their execution without receiving a DLL_THREAD_DETACH notification."
Situation
External library (LibraryExternal) that I cannot change calls LoadLibrary on LibraryA. After it is succesfully loaded, it calls an exported function AExport which returns a pointer to ClassA, which is a static instance. Before AExport returns, it too loads a library via LoadLibrary, called LibraryB. After succesfull load, it calls an exported function BExport which in turn returns a pointer to a static instance ClassB.
IMPORTANT
LibraryA is a c++ dll compiled with vs2012 xp tools and LibraryB is a c++/cli dll also compiled with vs2012 xp tools.
All libraries share some other libraries which only define what ClassA and ClassB need to derive from, in order to make sense of the pointers returned by AExport and BExport. They are nothing more than stubs and do not matter in this question (Only pure virtual functions, no fields and nothing being done in ctor/dtor).
Result
When LibraryExternal gets unloaded via program exit, it calls FreeLibrary on LibraryA. This succesfully calls the destructor of ClassA which in turn frees the library LibraryB. But the destructor of ClassB is never run somehow.
Desired Result
Have ClassB destructor run
ClassA.h
#include <StubA.h>
class StubB;
class ClassA: public StubA
{
public:
ClassA();
~ClassA();
bool Initialize();
static ClassA &GetInstance()
{
static ClassA INSTANCE;
return INSTANCE;
}
private:
ClassA(ClassA const &);
void operator=(ClassA const&);
HMODULE wrapperModule;
StubB *wrapperPlugin;
};
ClassA.cpp
#include "ClassA.h"
#include <Windows.h>
// typedef WrapperPlugin *(*WrapperPluginInitType) (); This is normally in shared library
static const wchar_t *WRAPPER_MODULE_NAME = L"LibraryB.dll";
static const char *WRAPPER_MODULE_INIT_FUNCTION_NAME = "BExport";
ClassA::ClassA() :
wrapperModule(NULL),
wrapperPlugin(NULL)
{
}
ClassA::~ClassA()
{
if (this->wrapperModule != NULL)
{
FreeLibrary(this->wrapperModule);
}
}
bool CSharpBridge::Initialize()
{
this->wrapperModule = LoadLibraryW(WRAPPER_MODULE_NAME);
if (this->wrapperModule == NULL)
{
return false;
}
WrapperPluginInitType wrapperPluginInit = reinterpret_cast<WrapperPluginInitType>(GetProcAddress(this->wrapperModule, WRAPPER_MODULE_INIT_FUNCTION_NAME));
if (wrapperPluginInit == NULL)
{
return false;
}
this->wrapperPlugin = wrapperPluginInit();
if (this->wrapperPlugin == NULL)
{
return false;
}
return true;
}
extern "C"
{
__declspec(ddlexport) StubA *AExport()
{
if (!ClassA::GetInstance().Initialize())
{
return NULL;
}
return &ClassA::GetInstance();
}
}
ClassB.h
#include <StubB.h>
class ClassB : public StubB
{
public:
ClassB ();
~ClassB ();
static ClassB &GetInstance()
{
static ClassB INSTANCE;
return INSTANCE;
}
private:
ClassB (ClassB const &);
void operator=(ClassB const&);
};
ClassB.cpp
#include "ClassB.h"
#include <Windows.h>
#include <iostream>
#include <fstream>
ClassB::ClassB()
{
std::ofstream myfile;
myfile.open("C:\\Users\\USERNAME\\Desktop\\test1.txt");
myfile << "ClassB::ClassB\r\n";
myfile.close();
}
ClassB::~ClassB()
{
std::ofstream myfile;
myfile.open("C:\\Users\\USERNAME\\Desktop\\test3.txt");
myfile << "ClassB::~ClassB\r\n";
myfile.close();
}
extern "C"
{
__declspec(dllexport) StubB *WrapperInit()
{
std::ofstream myfile;
myfile.open("C:\\Users\\USERNAME\\Desktop\\test2.txt");
myfile << "WrapperInit\r\n";
myfile.close();
return &ClassB::GetInstance();
}
}
Now I know with 100% certainty that ClassA ctor/dtor are called due to some LibraryExternal functions which give me some textual confirmation. And I do seem to be getting test1.txt and test2.txt generated. But NOT test3.txt.
After this I still need to create a managed reference to LibraryC which is a C# dll and 'destruct' that too when ClassB is being destructed.
It appears that you cannot use FreeLibrary on a library that is managed from an unmanaged library. Since the managed library will start the AppDomain for which the unmanaged library knows nothing about. The AppDomain keeps the library alive and therefor the destructor was never ran. See this answer.
Calling something from unmanaged to managed will still require some special attention since in not doing so will result in an exception: 0xC0020001: The string binding is invalid ! See this. What I did to fix the issue was having a static instance at ClassB scope and initializing it with the new operator in ClassB::GetInstance. Otherwise it would not be initialized at all. I then made a function ClassB::CleanUp in which I delete it. It is however important to mark the entire class (both header and source file) unmanaged with #pragma managed(push, off) and #pragma managed(pop).
To still be able to call managed methods/classes you have to make a function in the source file that has been surrounded with #pragma managed(push, on) and #pragma managed(pop). You can then call this function from the unmanaged class. This still seems strange to me, since that function is managed too?
i have implemented a singleton (static version) in C++. I know all the controversy about this pattern and potential thread-safety issues, but i am curious why this exact implementation won't halt. The program never quits, it remains in a deadlock state at the end.
singleton.h:
#pragma once
#include <thread>
#include <atomic>
class Singleton
{
public:
static Singleton& getInstance();
private:
std::thread mThread;
std::atomic_bool mRun;
Singleton();
~Singleton();
void threadFoo();
};
singleton.cpp
#include "singleton.h"
Singleton& Singleton::getInstance()
{
static Singleton instance;
return instance;
}
Singleton::Singleton()
{
mRun.store(true);
mThread = std::thread(&Singleton::threadFoo, this);
}
Singleton::~Singleton()
{
mRun.store(false);
if(mThread.joinable())
mThread.join();
}
void Singleton::threadFoo()
{
while(mRun)
{
}
}
main.cpp
#include "singleton.h"
int main()
{
Singleton::getInstance();
return 0;
}
What I already know:
the thread terminates
the main thread is stuck in the join
it has something to do with the static, if i make the constructor public and create an instance of Singleton in main() it will correctly terminate.
Using Visual Studio 2012. Thanks for your advice.
On the main thread, after main() terminates, the CRT acquires the exit lock and calls your static instance destructor, which waits for your background thread to exit.
On the background thread, after your thread function terminates, the CRT attempts to acquire the exit lock to do some thread termination work. This blocks forever because the exit lock is held by the main thread, which is waiting for this thread to exit.
It's a simple deadlock that's caused by the CRT implementation. The bottom line is that you can't await thread termination in a static instance destructor on Windows.
I've traced it down to void __cdecl _lock(int locknum) inside mlock.c. When main() ends, the main thread goes there and enters critical section EnterCriticalSection( _locktable[locknum].lock );. Then Singleton destructor gets called and the other thread tries to enter the same critical section, but can't, and so it starts waiting for main thread to leave the critical section. Main thread, in turn, waits for the other thread. So I guess it's a bug.
See [basic.start.term] in the Standard:
If there is a use of a standard library object or function not
permitted within signal handlers (18.10) that does not happen before
(1.10) completion of destruction of objects with static storage
duration and execution of std::atexit registered functions (18.5), the
program has undefined behavior. [Note: If there is a use of an object
with static storage duration that does not happen before the object’s
destruction, the program has undefined behavior. Terminating every
thread before a call to std::exit or the exit from main is sufficient,
but not necessary, to satisfy these requirements. These requirements
permit thread managers as static-storage-duration objects. —end note ]
Ok thank you all for your hints. Apparently this pattern implementation results in a deadlock on VC++.
After doing some further research i found this implementation based on C++11 mechanics which is working in VC++.
singleton.h
#pragma once
#include <thread>
#include <atomic>
#include <memory>
#include <mutex>
class Singleton
{
public:
static Singleton& getInstance();
virtual ~Singleton();
private:
static std::unique_ptr<Singleton> mInstance;
static std::once_flag mOnceFlag;
std::thread mThread;
std::atomic_bool mRun;
Singleton();
void threadFoo();
};
singleton.cpp
#include "singleton.h"
std::unique_ptr<Singleton> Singleton::mInstance = nullptr;
std::once_flag Singleton::mOnceFlag;
Singleton& Singleton::getInstance()
{
std::call_once(mOnceFlag, [] { mInstance.reset(new Singleton); });
return *mInstance.get();
}
Singleton::Singleton()
{
mRun.store(true);
mThread = std::thread(&Singleton::threadFoo, this);
}
Singleton::~Singleton()
{
mRun.store(false);
if(mThread.joinable())
mThread.join();
}
void Singleton::threadFoo()
{
while(mRun.load())
{
}
}
UPDATE
It looks like Microsoft is aware of this issue. In the VC++ forums a user named "dlafleur" reported this post:
https://connect.microsoft.com/VisualStudio/feedback/details/747145
This deadlock bug is the same as in
std::thread::join() hangs if called after main() exits when using VS2012 RC
and it is not fixed in Visual Studio 2013.
It seems to be fixed in Visual Studio 2015 and above, at least for this specific example.