Skip to content

Commit

Permalink
Update RuntimeInformation to include "inferred" runtime version (wher…
Browse files Browse the repository at this point in the history
…e we've already calculated this)
  • Loading branch information
andrewlock committed May 31, 2024
1 parent 9d35661 commit 8d9af1c
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 10 deletions.
25 changes: 19 additions & 6 deletions shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ namespace datadog::shared::nativeloader
HRESULT STDMETHODCALLTYPE CorProfiler::Initialize(IUnknown* pICorProfilerInfoUnk)
{
Log::Debug("CorProfiler::Initialize");
InspectRuntimeCompatibility(pICorProfilerInfoUnk);
const auto inferredVersion = InspectRuntimeCompatibility(pICorProfilerInfoUnk);

const auto process_name = ::shared::GetCurrentProcessName();
Log::Debug("ProcessName: ", process_name);
Expand Down Expand Up @@ -242,7 +242,7 @@ namespace datadog::shared::nativeloader
Log::Warn("CorProfiler::Initialize: Failed to attach profiler, interface ICorProfilerInfo4 not found.");
return E_FAIL;
}
const auto runtimeInformation = GetRuntimeVersion(info4);
const auto runtimeInformation = GetRuntimeVersion(info4, inferredVersion);

//
// Check if we're running in Single Step, and if so, whether we should bail out
Expand Down Expand Up @@ -1147,87 +1147,100 @@ namespace datadog::shared::nativeloader
RunInAllProfilers(EventPipeProviderCreated(provider));
}

void CorProfiler::InspectRuntimeCompatibility(IUnknown* corProfilerInfoUnk)
std::string CorProfiler::InspectRuntimeCompatibility(IUnknown* corProfilerInfoUnk)
{
if (corProfilerInfoUnk == nullptr)
{
Log::Info(
"No ICorProfilerInfoXxx available. Null pointer was passed to CorProfilerCallback for initialization."
" No compatible Profiling API is available.");
return;
return "";
}

IUnknown* tstVerProfilerInfo;
if (S_OK == corProfilerInfoUnk->QueryInterface(__uuidof(ICorProfilerInfo12), (void**) &tstVerProfilerInfo))
{
Log::Info("ICorProfilerInfo12 available. Profiling API compatibility: .NET Core 5.0 or later.");
tstVerProfilerInfo->Release();
return "5.0.0";
}
else if (S_OK == corProfilerInfoUnk->QueryInterface(__uuidof(ICorProfilerInfo11), (void**) &tstVerProfilerInfo))
{
Log::Info("ICorProfilerInfo11 available. Profiling API compatibility: .NET Core 3.1 or later.");
tstVerProfilerInfo->Release();
return "3.1.0";
}
else if (S_OK == corProfilerInfoUnk->QueryInterface(__uuidof(ICorProfilerInfo10), (void**) &tstVerProfilerInfo))
{
Log::Info("ICorProfilerInfo10 available. Profiling API compatibility: .NET Core 3.0 or later.");
tstVerProfilerInfo->Release();
return "3.0.0";
}
else if (S_OK == corProfilerInfoUnk->QueryInterface(__uuidof(ICorProfilerInfo9), (void**) &tstVerProfilerInfo))
{
Log::Info("ICorProfilerInfo9 available. Profiling API compatibility: .NET Core 2.1 or later.");
tstVerProfilerInfo->Release();
return "2.1.0";
}
else if (S_OK == corProfilerInfoUnk->QueryInterface(__uuidof(ICorProfilerInfo8), (void**) &tstVerProfilerInfo))
{
Log::Info("ICorProfilerInfo8 available. Profiling API compatibility: .NET Fx 4.7.2 or later.");
tstVerProfilerInfo->Release();
return "4.7.2";
}
else if (S_OK == corProfilerInfoUnk->QueryInterface(__uuidof(ICorProfilerInfo7), (void**) &tstVerProfilerInfo))
{
Log::Info("ICorProfilerInfo7 available. Profiling API compatibility: .NET Fx 4.6.1 or later.");
tstVerProfilerInfo->Release();
return "4.6.1";
}
else if (S_OK == corProfilerInfoUnk->QueryInterface(__uuidof(ICorProfilerInfo6), (void**) &tstVerProfilerInfo))
{
Log::Info("ICorProfilerInfo6 available. Profiling API compatibility: .NET Fx 4.6 or later.");
tstVerProfilerInfo->Release();
return "4.6.0";
}
else if (S_OK == corProfilerInfoUnk->QueryInterface(__uuidof(ICorProfilerInfo5), (void**) &tstVerProfilerInfo))
{
Log::Info("ICorProfilerInfo5 available. Profiling API compatibility: .NET Fx 4.5.2 or later.");
tstVerProfilerInfo->Release();
return "4.5.2";
}
else if (S_OK == corProfilerInfoUnk->QueryInterface(__uuidof(ICorProfilerInfo4), (void**) &tstVerProfilerInfo))
{
Log::Info("ICorProfilerInfo4 available. Profiling API compatibility: .NET Fx 4.5 or later.");
tstVerProfilerInfo->Release();
return "4.5.0";
}
else if (S_OK == corProfilerInfoUnk->QueryInterface(__uuidof(ICorProfilerInfo3), (void**) &tstVerProfilerInfo))
{
Log::Info("ICorProfilerInfo3 available. Profiling API compatibility: .NET Fx 4.0 or later.");
tstVerProfilerInfo->Release();
return "4.0.0";
}
else if (S_OK == corProfilerInfoUnk->QueryInterface(__uuidof(ICorProfilerInfo2), (void**) &tstVerProfilerInfo))
{
Log::Info("ICorProfilerInfo2 available. Profiling API compatibility: .NET Fx 2.0 or later.");
tstVerProfilerInfo->Release();
return "2.0.0";
}
else if (S_OK == corProfilerInfoUnk->QueryInterface(__uuidof(ICorProfilerInfo), (void**) &tstVerProfilerInfo))
{
Log::Info("ICorProfilerInfo available. Profiling API compatibility: .NET Fx 2 or later.");
tstVerProfilerInfo->Release();
return "2.0.0";
}
else
{
Log::Info("No ICorProfilerInfoXxx available. A valid IUnknown pointer was passed to CorProfilerCallback"
" for initialization, but QueryInterface(..) did not succeed for any of the known "
"ICorProfilerInfoXxx ifaces."
" No compatible Profiling API is available.");
return "";
}
}

