diff --git a/src/tests/Common/CLRTest.CrossGen.targets b/src/tests/Common/CLRTest.CrossGen.targets index ca3bde4776b65..52b8cbcc04e7a 100644 --- a/src/tests/Common/CLRTest.CrossGen.targets +++ b/src/tests/Common/CLRTest.CrossGen.targets @@ -168,8 +168,12 @@ if /i "$(AlwaysUseCrossGen2)" == "true" ( REM CrossGen2 Script if defined RunCrossGen2 ( set ExtraCrossGen2Args=!ExtraCrossGen2Args! $(CrossGen2TestExtraArguments) + set CrossGen2TestCheckPdb=$(CrossGen2TestCheckPdb) + set __CreatePdb=$(__CreatePdb) if defined LargeVersionBubble ( set ExtraCrossGen2Args=!ExtraCrossGen2Args! --inputbubble) + if defined CrossGen2TestCheckPdb ( set __CreatePdb=1) + set CrossGen2Status=0 set compilationDoneFlagFile=!ScriptPath!IL-CG2\done if exist "IL-CG2" ( @@ -192,6 +196,7 @@ if defined RunCrossGen2 ( if defined CompositeBuildMode ( set ExtraCrossGen2Args=!ExtraCrossGen2Args! --composite set __OutputFile=!scriptPath!\composite-r2r.dll + set __PdbFile=!scriptPath!\composite-r2r.ni.pdb rem In composite mode, treat all dll's in the test folder as rooting inputs set __InputFile=!scriptPath!IL-CG2\*.dll call :CompileOneFileCrossgen2 @@ -200,6 +205,7 @@ if defined RunCrossGen2 ( set ExtraCrossGen2Args=!ExtraCrossGen2Args! -r:!scriptPath!IL-CG2\*.dll for %%I in (!scriptPath!IL-CG2\*.dll) do ( set __OutputFile=!scriptPath!%%~nI.dll + set __PdbFile=!scriptPath!%%~nI.ni.pdb set __InputFile=%%I call :CompileOneFileCrossgen2 IF NOT !CrossGen2Status!==0 ( @@ -216,13 +222,14 @@ if defined RunCrossGen2 ( set __ResponseFile=!__OutputFile!.rsp del /Q !__ResponseFile! 2>nul - set __Command=!_DebuggerFullPath! REM Tests run locally need __TestDotNetCmd (set by runtest.py) or a compatible 5.0 dotnet runtime in the path if defined __TestDotNetCmd ( - set __Command=!__Command! "!__TestDotNetCmd!" + set __DotNet="!__TestDotNetCmd!" ) else ( - set __Command=!__Command! "dotnet" + set __DotNet="dotnet" ) + set __Command=!_DebuggerFullPath! + set __Command=!__Command! !__DotNet! set __Command=!__Command! "!CORE_ROOT!\crossgen2\crossgen2.dll" set __Command=!__Command! @"!__ResponseFile!" set __Command=!__Command! !ExtraCrossGen2Args! @@ -237,7 +244,7 @@ if defined RunCrossGen2 ( echo -r:!CORE_ROOT!\netstandard.dll>>!__ResponseFile! echo -O>>!__ResponseFile! - if not "$(__CreatePdb)" == "" ( + if defined __CreatePdb ( echo --pdb>>!__ResponseFile! ) @@ -259,6 +266,21 @@ if defined RunCrossGen2 ( endlocal set CrossGen2Status=!ERRORLEVEL! echo %time% + + if !CrossGen2Status!==0 ( + if defined CrossGen2TestCheckPdb ( + set __CheckPdbCommand=!__DotNet! + set __CheckPdbCommand=!__CheckPdbCommand! "!CORE_ROOT!\PdbChecker\PdbChecker.dll" + set __CheckPdbCommand=!__CheckPdbCommand! !__PdbFile! @(CheckPdbSymbol->'%22%(Identity)%22', ' ') + echo "!__CheckPdbCommand!" + call !__CheckPdbCommand! + if not !ERRORLEVEL!==0 ( + echo PDB check failed for file !__PdbFile! >2 + set CrossGen2Status=42 + ) + ) + ) + Exit /b 0 :DoneCrossgen2Operations diff --git a/src/tests/Common/Directory.Build.targets b/src/tests/Common/Directory.Build.targets index dde2731e82237..7046ef0ca995d 100644 --- a/src/tests/Common/Directory.Build.targets +++ b/src/tests/Common/Directory.Build.targets @@ -44,6 +44,7 @@ + @@ -174,7 +175,7 @@ - + _pdbSymbols; + + public MSDiaSymbolReader(string pdbFile) + { + try + { + _diaDataSource = new DiaSourceClass(); + _diaDataSource.loadDataFromPdb(pdbFile); + _diaDataSource.openSession(out _diaSession); + + _pdbSymbols = new List(); + + _diaSession.getSymbolsByAddr(out IDiaEnumSymbolsByAddr symbolEnum); + int symbolsTotal = 0; + for (IDiaSymbol symbol = symbolEnum.symbolByRVA(0); symbol != null; symbolEnum.Next(1, out symbol, out uint fetched)) + { + symbolsTotal++; + if (symbol.symTag == (uint)SymTagEnum.SymTagFunction || symbol.symTag == (uint)SymTagEnum.SymTagPublicSymbol) + { + _pdbSymbols.Add(symbol.name); + } + } + + Console.WriteLine("PDB file: {0}", pdbFile); + Console.WriteLine("Total symbols: {0}", symbolsTotal); + Console.WriteLine("Public symbols: {0}", _pdbSymbols.Count); + } + catch (Exception ex) + { + throw new Exception($"Error opening PDB file {pdbFile}", ex); + } + } + + public void DumpSymbols() + { + Console.WriteLine("PDB public symbol list:"); + foreach (string symbol in _pdbSymbols.OrderBy(s => s)) + { + Console.WriteLine(symbol); + } + Console.WriteLine("End of PDB public symbol list"); + } + + public bool ContainsSymbol(string symbolName) => _pdbSymbols.Any(s => s.Contains(symbolName)); +} diff --git a/src/tests/Common/PdbChecker/PdbChecker.csproj b/src/tests/Common/PdbChecker/PdbChecker.csproj new file mode 100644 index 0000000000000..cc9d3881353b6 --- /dev/null +++ b/src/tests/Common/PdbChecker/PdbChecker.csproj @@ -0,0 +1,16 @@ + + + + Exe + net7.0 + enable + enable + true + + + + + + + + diff --git a/src/tests/Common/PdbChecker/PdbChecker.sln b/src/tests/Common/PdbChecker/PdbChecker.sln new file mode 100644 index 0000000000000..3ba7e9ae4c337 --- /dev/null +++ b/src/tests/Common/PdbChecker/PdbChecker.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32708.82 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PdbChecker", "PdbChecker.csproj", "{6247A503-5387-4BE1-ACA3-027CADA30CA9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6247A503-5387-4BE1-ACA3-027CADA30CA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6247A503-5387-4BE1-ACA3-027CADA30CA9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6247A503-5387-4BE1-ACA3-027CADA30CA9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6247A503-5387-4BE1-ACA3-027CADA30CA9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4033231C-763B-4C57-BA35-7C1AC007AD0E} + EndGlobalSection +EndGlobal diff --git a/src/tests/Common/PdbChecker/Program.cs b/src/tests/Common/PdbChecker/Program.cs new file mode 100644 index 0000000000000..41f4209ce648d --- /dev/null +++ b/src/tests/Common/PdbChecker/Program.cs @@ -0,0 +1,60 @@ +// 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 Dia2Lib; +class Program +{ + public static int Main(string[] args) + { + try + { + TryMain(args); + return 0; + } + catch (Exception ex) + { + Console.Error.WriteLine("Fatal error: {0}", ex); + return 1; + } + } + + private static void TryMain(string[] args) + { + if (args.Length == 0) + { + DisplayUsage(); + return; + } + MSDiaSymbolReader reader = new MSDiaSymbolReader(args[0]); + int matchedSymbols = 0; + int missingSymbols = 0; + for (int symbolArgIndex = 1; symbolArgIndex < args.Length; symbolArgIndex++) + { + string symbolName = args[symbolArgIndex]; + if (reader.ContainsSymbol(symbolName)) + { + matchedSymbols++; + } + else + { + missingSymbols++; + Console.Error.WriteLine("Missing symbol: {0}", symbolName); + } + } + if (missingSymbols > 0) + { + reader.DumpSymbols(); + throw new Exception($"{missingSymbols} missing symbols ({matchedSymbols} symbols matched)"); + } + if (matchedSymbols > 0) + { + Console.WriteLine("Matched all {0} symbols", matchedSymbols); + } + } + + private static void DisplayUsage() + { + Console.WriteLine("Usage: PdbChecker { }"); + } +} diff --git a/src/tests/Common/test_dependencies/test_dependencies.csproj b/src/tests/Common/test_dependencies/test_dependencies.csproj index 8f10be173327d..b20052c390b0d 100644 --- a/src/tests/Common/test_dependencies/test_dependencies.csproj +++ b/src/tests/Common/test_dependencies/test_dependencies.csproj @@ -10,6 +10,7 @@ + diff --git a/src/tests/readytorun/crossgen2/crossgen2smoke.csproj b/src/tests/readytorun/crossgen2/crossgen2smoke.csproj index c233cd8dcbd04..4808e35ee4899 100644 --- a/src/tests/readytorun/crossgen2/crossgen2smoke.csproj +++ b/src/tests/readytorun/crossgen2/crossgen2smoke.csproj @@ -5,6 +5,14 @@ true + true + + + + + + +