Skip to content

Commit 27b6beb

Browse files
authored
[Profiler] Change profiler to use the libdatadog dynamic library instead (#6301)
1 parent d6cb804 commit 27b6beb

File tree

13 files changed

+128
-68
lines changed

13 files changed

+128
-68
lines changed

build/cmake/FindLibdatadog.cmake

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,28 @@ endif()
3535

3636
set(LIBDATADOG_BASE_DIR ${libdatadog-${LIBDATADOG_VERSION}_SOURCE_DIR})
3737

38-
add_library(libdatadog-lib STATIC IMPORTED)
38+
add_library(libdatadog-lib SHARED IMPORTED)
3939

4040
set_target_properties(libdatadog-lib PROPERTIES
4141
INTERFACE_INCLUDE_DIRECTORIES ${LIBDATADOG_BASE_DIR}/include
42-
IMPORTED_LOCATION ${LIBDATADOG_BASE_DIR}/lib/libdatadog_profiling.a
42+
IMPORTED_LOCATION ${LIBDATADOG_BASE_DIR}/lib/libdatadog_profiling.so
4343
)
4444

4545
add_dependencies(libdatadog-lib libdatadog-${LIBDATADOG_VERSION})
46+
47+
# Override target_link_libraries
48+
function(target_link_libraries target)
49+
# Call the original target_link_libraries
50+
_target_link_libraries(${ARGV})
51+
52+
if("libdatadog-lib" IN_LIST ARGN)
53+
add_custom_command(
54+
TARGET ${target}
55+
POST_BUILD
56+
COMMAND ${CMAKE_COMMAND} -E copy_if_different
57+
$<TARGET_FILE:libdatadog-lib>
58+
$<TARGET_FILE_DIR:${target}>
59+
COMMENT "Copying libdatadog to ${target} output directory"
60+
)
61+
endif()
62+
endfunction()

profiler/Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@
191191
<SHARED-LIB-INCLUDES>$(SHARED-LIB-PATH)fmt\include;$(SHARED-LIB-PATH)spdlog\include</SHARED-LIB-INCLUDES>
192192
<!-- VCPKG setup -->
193193
<VcpkgEnableManifest>true</VcpkgEnableManifest>
194-
<VcpkgUseStatic>true</VcpkgUseStatic>
194+
<VcpkgUseStatic>false</VcpkgUseStatic>
195195
<VcpkgTriplet>$(Platform)-windows</VcpkgTriplet>
196196
</PropertyGroup>
197197

profiler/Directory.Build.targets

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,40 @@
1212
<AdditionalDependencies>$(LibDatadogDependencies);%(AdditionalDependencies)</AdditionalDependencies>
1313
</Link>
1414
</ItemDefinitionGroup>
15+
16+
<PropertyGroup>
17+
<TopLevelDeployDirectoryBase Condition="'$(DeployToMonitoringHome)' == 'True'">$(EnlistmentRoot)\shared\bin\monitoring-home</TopLevelDeployDirectoryBase>
18+
<TopLevelDeployDirectoryBase Condition="'$(DeployToMonitoringHome)' != 'True'">$(BuildOutputRoot)\DDProf-Deploy</TopLevelDeployDirectoryBase>
19+
20+
<!-- In Linux case, we test against $(Platform), while on Windows case, we test against $(PlatformShortName). The reason is that for Windows, for -->
21+
<!-- 64bit, $(PlatformShortName) == to x64. But on Linux, $(PlatformShortName) == x86_64. -->
22+
<DDPlatform Condition=" '$(PlatformShortName)' != '' AND $([MSBuild]::IsOSPlatform('Windows'))">win-$(PlatformShortName)</DDPlatform>
23+
<DDPlatform Condition=" '$(PlatformShortName)' == '' AND $([MSBuild]::IsOSPlatform('Windows'))">win-unknown</DDPlatform>
24+
<DDPlatform Condition=" '$(Platform)' != '' AND $([MSBuild]::IsOSPlatform('Linux')) ">linux-$(Platform)</DDPlatform>
25+
<DDPlatform Condition=" '$(Platform)' == '' AND $([MSBuild]::IsOSPlatform('Linux')) ">linux-unknown</DDPlatform>
26+
27+
<DeployDirectoryBase >$(TopLevelDeployDirectoryBase)\$(DDPlatform)</DeployDirectoryBase>
28+
</PropertyGroup>
29+
30+
<PropertyGroup>
31+
<NativeWindowsDeployFilesSrcDir>$(BaseOutputPath)\$(ConfigBasedRelativeOutputPath)\profiler\src\ProfilerEngine\Datadog.Profiler.Native.Windows</NativeWindowsDeployFilesSrcDir>
32+
<NativeLinuxDeployFilesSrcDir>$(BaseOutputPath)\$(ConfigBasedRelativeOutputPath)\profiler\src\ProfilerEngine\Datadog.Profiler.Native.Linux</NativeLinuxDeployFilesSrcDir>
33+
</PropertyGroup>
34+
35+
<Target Name="CopyVcpkgPDBs" AfterTargets="Build">
36+
<Message Text="[PrepareDeployDirectory] NativeWindowsDeployFilesSrcDir: '$(NativeWindowsDeployFilesSrcDir)'" Importance="high" />
37+
<Message Text="[PrepareDeployDirectory] NativeLinuxDeployFilesSrcDir: '$(NativeLinuxDeployFilesSrcDir)'" Importance="high" />
38+
<ItemGroup>
39+
<VcpkgPDBs Condition="'$(Configuration)'=='Release'" Include="$(VcpkgInstalledDir)\$(VcpkgTriplet)\bin\*.pdb" />
40+
<VcpkgPDBs Condition="'$(Configuration)'=='Debug'" Include="$(VcpkgInstalledDir)\$(VcpkgTriplet)\debug\bin\*.pdb" />
41+
</ItemGroup>
42+
<Copy SourceFiles="@(VcpkgPDBs)" DestinationFiles="@(VcpkgPDBs->'$(DeployDirectoryBase)\%(RecursiveDir)%(Filename)%(Extension)')" />
43+
<Copy SourceFiles="@(VcpkgPDBs)" DestinationFiles="@(VcpkgPDBs->'$(NativeWindowsDeployFilesSrcDir)\%(Filename)%(Extension)')" />
44+
</Target>
45+
<Target Name="CleanVcpkPDBs" AfterTargets="Clean">
46+
<ItemGroup>
47+
<PDBsToDelete Include="$(NativeWindowsDeployFilesSrcDir)\*.pdb" />
48+
</ItemGroup>
49+
<Delete Files="@(PDBsToDelete)" />
50+
</Target>
1551
</Project>

profiler/src/ProfilerEngine/Datadog.Profiler.Native.Linux/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,5 @@ target_link_options(${PROFILER_SHARED_LIB_NAME} PRIVATE
143143
# Define linker libraries
144144
target_link_libraries(${PROFILER_SHARED_LIB_NAME}
145145
-Wl,--whole-archive $<TARGET_FILE:${PROFILER_STATIC_LIB_NAME}> -Wl,--no-whole-archive
146+
-Wl,-rpath,'$ORIGIN'
146147
${PROFILER_STATIC_LIB_NAME})

profiler/src/ProfilerEngine/Datadog.Profiler.Native/Datadog.Profiler.Native.vcxproj.filters

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,4 @@
756756
<Filter>Network</Filter>
757757
</ClCompile>
758758
</ItemGroup>
759-
<ItemGroup>
760-
<None Include="packages.config" />
761-
</ItemGroup>
762759
</Project>

profiler/src/ProfilerEngine/Directory.Build.targets

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,8 @@
2828
</AssemblyAttribute>
2929
</ItemGroup>
3030
</Target>
31-
3231
<Target Name="PrepareDeployDirectory" AfterTargets="Build">
3332

34-
<PropertyGroup>
35-
<TopLevelDeployDirectoryBase Condition="'$(DeployToMonitoringHome)' == 'True'">$(EnlistmentRoot)\shared\bin\monitoring-home</TopLevelDeployDirectoryBase>
36-
<TopLevelDeployDirectoryBase Condition="'$(DeployToMonitoringHome)' != 'True'">$(BuildOutputRoot)\DDProf-Deploy</TopLevelDeployDirectoryBase>
37-
38-
<!-- In Linux case, we test against $(Platform), while on Windows case, we test against $(PlatformShortName). The reason is that for Windows, for -->
39-
<!-- 64bit, $(PlatformShortName) == to x64. But on Linux, $(PlatformShortName) == x86_64. -->
40-
<DDPlatform Condition=" '$(PlatformShortName)' != '' AND $([MSBuild]::IsOSPlatform('Windows'))">win-$(PlatformShortName)</DDPlatform>
41-
<DDPlatform Condition=" '$(PlatformShortName)' == '' AND $([MSBuild]::IsOSPlatform('Windows'))">win-unknown</DDPlatform>
42-
<DDPlatform Condition=" '$(Platform)' != '' AND $([MSBuild]::IsOSPlatform('Linux')) ">linux-$(Platform)</DDPlatform>
43-
<DDPlatform Condition=" '$(Platform)' == '' AND $([MSBuild]::IsOSPlatform('Linux')) ">linux-unknown</DDPlatform>
44-
45-
<DeployDirectoryBase >$(TopLevelDeployDirectoryBase)\$(DDPlatform)</DeployDirectoryBase>
46-
</PropertyGroup>
47-
48-
<PropertyGroup>
49-
<NativeWindowsDeployFilesSrcDir>$(BaseOutputPath)\$(ConfigBasedRelativeOutputPath)\profiler\src\ProfilerEngine\Datadog.Profiler.Native.Windows</NativeWindowsDeployFilesSrcDir>
50-
<NativeLinuxDeployFilesSrcDir>$(BaseOutputPath)\$(ConfigBasedRelativeOutputPath)\profiler\src\ProfilerEngine\Datadog.Profiler.Native.Linux</NativeLinuxDeployFilesSrcDir>
51-
52-
</PropertyGroup>
53-
5433
<ItemGroup>
5534
<NativeDeployFiles Include="$(NativeWindowsDeployFilesSrcDir)\*.dll" />
5635
<NativeDeployFiles Include="$(NativeWindowsDeployFilesSrcDir)\*.pdb" />

profiler/test/Datadog.Profiler.Native.Tests/Datadog.Profiler.Native.Tests.vcxproj.filters

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,6 @@
207207
<ClInclude Include="RuntimeIdStoreHelper.h">
208208
<Filter>Helpers</Filter>
209209
</ClInclude>
210-
<ClInclude Include="ThreadsCpuManagerHelper.h">
211-
<Filter>Helpers</Filter>
212-
</ClInclude>
213210
<ClInclude Include="RuntimeInfoHelper.h">
214211
<Filter>Helpers</Filter>
215212
</ClInclude>
@@ -222,4 +219,4 @@
222219
<ItemGroup>
223220
<ResourceCompile Include="Resources.rc" />
224221
</ItemGroup>
225-
</Project>
222+
</Project>

profiler/test/Datadog.Profiler.Native.Tests/packages.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
33
<package id="gmock" version="1.11.0" targetFramework="native" />
44
<package id="Microsoft.googletest.v140.windesktop.msvcstl.static.rt-static" version="1.8.1.7" targetFramework="native" />

shared/src/msi-installer/Product.wxs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
<ComponentGroupRef Id="Shared.EnvironmentVariables.IIS"/>
4444
<ComponentGroupRef Id="Shared.Files" />
4545
<ComponentGroupRef Id="Shared.Files.NativeLoader.32"/> <!-- 32-bit native files are always included, even in 64-bit builds -->
46+
<ComponentGroupRef Id="Shared.Files.Libdatadog.32"/>
4647

4748
<ComponentGroupRef Id="ContinuousProfiler.EnvironmentVariables.Machine"/>
4849
<ComponentGroupRef Id="ContinuousProfiler.Files"/>
@@ -62,6 +63,7 @@
6263
<ComponentGroupRef Id="dd_dotnet.cmd"/>
6364
<ComponentGroupRef Id="dd_dotnet.exe"/>
6465
<ComponentGroupRef Id="Shared.Files.NativeLoader.64"/>
66+
<ComponentGroupRef Id="Shared.Files.Libdatadog.64"/>
6567
<ComponentGroupRef Id="ContinuousProfiler.Files.Native.64"/>
6668
<ComponentGroupRef Id="Tracer.Files.Native.64"/>
6769
<?endif ?>

shared/src/msi-installer/shared/Files.wxs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,27 @@
3737
</Component>
3838
</ComponentGroup>
3939

40+
<?if $(var.Win64) = yes ?>
41+
<ComponentGroup Id="Shared.Files.Libdatadog.64" Directory="INSTALLFOLDER.win_x64">
42+
<Component Win64="yes">
43+
<File Id="libdatadog"
44+
Source="$(var.MonitoringHomeDirectory)\win-x64\datadog_profiling_ffi.dll"
45+
Checksum="yes">
46+
</File>
47+
</Component>
48+
</ComponentGroup>
49+
50+
<?endif ?>
51+
52+
<!-- Always install the 32-bit binaries, even for the 64-bit installer -->
53+
<ComponentGroup Id="Shared.Files.Libdatadog.32" Directory="INSTALLFOLDER.win_x86">
54+
<Component Win64="$(var.Win64)">
55+
<File Id="libdatadog.32"
56+
Source="$(var.MonitoringHomeDirectory)\win-x86\datadog_profiling_ffi.dll"
57+
Checksum="yes">
58+
</File>
59+
</Component>
60+
</ComponentGroup>
61+
4062
</Fragment>
4163
</Wix>

shared/src/native-src/dynamic_library_base.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ bool DynamicLibraryBase::Load()
6161
_logger->Debug("Load: ", _filePath);
6262

6363
#if _WIN32
64-
_instance = LoadLibrary(::shared::ToWSTRING(_filePath).c_str());
64+
_instance = LoadLibraryEx(::shared::ToWSTRING(_filePath).c_str(),
65+
NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
6566
if (_instance == NULL)
6667
{
6768
LPVOID msgBuffer;

tracer/build/_build/Build.Profiler.Steps.cs

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using System.Threading.Tasks;
2121
using DiffMatchPatch;
2222
using Logger = Serilog.Log;
23+
using System.Runtime.CompilerServices;
2324

2425
partial class Build
2526
{
@@ -390,7 +391,7 @@ async Task DownloadAndExtractVcpkg(AbsolutePath destinationFolder)
390391
var sourceDir = ProfilerDeployDirectory / arch;
391392
EnsureExistingDirectory(MonitoringHomeDirectory / arch);
392393

393-
var files = new[] { "Datadog.Profiler.Native.so" };
394+
var files = new[] { "Datadog.Profiler.Native.so", "libdatadog_profiling.so" };
394395
foreach (var file in files)
395396
{
396397
var source = sourceDir / file;
@@ -426,16 +427,20 @@ async Task DownloadAndExtractVcpkg(AbsolutePath destinationFolder)
426427
.After(CompileProfilerNativeSrc)
427428
.Executes(() =>
428429
{
429-
foreach (var architecture in ArchitecturesForPlatformForProfiler)
430+
var files = new[] { "Datadog.Profiler.Native", "datadog_profiling_ffi" };
431+
foreach (var file in files)
430432
{
431-
var sourceDir = ProfilerDeployDirectory / $"win-{architecture}";
432-
var source = sourceDir / "Datadog.Profiler.Native.dll";
433-
var dest = MonitoringHomeDirectory / $"win-{architecture}";
434-
CopyFileToDirectory(source, dest, FileExistsPolicy.Overwrite);
435-
436-
source = sourceDir / "Datadog.Profiler.Native.pdb";
437-
dest = SymbolsDirectory / $"win-{architecture}" / Path.GetFileName(source);
438-
CopyFile(source, dest, FileExistsPolicy.Overwrite);
433+
foreach (var architecture in ArchitecturesForPlatformForProfiler)
434+
{
435+
var sourceDir = ProfilerDeployDirectory / $"win-{architecture}";
436+
var source = sourceDir / $"{file}.dll";
437+
var dest = MonitoringHomeDirectory / $"win-{architecture}";
438+
CopyFileToDirectory(source, dest, FileExistsPolicy.Overwrite);
439+
440+
source = sourceDir / $"{file}.pdb";
441+
dest = SymbolsDirectory / $"win-{architecture}" / Path.GetFileName(source);
442+
CopyFile(source, dest, FileExistsPolicy.Overwrite);
443+
}
439444
}
440445
});
441446

@@ -953,22 +958,31 @@ void RunCppCheck(string projectName, MSBuildTargetPlatform platform)
953958
.Executes(() =>
954959
{
955960
var (arch, extension) = GetUnixArchitectureAndExtension();
956-
var dest = ProfilerDeployDirectory / arch / $"{FileNames.NativeProfiler}.{extension}";
957961

958-
// The profiler has a different minimum glibc version to the tracer.
959-
// The _overall_ minimum is the highest of the two, but as we don't
960-
// currently enable the profiler on ARM64, we take the .NET runtime's minimum
961-
// glibc as our actual minimum in practice. Before we can enable the profiler
962-
// on arm64 we must first ensure we bring this glibc version down to 2.23.
962+
// If we need to increase this version on arm64 later, that is ok as long
963+
// as it doesn't go above 2.23. Just update the version below. We must
964+
// NOT increase it beyond 2.23, or increase the version on x64.
963965
//
964966
// See also the ValidateNativeTracerGlibcCompatibility Nuke task and the checks
965967
// in shared/src/Datadog.Trace.ClrProfiler.Native/cor_profiler.cpp#L1279
966-
var expectedGlibcVersion = IsArm64
967-
? new Version(2, 28)
968-
: new Version(2, 17);
969968

970-
ValidateNativeLibraryGlibcCompatibility(dest, expectedGlibcVersion);
969+
// On Alpine/aarch64, libdatadog requires those two symbols (they are defined as weak with no implementation).
970+
// Since the CLR requires them too, it seems safe to accept them.
971+
// For information, those symbols comes from libgcc and are exposed for compatibility
972+
var libdatadogAllowedSymbols = IsArm64 && IsAlpine ? new[] { "__register_frame_info@GLIBC_2.0", "__deregister_frame_info@GLIBC_2.0" } : null;
973+
var filesAndVersion = new List<Tuple<string, Version, IEnumerable<string>>>
974+
{
975+
new(FileNames.NativeProfiler, IsArm64 ? new Version(2, 18) : new Version(2, 17), null),
976+
new("libdatadog_profiling", IsArm64 ? new Version(2, 17) : new Version(2, 16), libdatadogAllowedSymbols)
977+
};
978+
979+
foreach (var (file, expectedGlibcVersion, allowedSymbols) in filesAndVersion)
980+
{
981+
var dest = ProfilerDeployDirectory / arch / $"{file}.{extension}";
982+
ValidateNativeLibraryGlibcCompatibility(dest, expectedGlibcVersion, allowedSymbols);
983+
}
971984
});
985+
972986
enum SanitizerKind
973987
{
974988
None,

tracer/build/_build/Build.Shared.Steps.cs

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -278,12 +278,6 @@ partial class Build
278278
var (arch, extension) = GetUnixArchitectureAndExtension();
279279
var dest = MonitoringHomeDirectory / arch / $"{NativeTracerProject.Name}.{extension}";
280280

281-
// The profiler has a different minimum glibc version to the tracer.
282-
// The _overall_ minimum is the highest of the two, but as we don't
283-
// currently enable the profiler on ARM64, we take the .NET runtime's minimum
284-
// glibc as our actual minimum in practice. Before we can enable the profiler
285-
// on arm64 we must first ensure we bring this glibc version down to 2.23.
286-
//
287281
// If we need to increase this version on arm64 later, that is ok as long
288282
// as it doesn't go above 2.23. Just update the version below. We must
289283
// NOT increase it beyond 2.23, or increase the version on x64.
@@ -297,24 +291,24 @@ partial class Build
297291
ValidateNativeLibraryGlibcCompatibility(dest, expectedGlibcVersion);
298292
});
299293

300-
void ValidateNativeLibraryGlibcCompatibility(AbsolutePath libraryPath, Version expectedGlibcVersion)
294+
void ValidateNativeLibraryGlibcCompatibility(AbsolutePath libraryPath, Version expectedGlibcVersion, IEnumerable<string> allowedSymbols = null)
301295
{
302296
var filename = Path.GetFileNameWithoutExtension(libraryPath);
303-
var glibcVersion = FindMinimumGlibcVersion(libraryPath);
297+
var glibcVersion = FindMaxGlibcVersion(libraryPath, allowedSymbols);
304298

305-
Logger.Information("Minimum required glibc version for {Filename} is {GlibcVersion}", filename, glibcVersion);
299+
Logger.Information("Maximum required glibc version for {Filename} is {GlibcVersion}", filename, glibcVersion);
306300

307301
if (IsAlpine && glibcVersion is not null)
308302
{
309303
throw new Exception($"Alpine build of {filename} should not have glibc symbols in the binary, but found {glibcVersion}");
310304
}
311305
else if (!IsAlpine && glibcVersion != expectedGlibcVersion)
312306
{
313-
throw new Exception($"{filename} should have a minimum required glibc version of {expectedGlibcVersion} but has {glibcVersion}");
307+
throw new Exception($"{filename} should have a maximum required glibc version of {expectedGlibcVersion} but has {glibcVersion}");
314308
}
315309
}
316310

317-
Version FindMinimumGlibcVersion(AbsolutePath libraryPath)
311+
Version FindMaxGlibcVersion(AbsolutePath libraryPath, IEnumerable<string> allowedSymbols)
318312
{
319313
var output = Nm.Value($"--with-symbol-versions -D {libraryPath} ").Select(x => x.Text).ToList();
320314

@@ -336,11 +330,11 @@ Version FindMinimumGlibcVersion(AbsolutePath libraryPath)
336330
// U __newlocale@GLIBC_2.17
337331
//
338332
// We only care about the Undefined symbols that are in glibc
333+
// In this example, we will return 2.18
339334

340335
return output
341-
.Where(x=>x.Contains("@GLIBC_"))
342-
.Select(x=> System.Version.Parse(x.Substring(x.IndexOf("@GLIBC_") + 7)))
343-
.OrderDescending()
344-
.FirstOrDefault();
336+
.Where(x => x.Contains("@GLIBC_") && allowedSymbols?.Any(y => x.Contains(y)) != true)
337+
.Select(x => System.Version.Parse(x.Substring(x.IndexOf("@GLIBC_") + 7)))
338+
.Max();
345339
}
346340
}

0 commit comments

Comments
 (0)