notify doctors work, audit work, new product advisory sprints
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -33,6 +34,7 @@ public sealed class MacOsDyldCaptureAdapter : IRuntimeCaptureAdapter
|
||||
private DateTime _startTime;
|
||||
private CancellationTokenSource? _captureCts;
|
||||
private Task? _captureTask;
|
||||
private Task? _durationTask;
|
||||
private Process? _dtraceProcess;
|
||||
private long _droppedEvents;
|
||||
private int _redactedPaths;
|
||||
@@ -40,11 +42,12 @@ public sealed class MacOsDyldCaptureAdapter : IRuntimeCaptureAdapter
|
||||
/// <summary>
|
||||
/// Creates a new macOS dyld capture adapter.
|
||||
/// </summary>
|
||||
/// <param name="timeProvider">Optional time provider for deterministic timestamps.</param>
|
||||
/// <param name="timeProvider">Time provider for deterministic timestamps.</param>
|
||||
/// <param name="guidProvider">Optional GUID provider for deterministic session IDs.</param>
|
||||
public MacOsDyldCaptureAdapter(TimeProvider? timeProvider = null, IGuidProvider? guidProvider = null)
|
||||
public MacOsDyldCaptureAdapter(TimeProvider timeProvider, IGuidProvider? guidProvider = null)
|
||||
{
|
||||
_timeProvider = timeProvider ?? TimeProvider.System;
|
||||
ArgumentNullException.ThrowIfNull(timeProvider);
|
||||
_timeProvider = timeProvider;
|
||||
_guidProvider = guidProvider ?? SystemGuidProvider.Instance;
|
||||
}
|
||||
|
||||
@@ -188,18 +191,11 @@ public sealed class MacOsDyldCaptureAdapter : IRuntimeCaptureAdapter
|
||||
}
|
||||
|
||||
// Start the duration timer
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Delay(options.MaxCaptureDuration, _captureCts.Token);
|
||||
await StopCaptureAsync(CancellationToken.None);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// Expected when capture is stopped manually
|
||||
}
|
||||
}, _captureCts.Token);
|
||||
_durationTask = CaptureDurationTimer.RunAsync(
|
||||
options.MaxCaptureDuration,
|
||||
ct => StopCaptureAsync(ct),
|
||||
_captureCts.Token,
|
||||
cancellationToken);
|
||||
|
||||
SetState(CaptureState.Running);
|
||||
return SessionId;
|
||||
@@ -258,6 +254,22 @@ public sealed class MacOsDyldCaptureAdapter : IRuntimeCaptureAdapter
|
||||
}
|
||||
}
|
||||
|
||||
if (_durationTask != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _durationTask.WaitAsync(TimeSpan.FromSeconds(2), cancellationToken);
|
||||
}
|
||||
catch (TimeoutException)
|
||||
{
|
||||
// Timer did not complete in time
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// Expected when canceling
|
||||
}
|
||||
}
|
||||
|
||||
var session = new RuntimeCaptureSession(
|
||||
SessionId: SessionId ?? "unknown",
|
||||
StartTime: _startTime,
|
||||
@@ -337,20 +349,7 @@ public sealed class MacOsDyldCaptureAdapter : IRuntimeCaptureAdapter
|
||||
// Build dtrace script for dyld tracing
|
||||
var script = BuildDtraceScript();
|
||||
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "dtrace",
|
||||
Arguments = $"-n '{script}'",
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
};
|
||||
|
||||
if (_options?.TargetProcessId != null)
|
||||
{
|
||||
psi.Arguments = $"-p {_options.TargetProcessId} -n '{script}'";
|
||||
}
|
||||
var psi = CreateDtraceStartInfo(script, _options?.TargetProcessId);
|
||||
|
||||
_dtraceProcess = new Process { StartInfo = psi };
|
||||
_dtraceProcess.OutputDataReceived += OnDtraceOutput;
|
||||
@@ -432,8 +431,8 @@ public sealed class MacOsDyldCaptureAdapter : IRuntimeCaptureAdapter
|
||||
|
||||
return new RuntimeLoadEvent(
|
||||
Timestamp: _timeProvider.GetUtcNow().UtcDateTime,
|
||||
ProcessId: int.Parse(parts[1]),
|
||||
ThreadId: int.Parse(parts[2]),
|
||||
ProcessId: int.Parse(parts[1], CultureInfo.InvariantCulture),
|
||||
ThreadId: int.Parse(parts[2], CultureInfo.InvariantCulture),
|
||||
LoadType: loadType,
|
||||
RequestedPath: parts[3],
|
||||
ResolvedPath: null, // Set on return probe
|
||||
@@ -524,14 +523,17 @@ public sealed class MacOsDyldCaptureAdapter : IRuntimeCaptureAdapter
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!IsSafeToken(command))
|
||||
return false;
|
||||
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "which",
|
||||
Arguments = command,
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
};
|
||||
psi.ArgumentList.Add(command);
|
||||
|
||||
using var process = Process.Start(psi);
|
||||
if (process == null)
|
||||
@@ -557,14 +559,17 @@ public sealed class MacOsDyldCaptureAdapter : IRuntimeCaptureAdapter
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!IsSafeToken("csrutil"))
|
||||
return SipStatus.Unknown;
|
||||
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "csrutil",
|
||||
Arguments = "status",
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
};
|
||||
psi.ArgumentList.Add("status");
|
||||
|
||||
using var process = Process.Start(psi);
|
||||
if (process == null)
|
||||
@@ -610,4 +615,43 @@ public sealed class MacOsDyldCaptureAdapter : IRuntimeCaptureAdapter
|
||||
|
||||
return Regex.IsMatch(path, regexPattern, RegexOptions.IgnoreCase);
|
||||
}
|
||||
|
||||
private static ProcessStartInfo CreateDtraceStartInfo(string script, int? targetProcessId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(script))
|
||||
throw new ArgumentException("Script cannot be empty.", nameof(script));
|
||||
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "dtrace",
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
};
|
||||
|
||||
if (targetProcessId is int pid && pid > 0)
|
||||
{
|
||||
psi.ArgumentList.Add("-p");
|
||||
psi.ArgumentList.Add(pid.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
psi.ArgumentList.Add("-n");
|
||||
psi.ArgumentList.Add(script);
|
||||
return psi;
|
||||
}
|
||||
|
||||
private static bool IsSafeToken(string value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
return false;
|
||||
|
||||
foreach (var ch in value)
|
||||
{
|
||||
if (!char.IsAsciiLetterOrDigit(ch) && ch != '-' && ch != '_' && ch != '.')
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user