Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix dlsym issue (#6048 -> v2) #6051

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .nuke/build.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@
"SignDlls",
"SignMsi",
"SummaryOfSnapshotChanges",
"TestNativeWrapper",
"UpdateChangeLog",
"UpdateSnapshots",
"UpdateSnapshotsFromBuild",
Expand Down Expand Up @@ -680,6 +681,7 @@
"SignDlls",
"SignMsi",
"SummaryOfSnapshotChanges",
"TestNativeWrapper",
"UpdateChangeLog",
"UpdateSnapshots",
"UpdateSnapshotsFromBuild",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@ void initLibrary(void)

// Bash provides its own version of the getenv/setenv functions
// Fetch the original ones and use those instead
char *(*real_getenv)(const char *) = (char *(*)(const char *))dlsym(RTLD_NEXT, "getenv");
int (*real_setenv)(const char *, const char *, int) = (int (*)(const char *, const char *, int))dlsym(RTLD_NEXT, "setenv");
char *(*real_getenv)(const char *) = __dd_dlsym(RTLD_NEXT, "getenv");
int (*real_setenv)(const char *, const char *, int) = __dd_dlsym(RTLD_NEXT, "setenv");

if (real_getenv == NULL || real_setenv == NULL)
{
Expand Down
79 changes: 79 additions & 0 deletions tracer/build/_build/Build.Profiler.Steps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Nuke.Common.Utilities;
using System.Collections;
using System.Threading.Tasks;
using DiffMatchPatch;
using Logger = Serilog.Log;

partial class Build
Expand Down Expand Up @@ -115,6 +116,84 @@ partial class Build
}
});

Target TestNativeWrapper => _ => _
.Unlisted()
.Description("Test that the Native wrapper symbols haven't changed")
.After(CompileProfilerNativeSrc)
.OnlyWhenStatic(() => IsLinux)
.Executes(() =>
{
var (arch, _) = GetUnixArchitectureAndExtension();
var libraryPath = ProfilerDeployDirectory / arch / LinuxApiWrapperLibrary;

var output = Nm.Value($"-D {libraryPath}").Select(x => x.Text).ToList();

// Gives output similar to this:
// 0000000000006bc8 D DdDotnetFolder
// 0000000000006bd0 D DdDotnetMuslFolder
// w _ITM_deregisterTMCloneTable
// w _ITM_registerTMCloneTable
// w __cxa_finalize
// w __deregister_frame_info
// U __errno_location
// U __tls_get_addr
// 0000000000002d1b T _fini
// 0000000000002d18 T _init
// 0000000000003d70 T accept
// 0000000000003e30 T accept4
// U access
//
// The types of symbols are:
// D: Data section symbol. These symbols are initialized global variables.
// w: Weak symbol. These symbols are weakly referenced and can be overridden by other symbols.
// U: Undefined symbol. These symbols are referenced in the file but defined elsewhere.
// T: Text section symbol. These symbols are functions or executable code.
// B: BSS (Block Started by Symbol) section symbol. These symbols are uninitialized global variables.
//
// We only care about the Undefined symbols - we don't want to accidentally add more of them

Logger.Debug("NM output: {Output}", string.Join(Environment.NewLine, output));

var symbols = output
.Select(x => x.Trim())
.Where(x => x.StartsWith("U "))
.Select(x => x.TrimStart("U "))
.OrderBy(x => x)
.ToList();


var received = string.Join(Environment.NewLine, symbols);
var verifiedPath = TestsDirectory / "snapshots" / $"native-wrapper-symbols-{UnixArchitectureIdentifier}.verified.txt";
var verified = File.Exists(verifiedPath)
? File.ReadAllText(verifiedPath)
: string.Empty;

Logger.Information("Comparing snapshot of Undefined symbols in the Native Wrapper library using {Path}...", verifiedPath);

var dmp = new diff_match_patch();
var diff = dmp.diff_main(verified, received);
dmp.diff_cleanupSemantic(diff);

var changedSymbols = diff
.Where(x => x.operation != Operation.EQUAL)
.Select(x => x.text.Trim())
.ToList();

if (changedSymbols.Count == 0)
{
Logger.Information("No changes found in Undefined symbols in the Native Wrapper library");
return;
}

PrintDiff(diff);

throw new Exception($"Found differences in undefined symbols ({string.Join(",", changedSymbols)}) in the Native Wrapper library. " +
"Verify that these changes are expected, and will not cause problems. " +
"Removing symbols is generally a safe operation, but adding them could cause crashes. " +
$"If the new symbols are safe to add, update the snapshot file at {verifiedPath} with the " +
"new values");
});

