Skip to content

Commit ba52589

Browse files
authored
Fix ELT profiler tests (#44285)
1 parent 41c27ff commit ba52589

2 files changed

Lines changed: 87 additions & 9 deletions

File tree

src/tests/profiler/common/ProfilerTestRunner.cs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public static int Run(string profileePath,
5353

5454
if(!File.Exists(profilerPath))
5555
{
56-
LogTestFailure("Profiler library not found at expected path: " + profilerPath);
56+
FailFastWithMessage("Profiler library not found at expected path: " + profilerPath);
5757
}
5858

5959
ProfileeOutputVerifier verifier = new ProfileeOutputVerifier();
@@ -83,17 +83,25 @@ public static int Run(string profileePath,
8383
process.BeginOutputReadLine();
8484

8585
process.WaitForExit();
86-
if (process.ExitCode == 100 && verifier.HasPassingOutput)
87-
{
88-
return 100;
89-
}
90-
else
86+
87+
// There are two conditions for profiler tests to pass, the output of the profiled program
88+
// must contain the phrase "PROFILER TEST PASSES" and the return code must be 100. This is
89+
// because lots of verification happen in the profiler code, where it is hard to change the
90+
// program return value.
91+
92+
if (!verifier.HasPassingOutput)
9193
{
92-
LogTestFailure("Profiler tests are expected to contain the text \'" + verifier.SuccessPhrase + "\' in the console output " +
94+
FailFastWithMessage("Profiler tests are expected to contain the text \'" + verifier.SuccessPhrase + "\' in the console output " +
9395
"of the profilee app to indicate a passing test. Usually it is printed from the Shutdown() method of the profiler implementation. This " +
9496
"text was not found in the output above.");
95-
return process.ExitCode == 100 ? process.ExitCode : -1;
9697
}
98+
99+
if (process.ExitCode != 100)
100+
{
101+
FailFastWithMessage($"Profilee returned exit code {process.ExitCode} instead of expected exit code 100.");
102+
}
103+
104+
return 100;
97105
}
98106

99107
private static string GetProfilerPath()
@@ -132,7 +140,7 @@ private static string GetCorerunPath()
132140
return Path.Combine(Environment.GetEnvironmentVariable("CORE_ROOT"), corerunName);
133141
}
134142

135-
private static void LogTestFailure(string error)
143+
private static void FailFastWithMessage(string error)
136144
{
137145
Console.WriteLine("Test failed: " + error);
138146
throw new Exception(error);

src/tests/profiler/native/eltprofiler/slowpatheltprofiler.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88
#include <cctype>
99
#include <iomanip>
1010
#include <algorithm>
11+
#include <thread>
12+
#include <chrono>
1113

1214
using std::shared_ptr;
1315
using std::vector;
1416
using std::wcout;
1517
using std::endl;
18+
using std::atomic;
1619

1720
shared_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+
2772
PROFILER_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

3284
PROFILER_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

3796
PROFILER_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

110178
HRESULT SlowPathELTProfiler::Shutdown()
111179
{
180+
ELTGuard::WaitForInProgressHooks();
181+
112182
Profiler::Shutdown();
113183

114184
if (_testType == TestType::EnterHooks)

0 commit comments

Comments
 (0)