| File: LegacyFallbackHelper.cs | Web Access |
| Project: src\runtime\src\native\managed\cdac\Microsoft.Diagnostics.DataContractReader.Legacy\Microsoft.Diagnostics.DataContractReader.Legacy.csproj (Microsoft.Diagnostics.DataContractReader.Legacy) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Microsoft.Diagnostics.DataContractReader.Legacy; /// <summary> /// Controls whether delegation-only APIs can fall back to the legacy DAC implementation. /// When <c>CDAC_NO_FALLBACK=1</c> is set, only explicitly allowlisted methods may delegate. /// All fallback attempts are logged to stderr for capture by the test infrastructure. /// </summary> internal static class LegacyFallbackHelper { private static readonly bool s_noFallback = Environment.GetEnvironmentVariable("CDAC_NO_FALLBACK") == "1"; // Methods that are allowed to fall back even in no-fallback mode. // Use the method name as it appears via [CallerMemberName]. private static readonly HashSet<string> s_allowlist = new(StringComparer.Ordinal) { // Dump creation — the cDAC does not implement memory enumeration. nameof(ICLRDataEnumMemoryRegions.EnumMemoryRegions), }; // Files whose methods are all allowed to fall back. // The entire DBI interface is deferred — the cDAC does not implement ICorDebug data access yet. private static readonly HashSet<string> s_fileAllowlist = new(StringComparer.OrdinalIgnoreCase) { "DacDbiImpl.cs", }; /// <summary> /// Returns <c>true</c> if the calling method is allowed to delegate to the legacy DAC. /// In normal mode (no <c>CDAC_NO_FALLBACK</c>), always returns <c>true</c>. /// In no-fallback mode, returns <c>true</c> only for allowlisted methods. /// All fallback attempts (allowed and blocked) are logged to stderr. /// </summary> internal static bool CanFallback( [CallerMemberName] string name = "", [CallerFilePath] string file = "", [CallerLineNumber] int line = 0) { if (!s_noFallback) return true; if (s_allowlist.Contains(name) || s_fileAllowlist.Contains(Path.GetFileName(file))) { Console.Error.WriteLine($"[cDAC] Allowed fallback: {name} at {Path.GetFileName(file)}:{line}"); return true; } Console.Error.WriteLine($"[cDAC] Blocked fallback: {name} at {Path.GetFileName(file)}:{line}"); return false; } }