88#include < cctype>
99#include < iomanip>
1010#include < algorithm>
11+ #include < thread>
12+ #include < chrono>
1113
1214using std::shared_ptr;
1315using std::vector;
1416using std::wcout;
1517using std::endl;
18+ using std::atomic;
1619
1720shared_ptr<SlowPathELTProfiler> SlowPathELTProfiler::s_profiler;
1821
@@ -24,18 +27,81 @@ shared_ptr<SlowPathELTProfiler> SlowPathELTProfiler::s_profiler;
2427#define PROFILER_STUB EXTERN_C void STDMETHODCALLTYPE
2528#endif // WIN32
2629
30+ class ELTGuard
31+ {
32+ private:
33+ static atomic<bool > s_preventHooks;
34+ static atomic<int > s_hooksInProgress;
35+
36+ public:
37+ ELTGuard ()
38+ {
39+ ++s_hooksInProgress;
40+ }
41+
42+ ~ELTGuard ()
43+ {
44+ --s_hooksInProgress;
45+ }
46+
47+ static void Initialize ()
48+ {
49+ s_preventHooks = false ;
50+ s_hooksInProgress = 0 ;
51+ }
52+
53+ static bool HasShutdownStarted ()
54+ {
55+ return s_preventHooks.load ();
56+ }
57+
58+ static void WaitForInProgressHooks ()
59+ {
60+ s_preventHooks = true ;
61+
62+ while (s_hooksInProgress.load () > 0 )
63+ {
64+ std::this_thread::sleep_for (std::chrono::milliseconds (10 ));
65+ }
66+ }
67+ };
68+
69+ atomic<bool > ELTGuard::s_preventHooks;
70+ atomic<int > ELTGuard::s_hooksInProgress;
71+
2772PROFILER_STUB EnterStub (FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo)
2873{
74+ ELTGuard ();
75+
76+ if (ELTGuard::HasShutdownStarted ())
77+ {
78+ return ;
79+ }
80+
2981 SlowPathELTProfiler::s_profiler->EnterCallback (functionId, eltInfo);
3082}
3183
3284PROFILER_STUB LeaveStub (FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo)
3385{
86+ ELTGuard ();
87+
88+ if (ELTGuard::HasShutdownStarted ())
89+ {
90+ return ;
91+ }
92+
3493 SlowPathELTProfiler::s_profiler->LeaveCallback (functionId, eltInfo);
3594}
3695
3796PROFILER_STUB TailcallStub (FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo)
3897{
98+ ELTGuard ();
99+
100+ if (ELTGuard::HasShutdownStarted ())
101+ {
102+ return ;
103+ }
104+
39105 SlowPathELTProfiler::s_profiler->TailcallCallback (functionId, eltInfo);
40106}
41107
@@ -50,6 +116,8 @@ HRESULT SlowPathELTProfiler::Initialize(IUnknown* pICorProfilerInfoUnk)
50116{
51117 Profiler::Initialize (pICorProfilerInfoUnk);
52118
119+ ELTGuard::Initialize ();
120+
53121 HRESULT hr = S_OK;
54122 constexpr ULONG bufferSize = 1024 ;
55123 ULONG envVarLen = 0 ;
@@ -109,6 +177,8 @@ HRESULT SlowPathELTProfiler::Initialize(IUnknown* pICorProfilerInfoUnk)
109177
110178HRESULT SlowPathELTProfiler::Shutdown ()
111179{
180+ ELTGuard::WaitForInProgressHooks ();
181+
112182 Profiler::Shutdown ();
113183
114184 if (_testType == TestType::EnterHooks)
0 commit comments