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

Enable IlasmRoundTrip tests for merged tests #93368

Merged
merged 42 commits into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8dd8951
Initial work
TIHan Oct 11, 2023
d348160
Tweak
TIHan Oct 11, 2023
41394cb
Tweak
TIHan Oct 11, 2023
d5afb0e
Do not generate _ilasmroundtrip.py for tests that have a generated ru…
TIHan Oct 11, 2023
c59ea7d
Reduce imports
TIHan Oct 11, 2023
a3a41cf
Force fail to see where CI fails
TIHan Oct 12, 2023
20adfcd
Revert forcing failure. Run roundtrip on build.
TIHan Oct 12, 2023
b91c82d
Trying to fix script
TIHan Oct 12, 2023
fa91e26
Backslash tweak
TIHan Oct 12, 2023
a825fe8
Do not roundtrip the same assembly
TIHan Oct 12, 2023
ede1994
Fixing
TIHan Oct 12, 2023
828c4b0
Remove import glob
TIHan Oct 12, 2023
844eb49
Added is_managed_assembly
TIHan Oct 12, 2023
265d870
remove print
TIHan Oct 12, 2023
cd497ac
Fixed paths
TIHan Oct 12, 2023
969369b
Support bash. Ignore certain tests for arm. Fix poison test.
TIHan Oct 13, 2023
c1e0b1f
Update CLRTest.Jit.targets
TIHan Oct 13, 2023
f654a59
Feedback. Added AssemblyChecker.
TIHan Oct 16, 2023
54d65a8
Merge branch 'ilasm-roundtrip-fix' of https://github.com/TIHan/runtim…
TIHan Oct 16, 2023
b06879a
Fix paths
TIHan Oct 17, 2023
9f8d9e8
Update src/tests/Common/Directory.Build.targets
TIHan Oct 17, 2023
9b7bf31
Feedback
TIHan Oct 17, 2023
0b14d98
Feedback
TIHan Oct 17, 2023
7aca653
Update AssemblyChecker.csproj
TIHan Oct 17, 2023
e9abeb4
Update Program.cs
TIHan Oct 17, 2023
5f57ed6
Trying to fix calling python on helix.
TIHan Oct 17, 2023
ca91893
Remove old roundtrip script calls. Added --is-exe option for Assembly…
TIHan Oct 17, 2023
ba6fc6f
Tweak option:
TIHan Oct 17, 2023
d564396
Remove check
TIHan Oct 17, 2023
c9d1e49
Remove imports
TIHan Oct 17, 2023
18914d8
Fix build
TIHan Oct 18, 2023
1a6476a
Fix syntax errors. Fixed Popen arguments
TIHan Oct 18, 2023
4e97e05
Fixed Popen arguments
TIHan Oct 18, 2023
b2c85b9
Fixing debug check
TIHan Oct 18, 2023
e25f1d4
Fixing tests
TIHan Oct 18, 2023
2ed31da
Update ILVerificationTests.csproj
TIHan Oct 19, 2023
f9c41e9
Fixing tests
TIHan Oct 19, 2023
fe51ff1
Feedback
TIHan Oct 23, 2023
703e89b
Feedback
TIHan Oct 24, 2023
7b4796a
Update CLRTest.Jit.targets
TIHan Oct 27, 2023
dcff071
Added help usage flag for AssemblyChecker
TIHan Oct 27, 2023
4a2442e
Feedback on assembly-checker
TIHan Oct 29, 2023
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
3 changes: 2 additions & 1 deletion eng/Subsets.props
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,8 @@
$(CoreClrProjectRoot)tools\r2rdump\R2RDump.csproj;
$(CoreClrProjectRoot)tools\dotnet-pgo\dotnet-pgo.csproj;
$(CoreClrProjectRoot)tools\aot\ILCompiler\repro\repro.csproj;
$(CoreClrProjectRoot)tools\r2rtest\R2RTest.csproj" Category="clr" Condition="'$(DotNetBuildFromSource)' != 'true'"/>
$(CoreClrProjectRoot)tools\r2rtest\R2RTest.csproj;
$(CoreClrProjectRoot)tools\AssemblyChecker\AssemblyChecker.csproj" Category="clr" Condition="'$(DotNetBuildFromSource)' != 'true'"/>
<ProjectToBuild Include="$(CoreClrProjectRoot)tools\aot\crossgen2\crossgen2.csproj" Category="clr" />
<ProjectToBuild Include="$(CoreClrProjectRoot)tools\aot\ILCompiler.Build.Tasks\ILCompiler.Build.Tasks.csproj" Category="clr" Condition="'$(NativeAotSupported)' == 'true'" />
<ProjectToBuild Include="$(CoreClrProjectRoot)tools\aot\ILCompiler\ILCompiler.csproj" Category="clr" Condition="'$(NativeAotSupported)' == 'true'" />
Expand Down
16 changes: 16 additions & 0 deletions src/coreclr/tools/AssemblyChecker/AssemblyChecker.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>AssemblyChecker</AssemblyName>
<OutputType>Exe</OutputType>
<TargetFramework>$(NetCoreAppToolCurrent)</TargetFramework>
<PlatformTarget>AnyCPU</PlatformTarget>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendTargetFrameworkToOutputPath Condition="'$(BuildingInsideVisualStudio)' == 'true'">true</AppendTargetFrameworkToOutputPath>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputPath>$(RuntimeBinDir)\AssemblyChecker</OutputPath>
<RunAnalyzers>false</RunAnalyzers>
</PropertyGroup>
</Project>
124 changes: 124 additions & 0 deletions src/coreclr/tools/AssemblyChecker/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

