From fe1cb133b4e478654eaef3ff72067bc263be1d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vandon?= Date: Fri, 13 Dec 2024 11:58:48 +0100 Subject: [PATCH 01/12] support relative path in DD_DOTNET_TRACER_HOME --- .../Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs | 2 +- .../Startup.NetFramework.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs index 8bc690f88360..a555ef651997 100644 --- a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs +++ b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs @@ -77,7 +77,7 @@ private static Assembly ResolveAssembly(string name) // WARNING: Logs must not be added _before_ we check for the above bail-out conditions StartupLogger.Debug("Assembly Resolve event received for: {0}", name); - var path = Path.Combine(ManagedProfilerDirectory, $"{assemblyName.Name}.dll"); + var path = new FileInfo(Path.Combine(ManagedProfilerDirectory, $"{assemblyName.Name}.dll")).FullName; StartupLogger.Debug("Looking for: {0}", path); if (IsDatadogAssembly(path, out var cachedAssembly)) diff --git a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs index 5cebb1be71bc..e1164a1d5ab9 100644 --- a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs +++ b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs @@ -59,7 +59,7 @@ private static Assembly ResolveAssembly(string name) } // WARNING: Logs must not be added _before_ we check for the above bail-out conditions - var path = string.IsNullOrEmpty(ManagedProfilerDirectory) ? $"{assemblyName.Name}.dll" : Path.Combine(ManagedProfilerDirectory, $"{assemblyName.Name}.dll"); + var path = new FileInfo(string.IsNullOrEmpty(ManagedProfilerDirectory) ? $"{assemblyName.Name}.dll" : Path.Combine(ManagedProfilerDirectory, $"{assemblyName.Name}.dll")).FullName; StartupLogger.Debug(" Looking for: '{0}'", path); if (File.Exists(path)) From 59d439b3389e047ed38cbc7f52708925a1e01370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vandon?= Date: Tue, 31 Dec 2024 13:58:24 +0100 Subject: [PATCH 02/12] Update tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs Co-authored-by: Andrew Lock --- .../Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs index a555ef651997..b4bb9b35d7bb 100644 --- a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs +++ b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs @@ -77,7 +77,7 @@ private static Assembly ResolveAssembly(string name) // WARNING: Logs must not be added _before_ we check for the above bail-out conditions StartupLogger.Debug("Assembly Resolve event received for: {0}", name); - var path = new FileInfo(Path.Combine(ManagedProfilerDirectory, $"{assemblyName.Name}.dll")).FullName; + var path = Path.GetFullPath(Path.Combine(ManagedProfilerDirectory, $"{assemblyName.Name}.dll")); StartupLogger.Debug("Looking for: {0}", path); if (IsDatadogAssembly(path, out var cachedAssembly)) From f994b1bf27298e15d5dbb311e1b57574b562691c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vandon?= Date: Tue, 31 Dec 2024 13:58:35 +0100 Subject: [PATCH 03/12] Update tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs Co-authored-by: Andrew Lock --- .../Startup.NetFramework.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs index e1164a1d5ab9..75c24d812abd 100644 --- a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs +++ b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs @@ -59,7 +59,7 @@ private static Assembly ResolveAssembly(string name) } // WARNING: Logs must not be added _before_ we check for the above bail-out conditions - var path = new FileInfo(string.IsNullOrEmpty(ManagedProfilerDirectory) ? $"{assemblyName.Name}.dll" : Path.Combine(ManagedProfilerDirectory, $"{assemblyName.Name}.dll")).FullName; + var path = Path.GetFullPath(string.IsNullOrEmpty(ManagedProfilerDirectory) ? $"{assemblyName.Name}.dll" : Path.Combine(ManagedProfilerDirectory, $"{assemblyName.Name}.dll")); StartupLogger.Debug(" Looking for: '{0}'", path); if (File.Exists(path)) From d87cfa1a56c021bef42574929cf9e612b4e65633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vandon?= Date: Thu, 2 Jan 2025 12:44:17 +0100 Subject: [PATCH 04/12] get full path earlier --- .../Startup.NetCore.cs | 4 ++-- .../Startup.NetFramework.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs index b4bb9b35d7bb..7c4ad9e0c749 100644 --- a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs +++ b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs @@ -33,7 +33,7 @@ private static string ResolveManagedProfilerDirectory() } var tracerHomeDirectory = ReadEnvironmentVariable("DD_DOTNET_TRACER_HOME") ?? string.Empty; - var fullPath = Path.Combine(tracerHomeDirectory, tracerFrameworkDirectory); + var fullPath = Path.GetFullPath(Path.Combine(tracerHomeDirectory, tracerFrameworkDirectory)); if (!Directory.Exists(fullPath)) { @@ -77,7 +77,7 @@ private static Assembly ResolveAssembly(string name) // WARNING: Logs must not be added _before_ we check for the above bail-out conditions StartupLogger.Debug("Assembly Resolve event received for: {0}", name); - var path = Path.GetFullPath(Path.Combine(ManagedProfilerDirectory, $"{assemblyName.Name}.dll")); + var path = Path.Combine(ManagedProfilerDirectory, $"{assemblyName.Name}.dll"); StartupLogger.Debug("Looking for: {0}", path); if (IsDatadogAssembly(path, out var cachedAssembly)) diff --git a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs index 75c24d812abd..f58621331f0a 100644 --- a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs +++ b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs @@ -19,7 +19,7 @@ public partial class Startup private static string ResolveManagedProfilerDirectory() { var tracerHomeDirectory = ReadEnvironmentVariable("DD_DOTNET_TRACER_HOME") ?? string.Empty; - var fullPath = Path.Combine(tracerHomeDirectory, "net461"); + var fullPath = Path.GetFullPath(Path.Combine(tracerHomeDirectory, "net461")); if (!Directory.Exists(fullPath)) { StartupLogger.Log($"The tracer home directory cannot be found at '{fullPath}', based on the DD_DOTNET_TRACER_HOME value '{tracerHomeDirectory}'"); @@ -59,7 +59,7 @@ private static Assembly ResolveAssembly(string name) } // WARNING: Logs must not be added _before_ we check for the above bail-out conditions - var path = Path.GetFullPath(string.IsNullOrEmpty(ManagedProfilerDirectory) ? $"{assemblyName.Name}.dll" : Path.Combine(ManagedProfilerDirectory, $"{assemblyName.Name}.dll")); + var path = string.IsNullOrEmpty(ManagedProfilerDirectory) ? $"{assemblyName.Name}.dll" : Path.Combine(ManagedProfilerDirectory, $"{assemblyName.Name}.dll"); StartupLogger.Debug(" Looking for: '{0}'", path); if (File.Exists(path)) From c8efb77237353ffebc008ad684e260081c1347aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vandon?= Date: Thu, 2 Jan 2025 15:04:43 +0100 Subject: [PATCH 05/12] add tests with relative paths --- .../InstrumentationTests.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs index e9f01d5e3958..cbd1b82c15ae 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs @@ -130,6 +130,35 @@ public async Task InstrumentsDotNetTest() Task RunDotnet(string arguments) => RunDotnetCommand(workingDir, agent, arguments); } + + [SkippableFact] + [Trait("RunOnWindows", "True")] + public async Task WhenUsingRelativeTracerHome_InstrumentsApp() + { + SetEnvironmentVariable("DD_INTERNAL_WAIT_FOR_DEBUGGER_ATTACH", "1"); + var path = Path.GetRelativePath(EnvironmentHelper.GetSampleApplicationOutputDirectory(), EnvironmentHelper.MonitoringHome); + SetEnvironmentVariable("DD_DOTNET_TRACER_HOME", path); + Output.WriteLine("Using DD_DOTNET_TRACER_HOME " + path); + using var agent = EnvironmentHelper.GetMockAgent(useTelemetry: true); + using var processResult = await RunSampleAndWaitForExit(agent, "traces 1"); + agent.Spans.Should().NotBeEmpty(); + agent.Telemetry.Should().NotBeEmpty(); + } + + [SkippableFact] + [Trait("RunOnWindows", "True")] + public async Task WhenUsingPathWithDotsInInTracerHome_InstrumentsApp() + { + SetEnvironmentVariable("DD_INTERNAL_WAIT_FOR_DEBUGGER_ATTACH", "1"); + // not using Path.Combine here because it resolves the .. and we want it in the path + var path = EnvironmentHelper.MonitoringHome + "/../" + Path.GetFileName(EnvironmentHelper.MonitoringHome); + Output.WriteLine("Using DD_DOTNET_TRACER_HOME " + path); + SetEnvironmentVariable("DD_DOTNET_TRACER_HOME", path); + using var agent = EnvironmentHelper.GetMockAgent(useTelemetry: true); + using var processResult = await RunSampleAndWaitForExit(agent, "traces 1"); + agent.Spans.Should().NotBeEmpty(); + agent.Telemetry.Should().NotBeEmpty(); + } #endif #if NETCOREAPP && !NETCOREAPP3_1_OR_GREATER From af46a28927b1d356e702d67001d5906f721caaac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vandon?= Date: Thu, 2 Jan 2025 15:57:46 +0100 Subject: [PATCH 06/12] Update tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs Co-authored-by: Andrew Lock --- .../InstrumentationTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs index cbd1b82c15ae..ed6010d4491b 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs @@ -130,6 +130,7 @@ public async Task InstrumentsDotNetTest() Task RunDotnet(string arguments) => RunDotnetCommand(workingDir, agent, arguments); } +#endif [SkippableFact] [Trait("RunOnWindows", "True")] From 7de21968975ff91bac23a6e2366b2b9d90661b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vandon?= Date: Thu, 2 Jan 2025 15:58:58 +0100 Subject: [PATCH 07/12] remove endif --- .../InstrumentationTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs index ed6010d4491b..348c8a530553 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs @@ -160,7 +160,6 @@ public async Task WhenUsingPathWithDotsInInTracerHome_InstrumentsApp() agent.Spans.Should().NotBeEmpty(); agent.Telemetry.Should().NotBeEmpty(); } -#endif #if NETCOREAPP && !NETCOREAPP3_1_OR_GREATER [SkippableFact] From bfd069738ac34c69f93b751a214d23e39d61e7a7 Mon Sep 17 00:00:00 2001 From: Andrew Lock Date: Fri, 3 Jan 2025 12:31:51 +0000 Subject: [PATCH 08/12] Add PathUtil.GetRelativePath helper (for .NET Framework) --- .../Helpers/PathUtil.cs | 266 ++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Helpers/PathUtil.cs diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Helpers/PathUtil.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Helpers/PathUtil.cs new file mode 100644 index 000000000000..6e47dcc514d7 --- /dev/null +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/Helpers/PathUtil.cs @@ -0,0 +1,266 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +using System; +using System.IO; +using System.Runtime.CompilerServices; +using System.Text; + +namespace Datadog.Trace.ClrProfiler.IntegrationTests; + +public class PathUtil +{ + /// + /// Create a relative path from one path to another. Paths will be resolved before calculating the difference. + /// Default path comparison for the active platform will be used (OrdinalIgnoreCase for Windows or Mac, Ordinal for Unix). + /// + /// The source path the output should be relative to. This path is always considered to be a directory. + /// The destination path. + /// The relative path or if the paths don't share the same root. + /// Thrown if or is null or an empty string. + public static string GetRelativePath(string relativeTo, string path) +#if NETCOREAPP + => Path.GetRelativePath(relativeTo, path); +#else + { + const char directorySeparatorChar = '\\'; + const char altDirectorySeparatorChar = '/'; + const char volumeSeparatorChar = ':'; + + const string extendedDevicePathPrefix = @"\\?\"; + const string uncExtendedPathPrefix = @"\\?\UNC\"; + + // based on https://github.com/dotnet/runtime/blob/1d1bf92fcf43aa6981804dc53c5174445069c9e4/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs#L843 + var comparisonType = StringComparison.OrdinalIgnoreCase; // Windows only + relativeTo = Path.GetFullPath(relativeTo); + path = Path.GetFullPath(path); + + // Need to check if the roots are different- if they are we need to return the "to" path. + if (!AreRootsEqual(relativeTo, path, comparisonType)) + { + return path; + } + + var commonLength = GetCommonPathLength(relativeTo, path, ignoreCase: true); + + // If there is nothing in common they can't share the same root, return the "to" path as is. + if (commonLength == 0) + { + return path; + } + + // Trailing separators aren't significant for comparison + var relativeToLength = relativeTo.Length; + if (EndsInDirectorySeparator(relativeTo)) + { + relativeToLength--; + } + + var pathEndsInSeparator = EndsInDirectorySeparator(path); + var pathLength = path.Length; + if (pathEndsInSeparator) + { + pathLength--; + } + + // If we have effectively the same path, return "." + if (relativeToLength == pathLength && commonLength >= relativeToLength) + { + return "."; + } + + // We have the same root, we need to calculate the difference now using the + // common Length and Segment count past the length. + // + // Some examples: + // + // C:\Foo C:\Bar L3, S1 -> ..\Bar + // C:\Foo C:\Foo\Bar L6, S0 -> Bar + // C:\Foo\Bar C:\Bar\Bar L3, S2 -> ..\..\Bar\Bar + // C:\Foo\Foo C:\Foo\Bar L7, S1 -> ..\Bar + + var sb = new StringBuilder(); + sb.EnsureCapacity(Math.Max(relativeTo.Length, path.Length)); + + // Add parent segments for segments past the common on the "from" path + if (commonLength < relativeToLength) + { + sb.Append(".."); + + for (var i = commonLength + 1; i < relativeToLength; i++) + { + if (IsDirectorySeparator(relativeTo[i])) + { + sb.Append(directorySeparatorChar); + sb.Append(".."); + } + } + } + else if (IsDirectorySeparator(path[commonLength])) + { + // No parent segments and we need to eat the initial separator + // (C:\Foo C:\Foo\Bar case) + commonLength++; + } + + // Now add the rest of the "to" path, adding back the trailing separator + var differenceLength = pathLength - commonLength; + if (pathEndsInSeparator) + { + differenceLength++; + } + + if (differenceLength > 0) + { + if (sb.Length > 0) + { + sb.Append(directorySeparatorChar); + } + + sb.Append(path, commonLength, differenceLength); + } + + return sb.ToString(); + + static int GetCommonPathLength(string first, string second, bool ignoreCase) + { + var commonChars = EqualStartingCharacterCount(first, second, ignoreCase: ignoreCase); + + // If nothing matches + if (commonChars == 0) + { + return commonChars; + } + + // Or we're a full string and equal length or match to a separator + if (commonChars == first.Length + && (commonChars == second.Length || IsDirectorySeparator(second[commonChars]))) + { + return commonChars; + } + + if (commonChars == second.Length && IsDirectorySeparator(first[commonChars])) + { + return commonChars; + } + + // It's possible we matched somewhere in the middle of a segment e.g. C:\Foodie and C:\Foobar. + while (commonChars > 0 && !IsDirectorySeparator(first[commonChars - 1])) + { + commonChars--; + } + + return commonChars; + } + + static int EqualStartingCharacterCount(string first, string second, bool ignoreCase) + { + if (string.IsNullOrEmpty(first) || string.IsNullOrEmpty(second)) + { + return 0; + } + + var commonChars = 0; + var f = 0; + var s = 0; + + var l = first[f]; + var r = second[s]; + var leftEnd = first.Length; + var rightEnd = second.Length; + + while (l < leftEnd + && r < rightEnd + && (l == r || (ignoreCase && char.ToUpperInvariant(l) == char.ToUpperInvariant(r)))) + { + commonChars++; + l++; + r++; + } + + return commonChars; + } + + static bool AreRootsEqual(string first, string second, StringComparison comparisonType) + { + var firstRootLength = GetRootLength(first); + var secondRootLength = GetRootLength(second); + + return firstRootLength == secondRootLength + && string.Compare( + strA: first, + indexA: 0, + strB: second, + indexB: 0, + length: firstRootLength, + comparisonType: comparisonType) == 0; + } + + static int GetRootLength(string path) + { + var i = 0; + var volumeSeparatorLength = 2; // Length to the colon "C:" + var uncRootLength = 2; // Length to the start of the server name "\\" + + var extendedSyntax = path.StartsWith(extendedDevicePathPrefix); + var extendedUncSyntax = path.StartsWith(uncExtendedPathPrefix); + if (extendedSyntax) + { + // Shift the position we look for the root from to account for the extended prefix + if (extendedUncSyntax) + { + // "\\" -> "\\?\UNC\" + uncRootLength = uncExtendedPathPrefix.Length; + } + else + { + // "C:" -> "\\?\C:" + volumeSeparatorLength += extendedDevicePathPrefix.Length; + } + } + + if ((!extendedSyntax || extendedUncSyntax) && path.Length > 0 && IsDirectorySeparator(path[0])) + { + // UNC or simple rooted path (e.g. "\foo", NOT "\\?\C:\foo") + + i = 1; // Drive rooted (\foo) is one character + if (extendedUncSyntax || (path.Length > 1 && IsDirectorySeparator(path[1]))) + { + // UNC (\\?\UNC\ or \\), scan past the next two directory separators at most + // (e.g. to \\?\UNC\Server\Share or \\Server\Share\) + i = uncRootLength; + var n = 2; // Maximum separators to skip + while (i < path.Length && (!IsDirectorySeparator(path[i]) || --n > 0)) + { + i++; + } + } + } + else if (path.Length >= volumeSeparatorLength && + path[volumeSeparatorLength - 1] == volumeSeparatorChar) + { + // Path is at least longer than where we expect a colon, and has a colon (\\?\A:, A:) + // If the colon is followed by a directory separator, move past it + i = volumeSeparatorLength; + if (path.Length >= volumeSeparatorLength + 1 && IsDirectorySeparator(path[volumeSeparatorLength])) + { + i++; + } + } + + return i; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool IsDirectorySeparator(char c) + { + return c == directorySeparatorChar || c == altDirectorySeparatorChar; + } + + static bool EndsInDirectorySeparator(string path) + => path.Length > 0 && IsDirectorySeparator(path[path.Length - 1]); + } +#endif +} From 97c36fbba3aaf593f6e6958340209add7b5a0cf9 Mon Sep 17 00:00:00 2001 From: Andrew Lock Date: Fri, 3 Jan 2025 12:32:37 +0000 Subject: [PATCH 09/12] Record current directory when failing to load the tracer home in the managed loader for debugging purposes --- .../Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs | 2 +- .../Startup.NetFramework.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs index 7c4ad9e0c749..bebb9b738ae7 100644 --- a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs +++ b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetCore.cs @@ -37,7 +37,7 @@ private static string ResolveManagedProfilerDirectory() if (!Directory.Exists(fullPath)) { - StartupLogger.Log($"The tracer home directory cannot be found at '{fullPath}', based on the DD_DOTNET_TRACER_HOME value '{tracerHomeDirectory}'"); + StartupLogger.Log($"The tracer home directory cannot be found at '{fullPath}', based on the DD_DOTNET_TRACER_HOME value '{tracerHomeDirectory}' and current directory {Environment.CurrentDirectory}"); return null; } diff --git a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs index f58621331f0a..9b504c1e8131 100644 --- a/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs +++ b/tracer/src/Datadog.Trace.ClrProfiler.Managed.Loader/Startup.NetFramework.cs @@ -22,7 +22,7 @@ private static string ResolveManagedProfilerDirectory() var fullPath = Path.GetFullPath(Path.Combine(tracerHomeDirectory, "net461")); if (!Directory.Exists(fullPath)) { - StartupLogger.Log($"The tracer home directory cannot be found at '{fullPath}', based on the DD_DOTNET_TRACER_HOME value '{tracerHomeDirectory}'"); + StartupLogger.Log($"The tracer home directory cannot be found at '{fullPath}', based on the DD_DOTNET_TRACER_HOME value '{tracerHomeDirectory}' and current directory {Environment.CurrentDirectory}"); return null; } From 6f6e684464825d545bec07ff624b02708c6d8916 Mon Sep 17 00:00:00 2001 From: Andrew Lock Date: Fri, 3 Jan 2025 12:32:50 +0000 Subject: [PATCH 10/12] Fix integration tests --- .../InstrumentationTests.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs index 348c8a530553..3dcc7d5a34b9 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs @@ -137,9 +137,14 @@ public async Task InstrumentsDotNetTest() public async Task WhenUsingRelativeTracerHome_InstrumentsApp() { SetEnvironmentVariable("DD_INTERNAL_WAIT_FOR_DEBUGGER_ATTACH", "1"); - var path = Path.GetRelativePath(EnvironmentHelper.GetSampleApplicationOutputDirectory(), EnvironmentHelper.MonitoringHome); + // the working dir when we run the app is the _test_ project, not the app itself, so we need to be relative to that + // This is a perfect example of why we don't recommend using relative paths for these variables + var workingDir = Environment.CurrentDirectory; + var monitoringHome = EnvironmentHelper.MonitoringHome; + var path = PathUtil.GetRelativePath(workingDir, monitoringHome); + var effectivePath = Path.GetFullPath(Path.Combine(workingDir, path)); + Output.WriteLine($"Using DD_DOTNET_TRACER_HOME={path} with workingDir={workingDir} and monitoringHome={monitoringHome}, giving an effective path of {effectivePath}"); SetEnvironmentVariable("DD_DOTNET_TRACER_HOME", path); - Output.WriteLine("Using DD_DOTNET_TRACER_HOME " + path); using var agent = EnvironmentHelper.GetMockAgent(useTelemetry: true); using var processResult = await RunSampleAndWaitForExit(agent, "traces 1"); agent.Spans.Should().NotBeEmpty(); @@ -152,7 +157,7 @@ public async Task WhenUsingPathWithDotsInInTracerHome_InstrumentsApp() { SetEnvironmentVariable("DD_INTERNAL_WAIT_FOR_DEBUGGER_ATTACH", "1"); // not using Path.Combine here because it resolves the .. and we want it in the path - var path = EnvironmentHelper.MonitoringHome + "/../" + Path.GetFileName(EnvironmentHelper.MonitoringHome); + var path = Path.Combine(EnvironmentHelper.MonitoringHome, "..", Path.GetFileName(EnvironmentHelper.MonitoringHome)!); Output.WriteLine("Using DD_DOTNET_TRACER_HOME " + path); SetEnvironmentVariable("DD_DOTNET_TRACER_HOME", path); using var agent = EnvironmentHelper.GetMockAgent(useTelemetry: true); From cfdacf1b94a6c18a28ede4a88bcbbd6b33e0efa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vandon?= Date: Fri, 3 Jan 2025 14:31:35 +0100 Subject: [PATCH 11/12] remove debug env variable --- .../InstrumentationTests.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs index 3dcc7d5a34b9..a247768d46a6 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs @@ -136,7 +136,6 @@ public async Task InstrumentsDotNetTest() [Trait("RunOnWindows", "True")] public async Task WhenUsingRelativeTracerHome_InstrumentsApp() { - SetEnvironmentVariable("DD_INTERNAL_WAIT_FOR_DEBUGGER_ATTACH", "1"); // the working dir when we run the app is the _test_ project, not the app itself, so we need to be relative to that // This is a perfect example of why we don't recommend using relative paths for these variables var workingDir = Environment.CurrentDirectory; @@ -155,7 +154,6 @@ public async Task WhenUsingRelativeTracerHome_InstrumentsApp() [Trait("RunOnWindows", "True")] public async Task WhenUsingPathWithDotsInInTracerHome_InstrumentsApp() { - SetEnvironmentVariable("DD_INTERNAL_WAIT_FOR_DEBUGGER_ATTACH", "1"); // not using Path.Combine here because it resolves the .. and we want it in the path var path = Path.Combine(EnvironmentHelper.MonitoringHome, "..", Path.GetFileName(EnvironmentHelper.MonitoringHome)!); Output.WriteLine("Using DD_DOTNET_TRACER_HOME " + path); From e9e7a4b25f28a9e412f6d271917e506abc36269d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vandon?= Date: Fri, 3 Jan 2025 14:55:17 +0100 Subject: [PATCH 12/12] remove irrelevant comment --- .../InstrumentationTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs index a247768d46a6..a9c78ab5a090 100644 --- a/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs +++ b/tracer/test/Datadog.Trace.ClrProfiler.IntegrationTests/InstrumentationTests.cs @@ -154,7 +154,6 @@ public async Task WhenUsingRelativeTracerHome_InstrumentsApp() [Trait("RunOnWindows", "True")] public async Task WhenUsingPathWithDotsInInTracerHome_InstrumentsApp() { - // not using Path.Combine here because it resolves the .. and we want it in the path var path = Path.Combine(EnvironmentHelper.MonitoringHome, "..", Path.GetFileName(EnvironmentHelper.MonitoringHome)!); Output.WriteLine("Using DD_DOTNET_TRACER_HOME " + path); SetEnvironmentVariable("DD_DOTNET_TRACER_HOME", path);