Skip to content

Commit 08c9c4c

Browse files
authored
[Profiler] Detect Single Step Instrumentation deployment
* Detect Single Step Instrumentation
1 parent 98b6687 commit 08c9c4c

File tree

9 files changed

+128
-0
lines changed

9 files changed

+128
-0
lines changed

profiler/src/ProfilerEngine/Datadog.Profiler.Native/Configuration.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ Configuration::Configuration()
8989
}
9090

9191
_isEtwEnabled = GetEnvironmentValue(EnvironmentVariables::EtwEnabled, false);
92+
ExtractSsiState(_isSsiDeployed, _isSsiActivated);
9293
}
9394

9495
fs::path Configuration::ExtractLogDirectory()
@@ -536,6 +537,16 @@ bool Configuration::IsEtwEnabled() const
536537
#endif
537538
}
538539

540+
bool Configuration::IsSsiDeployed() const
541+
{
542+
return _isSsiDeployed;
543+
}
544+
545+
bool Configuration::IsSsiActivated() const
546+
{
547+
return _isSsiActivated;
548+
}
549+
539550

540551
bool convert_to(shared::WSTRING const& s, bool& result)
541552
{
@@ -604,3 +615,30 @@ bool Configuration::IsEnvironmentValueSet(shared::WSTRING const& name, T& value)
604615
value = result;
605616
return true;
606617
}
618+
619+
void Configuration::ExtractSsiState(bool& ssiDeployed, bool& ssiEnabled)
620+
{
621+
// if the profiler has been deployed via Single Step Instrumentation,
622+
// the DD_INJECTION_ENABLED env var exists.
623+
// if the profiler has been activated via Single Step Instrumentation,
624+
// the DD_INJECTION_ENABLED env var should contain "profiling" (it is a list of SSI installed products)
625+
//
626+
if (!shared::EnvironmentExist(EnvironmentVariables::SsiDeployed))
627+
{
628+
ssiDeployed = false;
629+
ssiEnabled = false;
630+
return;
631+
}
632+
633+
ssiDeployed = true;
634+
635+
auto r = shared::GetEnvironmentValue(EnvironmentVariables::SsiDeployed);
636+
if (r.empty())
637+
{
638+
ssiEnabled = false;
639+
return;
640+
}
641+
642+
auto pos = r.find(WStr("profiling"));
643+
ssiEnabled = (pos != shared::WSTRING::npos);
644+
}

profiler/src/ProfilerEngine/Datadog.Profiler.Native/Configuration.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ class Configuration final : public IConfiguration
6767
bool IsCIVisibilityEnabled() const override;
6868
std::uint64_t GetCIVisibilitySpanId() const override;
6969
bool IsEtwEnabled() const override;
70+
bool IsSsiDeployed() const override;
71+
bool IsSsiActivated() const override;
72+
7073

7174

7275
private:
@@ -89,6 +92,7 @@ class Configuration final : public IConfiguration
8992
static int32_t ExtractCpuThreadsThreshold();
9093
static int32_t ExtractCodeHotspotsThreadsThreshold();
9194
static bool GetContention();
95+
static void ExtractSsiState(bool& ssiDeployed, bool& ssiEnabled);
9296

9397
private:
9498
static std::string const DefaultProdSite;
@@ -151,4 +155,6 @@ class Configuration final : public IConfiguration
151155
bool _isCIVisibilityEnabled;
152156
std::uint64_t _internalCIVisibilitySpanId;
153157
bool _isEtwEnabled;
158+
bool _isSsiDeployed;
159+
bool _isSsiActivated;
154160
};

profiler/src/ProfilerEngine/Datadog.Profiler.Native/EnvironmentVariables.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class EnvironmentVariables final
6161
inline static const shared::WSTRING ThreadLifetimeEnabled = WStr("DD_INTERNAL_THREAD_LIFETIME_ENABLED");
6262
inline static const shared::WSTRING SystemCallsShieldEnabled = WStr("DD_INTERNAL_SYSTEM_CALLS_SHIELD_ENABLED");
6363
inline static const shared::WSTRING EtwEnabled = WStr("DD_INTERNAL_PROFILING_ETW_ENABLED");
64+
inline static const shared::WSTRING SsiDeployed = WStr("DD_INJECTION_ENABLED");
6465

6566
inline static const shared::WSTRING CIVisibilityEnabled = WStr("DD_CIVISIBILITY_ENABLED");
6667
inline static const shared::WSTRING InternalCIVisibilitySpanId = WStr("DD_INTERNAL_CIVISIBILITY_SPANID");

profiler/src/ProfilerEngine/Datadog.Profiler.Native/IConfiguration.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,6 @@ class IConfiguration
6565
virtual bool IsCIVisibilityEnabled() const = 0;
6666
virtual std::uint64_t GetCIVisibilitySpanId() const = 0;
6767
virtual bool IsEtwEnabled() const = 0;
68+
virtual bool IsSsiDeployed() const = 0;
69+
virtual bool IsSsiActivated() const = 0;
6870
};

profiler/test/Datadog.Profiler.IntegrationTests/Helpers/EnvironmentVariables.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ internal class EnvironmentVariables
2626
public const string DebugInfoEnabled = "DD_INTERNAL_PROFILING_DEBUG_INFO_ENABLED";
2727
public const string GcThreadsCpuTimeEnabled = "DD_INTERNAL_GC_THREADS_CPUTIME_ENABLED";
2828
public const string ThreadLifetimeEnabled = "DD_INTERNAL_THREAD_LIFETIME_ENABLED";
29+
public const string SsiDeployed = "DD_INJECTION_ENABLED";
2930
}
3031
}