TIHan marked this conversation as resolved.
Show resolved Hide resolved
// This is a simple console application that is designed to answer True or False
// questions about whether a given file is a managed assembly or not.
// You can also ask whether or not the assembly is debuggable.
// Return code of 0 indicates the file is a managed assembly.
// Return code of 1 indicates the file is not a managed assembly. No errors will be printed for this one.

using System.Text;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;

namespace AssemblyChecker
{
public class Program
{
static bool IsAssembly(string path)
{
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

// Try to read CLI metadata from the PE file.
using var peReader = new PEReader(fs);

if (!peReader.HasMetadata)
{
return false; // File does not have CLI metadata.
}

// Check that file has an assembly manifest.
MetadataReader reader = peReader.GetMetadataReader();
return reader.IsAssembly;
}

static bool IsDebug(string path)
{
var asm = Assembly.LoadFrom(path);
object[] attribs = asm.GetCustomAttributes(typeof(DebuggableAttribute), false);

if (attribs.Length > 0)
{
return
attribs.Any(x =>
{
DebuggableAttribute? debuggableAttribute = attribs[0] as DebuggableAttribute;
if (debuggableAttribute != null)
{
return debuggableAttribute.IsJITOptimizerDisabled;
}
return false;
});
}
else
{
return false;
}
TIHan marked this conversation as resolved.
Show resolved Hide resolved
}

static bool IsExe(string path)
{
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

// Try to read CLI metadata from the PE file.
using var peReader = new PEReader(fs);

if (!peReader.HasMetadata)
{
return false; // File does not have CLI metadata.
}

return peReader.PEHeaders.IsExe;
}

static int Main(string[] args)
{
if (args.Length == 0)
{
Console.Error.WriteLine("Expected assembly file-path.");
TIHan marked this conversation as resolved.
Show resolved Hide resolved
return 2;
}

if (args.Length == 1)
{
if (IsAssembly(args[0]))
return 0;
else
return 1;
TIHan marked this conversation as resolved.
Show resolved Hide resolved
}

if (args.Length == 2)
{
switch (args[0])
{
case "--is-debug":
{
if (IsDebug(args[1]))
return 0;
else
return 1;
}

case "--is-exe":
{
if (IsExe(args[1]))
return 0;
else
return 1;
}

default:
{
Console.Error.WriteLine("Invalid option.");
return 2;
}
}
}

Console.Error.WriteLine("Too many arguments.");
return 2;
TIHan marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
184 changes: 112 additions & 72 deletions src/tests/Common/CLRTest.Jit.targets
Original file line number Diff line number Diff line change
Expand Up @@ -55,60 +55,22 @@ export RunningIlasmRoundTrip=
]]>
</IlasmRoundTripBashScript>

<IlasmRoundTripBashScript Condition="'$(CLRTestKind)' == 'BuildAndRun'"><![CDATA[
<IlasmRoundTripBashScript Condition="'$(CLRTestKind)' == 'BuildAndRun' And '$(IlasmRoundTripIncompatible)' != 'true'"><![CDATA[
TIHan marked this conversation as resolved.
Show resolved Hide resolved
# IlasmRoundTrip Script
# Disable Ilasm round-tripping for Linker tests.
# Todo: Ilasm round-trip on linked binaries.
TIHan marked this conversation as resolved.
Show resolved Hide resolved

if [ -z "$DoLink" -a ! -z "$RunningIlasmRoundTrip" ];
then
mkdir IL-RT
cp $(InputAssemblyName) $(TargetAssemblyName)
echo "$CORE_ROOT/ildasm" -raweh -unicode -out=$(DisassemblyName) $(TargetAssemblyName)
"$CORE_ROOT/ildasm" -raweh -unicode -out=$(DisassemblyName) $(TargetAssemblyName)
python3 $(AssemblyName)_ilasmroundtrip.py
ERRORLEVEL=$?
if [ $ERRORLEVEL -ne 0 ]
then
echo EXECUTION OF ILDASM - FAILED $ERRORLEVEL
exit 1
fi
if [ ! -f "$(DisassemblyName)" ]
then
echo "EXECUTION OF ILDASM - FAILED $(DisassemblyName) is missing"
exit 1
fi

ilasm_count=1
while true
do
echo "$CORE_ROOT/ilasm" -output=$(InputAssemblyName) $(_IlasmSwitches) $(DisassemblyName)
"$CORE_ROOT/ilasm" -output=$(InputAssemblyName) $(_IlasmSwitches) $(DisassemblyName)
ERRORLEVEL=$?
if [ $ERRORLEVEL -eq 0 ]
then
break
fi

echo EXECUTION $ilasm_count OF ILASM - FAILED with $ERRORLEVEL

if [ $ilasm_count -eq 3 ]
then
break
fi

((ilasm_count++))
echo Trying again
sleep 10
done

if [ $ERRORLEVEL -ne 0 ]
then
echo ILASM ROUND-TRIP - FAILED $ERRORLEVEL
exit 1
fi
fi
]]>
</IlasmRoundTripBashScript>
<BashIlrtTestLaunchCmds Condition="'$(CLRTestKind)' == 'BuildAndRun'"><![CDATA[
<BashIlrtTestLaunchCmds Condition="'$(CLRTestKind)' == 'BuildAndRun' And '$(IlasmRoundTripIncompatible)' != 'true'"><![CDATA[
TIHan marked this conversation as resolved.
Show resolved Hide resolved
if [ -z "$DoLink" -a ! -z "$RunningIlasmRoundTrip" ];
then
echo $LAUNCHER $(InputAssemblyName) %24(printf "'%s' " "${CLRTestExecutionArguments[@]}")
Expand Down Expand Up @@ -140,46 +102,21 @@ set RunningIlasmRoundTrip=
]]>
</IlasmRoundTripBatchScript>

<IlasmRoundTripBatchScript Condition="'$(CLRTestKind)' == 'BuildAndRun'"><![CDATA[
<IlasmRoundTripBatchScript Condition="'$(CLRTestKind)' == 'BuildAndRun' And '$(IlasmRoundTripIncompatible)' != 'true'"><![CDATA[
REM IlasmRoundTrip Script
REM Disable Ilasm round-tripping for Linker tests.
REM Todo: Ilasm round-trip on linked binaries.

IF NOT DEFINED DoLink (
IF DEFINED RunningIlasmRoundTrip (
mkdir IL-RT
copy $(InputAssemblyName) $(TargetAssemblyName)
ECHO %CORE_ROOT%\ildasm.exe /raweh /unicode /out=$(DisassemblyName) $(TargetAssemblyName)
%CORE_ROOT%\ildasm.exe /raweh /unicode /out=$(DisassemblyName) $(TargetAssemblyName)

IF NOT "!ERRORLEVEL!"=="0" (
ECHO EXECUTION OF ILDASM - FAILED !ERRORLEVEL!
Exit /b 1
)
IF NOT EXIST $(DisassemblyName) (
ECHO EXECUTION OF ILDASM - FAILED $(DisassemblyName) is missing
Exit /b 1
)

set ilasm_count=1
:Try_ilasm
ECHO %CORE_ROOT%\ilasm.exe /output=$(InputAssemblyName) $(_IlasmSwitches) $(DisassemblyName)
%CORE_ROOT%\ilasm.exe /output=$(InputAssemblyName) $(_IlasmSwitches) $(DisassemblyName)
python $(AssemblyName)_ilasmroundtrip.py
IF NOT "!ERRORLEVEL!"=="0" (
ECHO EXECUTION OF ILASM - Try !ilasm_count! FAILED with status !ERRORLEVEL!
IF !ilasm_count! LEQ 3 (
ECHO Trying again
set /A ilasm_count=ilasm_count+1
timeout /t 10 /nobreak
goto :Try_ilasm
)
ECHO EXECUTION OF ILASM - FAILED
ECHO ILASM ROUND-TRIP - FAILED !ERRORLEVEL!
Exit /b 1
)
)
)
]]>
</IlasmRoundTripBatchScript>
<BatchIlrtTestLaunchCmds Condition="'$(CLRTestKind)' == 'BuildAndRun'"><![CDATA[
<BatchIlrtTestLaunchCmds Condition="'$(CLRTestKind)' == 'BuildAndRun' And '$(IlasmRoundTripIncompatible)' != 'true'"><![CDATA[
IF NOT DEFINED DoLink (
if defined RunningIlasmRoundTrip (
ECHO %LAUNCHER% $(InputAssemblyName) %CLRTestExecutionArguments%
Expand Down Expand Up @@ -365,6 +302,109 @@ set DOTNET_JitPath=%CORE_ROOT%\superpmi-shim-collector.dll
</PropertyGroup>
</Target>

<!--
***********************************************************************************************
IlasmRoundTrip for merged tests
***********************************************************************************************
-->

<Target Name="IlasmRoundTripCommand" AfterTargets="AfterBuild" Condition="'$(IlasmRoundTripIncompatible)' != 'true'">
<PropertyGroup>
<InputAssemblyName>$(AssemblyName).dll</InputAssemblyName>
<DisassemblyName>IL-RT/$(AssemblyName).il</DisassemblyName>
<TargetAssemblyName>IL-RT/$(AssemblyName).dll</TargetAssemblyName>
<_IlasmRoundTripScriptText><![CDATA[
import os
import shutil
import subprocess
import sys
import glob

def is_managed_assembly(file):
TIHan marked this conversation as resolved.
Show resolved Hide resolved
proc = subprocess.Popen([f'{os.environ["CORE_ROOT"]}/corerun', f'{os.environ["CORE_ROOT"]}/AssemblyChecker/AssemblyChecker.dll', file])

try:
proc.communicate()
return proc.returncode == 0
except:
proc.kill()
return False

def is_managed_debug_assembly(file):
proc = subprocess.Popen([f'{os.environ["CORE_ROOT"]}/corerun', f'{os.environ["CORE_ROOT"]}/AssemblyChecker/AssemblyChecker.dll', "--is-debug", file])

try:
proc.communicate()
return proc.returncode == 0
except:
proc.kill()
return False

def is_managed_exe_assembly(file):
proc = subprocess.Popen([f'{os.environ["CORE_ROOT"]}/corerun', f'{os.environ["CORE_ROOT"]}/AssemblyChecker/AssemblyChecker.dll', "--is-exe", file])

try:
proc.communicate()
return proc.returncode == 0
except:
proc.kill()
return False

print("")
print("ILASM RoundTrips")

if not os.path.exists("IL-RT"):
os.mkdir("IL-RT")

for inputAssemblyName in glob.glob("*.dll"):
if is_managed_assembly(inputAssemblyName):
print("ILASM RoundTrip for " + inputAssemblyName)

ilasmSwitches = ""

if not is_managed_exe_assembly(inputAssemblyName):
ilasmSwitches = ilasmSwitches + " -DLL"

if is_managed_debug_assembly(inputAssemblyName):
ilasmSwitches = ilasmSwitches + " -DEBUG"

disassemblyName = os.path.join("IL-RT", os.path.splitext(os.path.basename(inputAssemblyName))[0] + ".il")
targetAssemblyName = os.path.join("IL-RT", os.path.basename(inputAssemblyName))

shutil.copyfile(inputAssemblyName, targetAssemblyName)

ildasm_args = f'{os.environ["CORE_ROOT"]}/ildasm -raweh -unicode -out={disassemblyName} {targetAssemblyName}'
print(ildasm_args)
proc = subprocess.Popen(ildasm_args, shell=True)

try:
proc.communicate()
except:
proc.kill()
sys.exit(1)

ilasm_args = f'{os.environ["CORE_ROOT"]}/ilasm -output={inputAssemblyName} {ilasmSwitches} {disassemblyName}'
print(ilasm_args)
proc = subprocess.Popen(ilasm_args, shell=True)

try:
proc.communicate()
except:
proc.kill()
sys.exit(1)

print("")

print("")

]]></_IlasmRoundTripScriptText>
</PropertyGroup>
<WriteLinesToFile
File="$(OutputPath)$(AssemblyName)_ilasmroundtrip.py"
Lines="$(_IlasmRoundTripScriptText)"
Overwrite="true" />
</Target>

<!--
***********************************************************************************************
GCStress settings
Expand Down
5 changes: 5 additions & 0 deletions src/tests/Common/Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@
<IncludeSubFolders>True</IncludeSubFolders>
</RunTimeArtifactsIncludeFolders>

<!-- Used to determine if a file is a managed assembly or a managed assembly built with DEBUG -->
<RunTimeArtifactsIncludeFolders Include="AssemblyChecker/" TargetDir="AssemblyChecker/">
<IncludeSubFolders>True</IncludeSubFolders>
</RunTimeArtifactsIncludeFolders>

<!-- XUnit runner harness assemblies that we don't want to mix in with the framework in Core_Root -->
<RunTimeArtifactsIncludeFolders Include="xunit/" TargetDir="xunit/" />
</ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions src/tests/JIT/Methodical/fp/exgen/10w5d_cs_do.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<!-- Needed for JIT/superpmi/superpmicollect.csproj which depends on the
individual test .cmd file -->
<RequiresProcessIsolation>true</RequiresProcessIsolation>
<IlasmRoundTripIncompatible>true</IlasmRoundTripIncompatible>
TIHan marked this conversation as resolved.
Show resolved Hide resolved
</PropertyGroup>
<PropertyGroup>
<DebugType>Full</DebugType>
Expand Down
Loading
Loading