RuntimeInformation CorProfiler::GetRuntimeVersion(ICorProfilerInfo4* pCorProfilerInfo)
RuntimeInformation CorProfiler::GetRuntimeVersion(ICorProfilerInfo4* pCorProfilerInfo, const std::string& inferred_version)
{
USHORT clrInstanceId;
COR_PRF_RUNTIME_TYPE runtimeType;
Expand Down Expand Up @@ -1256,7 +1269,7 @@ namespace datadog::shared::nativeloader
: (std::string("unknown(") + std::to_string(runtimeType) + std::string(")"))),
",", " majorVersion: ", majorVersion, ", minorVersion: ", minorVersion,
", buildNumber: ", buildNumber, ", qfeVersion: ", qfeVersion, " }.");
return {runtimeType, majorVersion, minorVersion, buildNumber, qfeVersion};
return {runtimeType, majorVersion, minorVersion, buildNumber, qfeVersion, inferred_version};
}
}

Expand Down
25 changes: 21 additions & 4 deletions shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ namespace datadog::shared::nativeloader
ICorProfilerInfo4* m_info;
std::shared_ptr<ICorProfilerInfo12> m_writeToDiskCorProfilerInfo;

static void InspectRuntimeCompatibility(IUnknown* corProfilerInfoUnk);
static RuntimeInformation GetRuntimeVersion(ICorProfilerInfo4* pCorProfilerInfo);
static std::string InspectRuntimeCompatibility(IUnknown* corProfilerInfoUnk);
static RuntimeInformation GetRuntimeVersion(ICorProfilerInfo4* pCorProfilerInfo, const std::string& inferred_version);

public:
CorProfiler(IDynamicDispatcher* dispatcher);
Expand Down Expand Up @@ -185,19 +185,21 @@ namespace datadog::shared::nativeloader
USHORT minor_version;
USHORT build_version;
USHORT qfe_version;
std::string inferred_version = "";

RuntimeInformation() :
runtime_type((COR_PRF_RUNTIME_TYPE) 0x0), major_version(0), minor_version(0), build_version(0), qfe_version(0)
{
}

RuntimeInformation(COR_PRF_RUNTIME_TYPE runtime_type, USHORT major_version, USHORT minor_version,
USHORT build_version, USHORT qfe_version) :
USHORT build_version, USHORT qfe_version, const std::string inferred_version) :
runtime_type(runtime_type),
major_version(major_version),
minor_version(minor_version),
build_version(build_version),
qfe_version(qfe_version)
qfe_version(qfe_version),
inferred_version(inferred_version)
{
}

Expand All @@ -219,5 +221,20 @@ namespace datadog::shared::nativeloader
{
return runtime_type == COR_PRF_CORE_CLR;
}

std::string description() const
{
// on .NET Core, prior to .NET 5, can't trust the versions
// Similarly, the inferred version (from ICorProfiler interface) gives more
// granularity for us in .NET Framework
if((is_core() && major_version >= 5) || inferred_version.empty())
{
return std::to_string(major_version) + "." +
std::to_string(minor_version) + "." +
std::to_string(build_version);
}

return inferred_version;
}
};
} // namespace datadog::shared::nativeloader

0 comments on commit 8d9af1c

Please sign in to comment.