profiler/test/Datadog.Profiler.Native.Tests/ConfigurationTest.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,3 +825,63 @@ TEST(ConfigurationTest, CheckEtwIsDisabledIfEnvVarSetToFalse)
825825
auto expectedValue = false;
826826
ASSERT_THAT(configuration.IsEtwEnabled(), expectedValue);
827827
}
828+
829+
TEST(ConfigurationTest, CheckSsiDeployedByDefault)
830+
{
831+
auto configuration = Configuration{};
832+
ASSERT_THAT(configuration.IsSsiDeployed(), false);
833+
}
834+
835+
TEST(ConfigurationTest, CheckSsiIsDeployedIfEnvVarConstainsProfiling)
836+
{
837+
EnvironmentHelper::EnvironmentVariable ar(EnvironmentVariables::SsiDeployed, WStr("tracer,profiling"));
838+
auto configuration = Configuration{};
839+
auto expectedValue = true;
840+
ASSERT_THAT(configuration.IsSsiDeployed(), expectedValue);
841+
}
842+
843+
TEST(ConfigurationTest, CheckSsiIsDeployedIfEnvVarDoesNotContainProfiling)
844+
{
845+
EnvironmentHelper::EnvironmentVariable ar(EnvironmentVariables::SsiDeployed, WStr("tracer"));
846+
auto configuration = Configuration{};
847+
auto expectedValue = true;
848+
ASSERT_THAT(configuration.IsSsiDeployed(), expectedValue);
849+
}
850+
851+
TEST(ConfigurationTest, CheckSsiIsDeployedIfEnvVarIsEmpty)
852+
{
853+
EnvironmentHelper::EnvironmentVariable ar(EnvironmentVariables::SsiDeployed, WStr(""));
854+
auto configuration = Configuration{};
855+
auto expectedValue = true;
856+
ASSERT_THAT(configuration.IsSsiDeployed(), expectedValue);
857+
}
858+
859+
TEST(ConfigurationTest, CheckSsiActivatedByDefault)
860+
{
861+
auto configuration = Configuration{};
862+
ASSERT_THAT(configuration.IsSsiActivated(), false);
863+
}
864+
865+
TEST(ConfigurationTest, CheckSsiIsActivatedIfEnvVarConstainsProfiling)
866+
{
867+
EnvironmentHelper::EnvironmentVariable ar(EnvironmentVariables::SsiDeployed, WStr("tracer,profiling"));
868+
auto configuration = Configuration{};
869+
auto expectedValue = true;
870+
ASSERT_THAT(configuration.IsSsiActivated(), expectedValue);
871+
}
872+
873+
TEST(ConfigurationTest, CheckSsiIsNotActivatedIfEnvVarDoesNotContainProfiling)
874+
{
875+
EnvironmentHelper::EnvironmentVariable ar(EnvironmentVariables::SsiDeployed, WStr("tracer"));
876+
auto configuration = Configuration{};
877+
auto expectedValue = false;
878+
ASSERT_THAT(configuration.IsSsiActivated(), expectedValue);
879+
}
880+
881+
TEST(ConfigurationTest, CheckSsiIsNotActivatedIfEnvVarIsEmpty)
882+
{
883+
EnvironmentHelper::EnvironmentVariable ar(EnvironmentVariables::SsiDeployed, WStr(""));
884+
auto configuration = Configuration{};
885+
auto expectedValue = false;
886+
ASSERT_THAT(configuration.IsSsiActivated(), expectedValue);
887+
}

profiler/test/Datadog.Profiler.Native.Tests/ProfilerMockedInterface.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ class MockConfiguration : public IConfiguration
6969
MOCK_METHOD(bool, IsCIVisibilityEnabled, (), (const override));
7070
MOCK_METHOD(std::uint64_t, GetCIVisibilitySpanId, (), (const override));
7171
MOCK_METHOD(bool, IsEtwEnabled, (), (const override));
72+
MOCK_METHOD(bool, IsSsiDeployed, (), (const override));
73+
MOCK_METHOD(bool, IsSsiActivated, (), (const override));
7274
};
7375

7476
class MockExporter : public IExporter

shared/src/native-src/util.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,21 @@ namespace shared
121121
return false;
122122
}
123123

124+
bool EnvironmentExist(const WSTRING& name)
125+
{
126+
#ifdef _WIN32
127+
auto len = ::GetEnvironmentVariable((LPWSTR)name.data(), (LPWSTR)nullptr, 0);
128+
if (len > 0)
129+
{
130+
return true;
131+
}
132+
133+
return (::GetLastError() != ERROR_ENVVAR_NOT_FOUND);
134+
#else
135+
auto cstr = std::getenv(ToString(name).c_str());
136+
return (cstr != nullptr);
137+
#endif
138+
}
124139

125140
WSTRING GetEnvironmentValue(const WSTRING& name)
126141
{

shared/src/native-src/util.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ namespace shared
4444
// Trim removes space from the beginning and end of a string.
4545
std::string Trim(const std::string& str);
4646

47+
// Check that an environment variable exists
48+
bool EnvironmentExist(const WSTRING& name);
49+
4750
// GetEnvironmentValue returns the environment variable value for the given
4851
// name. Space is trimmed.
4952
WSTRING GetEnvironmentValue(const WSTRING& name);

0 commit comments

Comments
 (0)