Target RunProfilerNativeUnitTestsLinux => _ => _
.Unlisted()
.Description("Run profiler native unit tests")
Expand Down
1 change: 1 addition & 0 deletions tracer/build/_build/Build.Steps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ partial class Build
[LazyPathExecutable(name: "ln")] readonly Lazy<Tool> HardLinkUtil;
[LazyPathExecutable(name: "cppcheck")] readonly Lazy<Tool> CppCheck;
[LazyPathExecutable(name: "run-clang-tidy")] readonly Lazy<Tool> RunClangTidy;
[LazyPathExecutable(name: "nm")] readonly Lazy<Tool> Nm;

//OSX Tools
readonly string[] OsxArchs = { "arm64", "x86_64" };
Expand Down
72 changes: 39 additions & 33 deletions tracer/build/_build/Build.Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -338,39 +338,7 @@ partial class Build
var diff = dmp.diff_main(File.ReadAllText(source.ToString().Replace("received", "verified")), File.ReadAllText(source));
dmp.diff_cleanupSemantic(diff);

foreach (var t in diff)
{
if (t.operation != Operation.EQUAL)
{
var str = DiffToString(t);
if (str.Contains(value: '\n'))
{
// if the diff is multiline, start with a newline so that all changes are aligned
// otherwise it's easy to miss the first line of the diff
str = "\n" + str;
}

Logger.Information(str);
}
}
}

string DiffToString(Diff diff)
{
if (diff.operation == Operation.EQUAL)
{
return string.Empty;
}

var symbol = diff.operation switch
{
Operation.DELETE => '-',
Operation.INSERT => '+',
_ => throw new Exception("Unknown value of the Option enum.")
};
// put the symbol at the beginning of each line to make diff clearer when whole blocks of text are missing
var lines = diff.text.TrimEnd(trimChar: '\n').Split(Environment.NewLine);
return string.Join(Environment.NewLine, lines.Select(l => symbol + l));
PrintDiff(diff);
}
});

Expand Down Expand Up @@ -527,4 +495,42 @@ private static string GetDefaultRuntimeIdentifier(bool isAlpine)

private static MSBuildTargetPlatform ARM64TargetPlatform = (MSBuildTargetPlatform)"ARM64";
private static MSBuildTargetPlatform ARM64ECTargetPlatform = (MSBuildTargetPlatform)"ARM64EC";

private static void PrintDiff(List<Diff> diff, bool printEqual = false)
{
foreach (var t in diff)
{
if (printEqual || t.operation != Operation.EQUAL)
{
var str = DiffToString(t);
if (str.Contains(value: '\n'))
{
// if the diff is multiline, start with a newline so that all changes are aligned
// otherwise it's easy to miss the first line of the diff
str = "\n" + str;
}

Logger.Information(str);
}
}

string DiffToString(Diff diff)
{
if (diff.operation == Operation.EQUAL)
{
return string.Empty;
}

var symbol = diff.operation switch
{
Operation.DELETE => '-',
Operation.INSERT => '+',
_ => throw new Exception("Unknown value of the Option enum.")
};
// put the symbol at the beginning of each line to make diff clearer when whole blocks of text are missing
var lines = diff.text.TrimEnd(trimChar: '\n').Split(Environment.NewLine);
return string.Join(Environment.NewLine, lines.Select(l => symbol + l));
}

}
}
1 change: 1 addition & 0 deletions tracer/build/_build/Build.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ void DeleteReparsePoints(string path)
.Description("Builds the Profiler native and managed src, and publishes the profiler home directory")
.After(Clean)
.DependsOn(CompileProfilerNativeSrc)
.DependsOn(TestNativeWrapper)
.DependsOn(PublishProfiler);

Target BuildNativeLoader => _ => _
Expand Down
14 changes: 14 additions & 0 deletions tracer/test/snapshots/native-wrapper-symbols-arm64.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
__errno_location
access
asprintf
free
getauxval
getenv
malloc
strcasecmp
strcmp
strcpy
strlen
strncmp
strncpy
strrchr
14 changes: 14 additions & 0 deletions tracer/test/snapshots/native-wrapper-symbols-x64.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
__errno_location
__tls_get_addr
access
asprintf
free
getenv
malloc
strcasecmp
strcmp
strcpy
strlen
strncmp
strncpy
strrchr
Loading