diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f131abb265644e..5f06553dfe751e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -18,77 +18,77 @@ - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - a35b36664af90a8e61f051ad06fb8039380b1526 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb https://github.com/microsoft/vstest @@ -210,9 +210,9 @@ https://github.com/dotnet/xharness e9669dc84ecd668d3bbb748758103e23b394ffef - + https://github.com/dotnet/arcade - ee9b7f19853685805c612103282c8d9486c7db86 + 7421b55f46aff8373764016d942b23cbf87c75cb https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index 54bb177aa69193..a83a400a100f6a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,11 +1,11 @@ - 6.0.1 + 6.0.2 6 0 - 1 + 2 6.0.100 mauipre 1 @@ -37,8 +37,8 @@ manually enabled by updating the metadata. --> - - + + @@ -54,21 +54,21 @@ 1.0.0-rc.2.21511.46 - 6.0.0-beta.21560.2 - 6.0.0-beta.21560.2 - 6.0.0-beta.21560.2 - 6.0.0-beta.21560.2 - 6.0.0-beta.21560.2 - 6.0.0-beta.21560.2 - 2.5.1-beta.21560.2 - 6.0.0-beta.21560.2 - 6.0.0-beta.21565.3 - 6.0.0-beta.21560.2 - 6.0.0-beta.21560.2 - 6.0.0-beta.21560.2 - 6.0.0-beta.21560.2 - 6.0.0-beta.21560.2 - 6.0.0-beta.21560.2 + 6.0.0-beta.21609.4 + 6.0.0-beta.21609.4 + 6.0.0-beta.21609.4 + 6.0.0-beta.21609.4 + 6.0.0-beta.21609.4 + 6.0.0-beta.21609.4 + 2.5.1-beta.21609.4 + 6.0.0-beta.21609.4 + 6.0.0-beta.21609.4 + 6.0.0-beta.21609.4 + 6.0.0-beta.21609.4 + 6.0.0-beta.21609.4 + 6.0.0-beta.21609.4 + 6.0.0-beta.21609.4 + 6.0.0-beta.21609.4 6.0.0-preview.1.102 diff --git a/eng/common/build.sh b/eng/common/build.sh index bc07a1c6848243..a16e18b174a759 100755 --- a/eng/common/build.sh +++ b/eng/common/build.sh @@ -188,9 +188,6 @@ function InitializeCustomToolset { function Build { - if [[ "$ci" == true ]]; then - TryLogClientIpAddress - fi InitializeToolset InitializeCustomToolset diff --git a/eng/common/sdk-task.ps1 b/eng/common/sdk-task.ps1 index 7ab9baac5c8d9a..b1bca63ab1d82c 100644 --- a/eng/common/sdk-task.ps1 +++ b/eng/common/sdk-task.ps1 @@ -83,9 +83,6 @@ try { } if ($restore) { - if ($ci) { - Try-LogClientIpAddress - } Build 'Restore' } diff --git a/eng/common/templates/job/onelocbuild.yml b/eng/common/templates/job/onelocbuild.yml index 2b55a567f82ae5..069098b0a066c3 100644 --- a/eng/common/templates/job/onelocbuild.yml +++ b/eng/common/templates/job/onelocbuild.yml @@ -12,6 +12,7 @@ parameters: SourcesDirectory: $(Build.SourcesDirectory) CreatePr: true AutoCompletePr: false + ReusePr: true UseLfLineEndings: true UseCheckedInLocProjectJson: false LanguageSet: VS_Main_Languages @@ -64,6 +65,8 @@ jobs: ${{ if eq(parameters.CreatePr, true) }}: isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }} isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }} + ${{ if eq(parameters.RepoType, 'gitHub') }}: + isShouldReusePrSelected: ${{ parameters.ReusePr }} packageSourceAuth: patAuth patVariable: ${{ parameters.CeapexPat }} ${{ if eq(parameters.RepoType, 'gitHub') }}: diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 44484289943ed5..f1e1cb53953bcc 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -163,9 +163,6 @@ function InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) { # Disable telemetry on CI. if ($ci) { $env:DOTNET_CLI_TELEMETRY_OPTOUT=1 - - # In case of network error, try to log the current IP for reference - Try-LogClientIpAddress } # Source Build uses DotNetCoreSdkDir variable @@ -301,32 +298,45 @@ function InstallDotNet([string] $dotnetRoot, if ($skipNonVersionedFiles) { $installParameters.SkipNonVersionedFiles = $skipNonVersionedFiles } if ($noPath) { $installParameters.NoPath = $True } - try { - & $installScript @installParameters - } - catch { - if ($runtimeSourceFeed -or $runtimeSourceFeedKey) { - Write-Host "Failed to install dotnet from public location. Trying from '$runtimeSourceFeed'" - if ($runtimeSourceFeed) { $installParameters.AzureFeed = $runtimeSourceFeed } + $variations = @() + $variations += @($installParameters) - if ($runtimeSourceFeedKey) { - $decodedBytes = [System.Convert]::FromBase64String($runtimeSourceFeedKey) - $decodedString = [System.Text.Encoding]::UTF8.GetString($decodedBytes) - $installParameters.FeedCredential = $decodedString - } + $dotnetBuilds = $installParameters.Clone() + $dotnetbuilds.AzureFeed = "https://dotnetbuilds.azureedge.net/public" + $variations += @($dotnetBuilds) - try { - & $installScript @installParameters - } - catch { - Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Failed to install dotnet from custom location '$runtimeSourceFeed'." - ExitWithExitCode 1 - } + if ($runtimeSourceFeed) { + $runtimeSource = $installParameters.Clone() + $runtimeSource.AzureFeed = $runtimeSourceFeed + if ($runtimeSourceFeedKey) { + $decodedBytes = [System.Convert]::FromBase64String($runtimeSourceFeedKey) + $decodedString = [System.Text.Encoding]::UTF8.GetString($decodedBytes) + $runtimeSource.FeedCredential = $decodedString + } + $variations += @($runtimeSource) + } + + $installSuccess = $false + foreach ($variation in $variations) { + if ($variation | Get-Member AzureFeed) { + $location = $variation.AzureFeed } else { - Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Failed to install dotnet from public location." - ExitWithExitCode 1 + $location = "public location"; + } + Write-Host "Attempting to install dotnet from $location." + try { + & $installScript @variation + $installSuccess = $true + break + } + catch { + Write-Host "Failed to install dotnet from $location." } } + if (-not $installSuccess) { + Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "Failed to install dotnet from any of the specified locations." + ExitWithExitCode 1 + } } # @@ -882,24 +892,6 @@ if (!$disableConfigureToolsetImport) { } } -function Try-LogClientIpAddress() -{ - Write-Host "Attempting to log this client's IP for Azure Package feed telemetry purposes" - try - { - $result = Invoke-WebRequest -Uri "http://co1.msedge.net/fdv2/diagnostics.aspx" -UseBasicParsing - $lines = $result.Content.Split([Environment]::NewLine) - $socketIp = $lines | Select-String -Pattern "^Socket IP:.*" - Write-Host $socketIp - $clientIp = $lines | Select-String -Pattern "^Client IP:.*" - Write-Host $clientIp - } - catch - { - Write-Host "Unable to get this machine's effective IP address for logging: $_" - } -} - # # If $ci flag is set, turn on (and log that we did) special environment variables for improved Nuget client retry logic. # diff --git a/eng/common/tools.sh b/eng/common/tools.sh index 6a4871ef72b7a9..e555c34269f6e8 100755 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -188,28 +188,29 @@ function InstallDotNet { GetDotNetInstallScript "$root" local install_script=$_GetDotNetInstallScript - local archArg='' + local installParameters=(--version $version --install-dir "$root") + if [[ -n "${3:-}" ]] && [ "$3" != 'unset' ]; then - archArg="--architecture $3" + installParameters+=(--architecture $3) fi - local runtimeArg='' if [[ -n "${4:-}" ]] && [ "$4" != 'sdk' ]; then - runtimeArg="--runtime $4" + installParameters+=(--runtime $4) fi - local skipNonVersionedFilesArg="" if [[ "$#" -ge "5" ]] && [[ "$5" != 'false' ]]; then - skipNonVersionedFilesArg="--skip-non-versioned-files" + installParameters+=(--skip-non-versioned-files) fi - bash "$install_script" --version $version --install-dir "$root" $archArg $runtimeArg $skipNonVersionedFilesArg || { - local exit_code=$? - echo "Failed to install dotnet SDK from public location (exit code '$exit_code')." - local runtimeSourceFeed='' - if [[ -n "${6:-}" ]]; then - runtimeSourceFeed="--azure-feed $6" - fi + local variations=() # list of variable names with parameter arrays in them + + local public_location=("${installParameters[@]}") + variations+=(public_location) - local runtimeSourceFeedKey='' + local dotnetbuilds=("${installParameters[@]}" --azure-feed "https://dotnetbuilds.azureedge.net/public") + variations+=(dotnetbuilds) + + if [[ -n "${6:-}" ]]; then + variations+=(private_feed) + local private_feed=("${installParameters[@]}" --azure-feed $6) if [[ -n "${7:-}" ]]; then # The 'base64' binary on alpine uses '-d' and doesn't support '--decode' # '-d'. To work around this, do a simple detection and switch the parameter @@ -219,22 +220,27 @@ function InstallDotNet { decodeArg="-d" fi decodedFeedKey=`echo $7 | base64 $decodeArg` - runtimeSourceFeedKey="--feed-credential $decodedFeedKey" + private_feed+=(--feed-credential $decodedFeedKey) fi + fi - if [[ -n "$runtimeSourceFeed" || -n "$runtimeSourceFeedKey" ]]; then - bash "$install_script" --version $version --install-dir "$root" $archArg $runtimeArg $skipNonVersionedFilesArg $runtimeSourceFeed $runtimeSourceFeedKey || { - local exit_code=$? - Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to install dotnet SDK from custom location '$runtimeSourceFeed' (exit code '$exit_code')." - ExitWithExitCode $exit_code - } - else - if [[ $exit_code != 0 ]]; then - Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to install dotnet SDK from public location (exit code '$exit_code')." - fi - ExitWithExitCode $exit_code + local installSuccess=0 + for variationName in "${variations[@]}"; do + local name="$variationName[@]" + local variation=("${!name}") + echo "Attempting to install dotnet from $variationName." + bash "$install_script" "${variation[@]}" && installSuccess=1 + if [[ "$installSuccess" -eq 1 ]]; then + break fi - } + + echo "Failed to install dotnet from $variationName." + done + + if [[ "$installSuccess" -eq 0 ]]; then + Write-PipelineTelemetryError -category 'InitializeToolset' "Failed to install dotnet SDK from any of the specified locations." + ExitWithExitCode 1 + fi } function with_retries { @@ -399,13 +405,6 @@ function StopProcesses { return 0 } -function TryLogClientIpAddress () { - echo 'Attempting to log this client''s IP for Azure Package feed telemetry purposes' - if command -v curl > /dev/null; then - curl -s 'http://co1.msedge.net/fdv2/diagnostics.aspx' | grep ' IP: ' || true - fi -} - function MSBuild { local args=$@ if [[ "$pipelines_log" == true ]]; then diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml index 15fe948e92967e..3beb80193a725a 100644 --- a/eng/pipelines/common/platform-matrix.yml +++ b/eng/pipelines/common/platform-matrix.yml @@ -91,7 +91,7 @@ jobs: targetRid: linux-musl-x64 platform: Linux_musl_x64 container: - image: alpine-3.9-WithNode-20210714125437-9b5bbc2 + image: alpine-3.13-WithNode-20210910135845-c401c85 registry: mcr jobParameters: runtimeFlavor: ${{ parameters.runtimeFlavor }} diff --git a/eng/pipelines/coreclr/ci.yml b/eng/pipelines/coreclr/ci.yml index c4cbf06a14bde6..282d83d4030e54 100644 --- a/eng/pipelines/coreclr/ci.yml +++ b/eng/pipelines/coreclr/ci.yml @@ -150,13 +150,3 @@ jobs: crossgen2: true displayNameArgs: R2R_CG2 liveLibrariesBuildConfig: Release - -# -# Formatting -# -- template: /eng/pipelines/common/platform-matrix.yml - parameters: - jobTemplate: /eng/pipelines/coreclr/templates/format-job.yml - platforms: - - Linux_x64 - - windows_x64 diff --git a/eng/pipelines/coreclr/templates/helix-queues-setup.yml b/eng/pipelines/coreclr/templates/helix-queues-setup.yml index 8deb4bee0f6e7e..efdea9ebfa4f9c 100644 --- a/eng/pipelines/coreclr/templates/helix-queues-setup.yml +++ b/eng/pipelines/coreclr/templates/helix-queues-setup.yml @@ -47,7 +47,8 @@ jobs: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - (Ubuntu.1804.Arm32.Open)Ubuntu.1804.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-arm32v7-bfcd90a-20200121150440 - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - (Debian.9.Arm32)Ubuntu.1804.Armarch@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-9-helix-arm32v7-bfcd90a-20200121150037 + - (Debian.10.Arm32)Ubuntu.1804.Armarch@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-arm32v7-20210304164340-6616c63 + - (Debian.11.Arm32)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-arm32v7-20210304164347-5a7c380 - (Ubuntu.1804.Arm32)Ubuntu.1804.Armarch@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-arm32v7-bfcd90a-20200121150440 # Linux arm64 @@ -55,45 +56,47 @@ jobs: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - (Ubuntu.1804.Arm64.Open)Ubuntu.1804.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-arm64v8-20210531091519-97d8652 - ${{ if and(eq(variables['System.TeamProject'], 'public'), notIn(parameters.jobParameters.helixQueueGroup, 'pr', 'ci', 'libraries')) }}: - - (Debian.9.Arm64.Open)Ubuntu.1804.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-9-helix-arm64v8-bfcd90a-20200121150055 + - (Debian.10.Arm64.Open)Ubuntu.1804.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-arm64v8-20210304164340-56c6673 + - (Debian.11.Arm64.Open)Ubuntu.1804.Armarch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-arm64v8-20210304164340-5a7c380 - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - (Debian.9.Arm64)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-9-helix-arm64v8-bfcd90a-20200121150055 + - (Debian.10.Arm64)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-arm64v8-20210304164340-56c6673 + - (Debian.11.Arm64)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-arm64v8-20210304164340-5a7c380 - (Ubuntu.1804.Arm64)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-18.04-helix-arm64v8-20210531091519-97d8652 # Linux musl x64 - ${{ if eq(parameters.platform, 'Linux_musl_x64') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - (Alpine.312.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.12-helix-20200602002622-e06dc59 + - (Alpine.314.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.14-helix-amd64-20210910135833-1848e19 - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - (Alpine.312.Amd64)ubuntu.1604.amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.12-helix-20200602002622-e06dc59 + - (Alpine.314.Amd64)ubuntu.1604.amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.14-helix-amd64-20210910135833-1848e19 # Linux musl arm32 - ${{ if eq(parameters.platform, 'Linux_musl_arm') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - (Alpine.313.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.13-helix-arm32v7-20210414141857-1ea6b0a + - (Alpine.314.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.14-helix-arm32v7-20210910135806-8a6f4f3 - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - (Alpine.313.Arm32)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.13-helix-arm32v7-20210414141857-1ea6b0a + - (Alpine.314.Arm32)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.14-helix-arm32v7-20210910135806-8a6f4f3 # Linux musl arm64 - ${{ if eq(parameters.platform, 'Linux_musl_arm64') }}: - ${{ if eq(variables['System.TeamProject'], 'public') }}: - - (Alpine.312.Arm64.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.12-helix-arm64v8-20200602002604-25f8a3e + - (Alpine.314.Arm64.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.14-helix-arm64v8-20210910135810-8a6f4f3 - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - (Alpine.312.Arm64)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.12-helix-arm64v8-20200602002604-25f8a3e + - (Alpine.314.Arm64)Ubuntu.1804.ArmArch@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.14-helix-arm64v8-20210910135810-8a6f4f3 # Linux x64 - ${{ if eq(parameters.platform, 'Linux_x64') }}: - ${{ if and(eq(variables['System.TeamProject'], 'public'), in(parameters.jobParameters.helixQueueGroup, 'pr', 'ci', 'libraries')) }}: - Ubuntu.1804.Amd64.Open - ${{ if and(eq(variables['System.TeamProject'], 'public'), notIn(parameters.jobParameters.helixQueueGroup, 'pr', 'ci', 'libraries')) }}: - - Debian.9.Amd64.Open - - Ubuntu.1604.Amd64.Open + - (Debian.10.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-amd64-20210304164434-56c6673 + - (Debian.11.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64-20210304164428-5a7c380 - Ubuntu.1804.Amd64.Open - (Centos.8.Amd64.Open)Ubuntu.1604.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-8-helix-20201229003624-c1bf759 - RedHat.7.Amd64.Open - ${{ if eq(variables['System.TeamProject'], 'internal') }}: - - Debian.9.Amd64 - - Ubuntu.1604.Amd64 + - (Debian.10.Amd64)Ubuntu.1804.amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-amd64-20210304164434-56c6673 + - (Debian.11.Amd64)Ubuntu.1804.amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64-20210304164428-5a7c380 - Ubuntu.1804.Amd64 - (Centos.8.Amd64)Ubuntu.1604.amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-8-helix-20201229003624-c1bf759 - (Fedora.34.Amd64)Ubuntu.1604.amd64@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-34-helix-20210728124700-4f64125 diff --git a/eng/pipelines/coreclr/templates/run-performance-job.yml b/eng/pipelines/coreclr/templates/run-performance-job.yml index 3e95e9c30999af..596339fc05c182 100644 --- a/eng/pipelines/coreclr/templates/run-performance-job.yml +++ b/eng/pipelines/coreclr/templates/run-performance-job.yml @@ -23,7 +23,7 @@ parameters: runKind: '' # required -- test category logicalMachine: '' # required -- Used to specify a which pool of machines the test should run against javascriptEngine: 'NoJS' - + jobs: - template: xplat-pipeline-job.yml parameters: @@ -36,7 +36,7 @@ jobs: enableTelemetry: ${{ parameters.enableTelemetry }} enablePublishBuildArtifacts: true continueOnError: ${{ parameters.continueOnError }} - + ${{ if ne(parameters.displayName, '') }}: displayName: '${{ parameters.displayName }}' ${{ if eq(parameters.displayName, '') }}: @@ -57,7 +57,7 @@ jobs: - HelixApiAccessToken: '' - HelixPreCommandStemWindows: 'set ORIGPYPATH=%PYTHONPATH%;py -m pip install -U pip;py -3 -m venv %HELIX_WORKITEM_PAYLOAD%\.venv;call %HELIX_WORKITEM_PAYLOAD%\.venv\Scripts\activate.bat;set PYTHONPATH=;py -3 -m pip install -U pip;py -3 -m pip install azure.storage.blob==12.0.0;py -3 -m pip install azure.storage.queue==12.0.0;set "PERFLAB_UPLOAD_TOKEN=$(PerfCommandUploadToken)"' - HelixPreCommandStemLinux: 'export ORIGPYPATH=$PYTHONPATH;python3 -m pip install -U pip;sudo apt-get -y install python3-venv;python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/bin/activate;export PYTHONPATH=;python3 -m pip install -U pip;pip3 install azure.storage.blob==12.0.0;pip3 install azure.storage.queue==12.0.0;sudo apt-get update;sudo apt -y install curl dirmngr apt-transport-https lsb-release ca-certificates;curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -;sudo apt-get -y install nodejs;sudo apt-get -y install npm;npm install --prefix $HELIX_WORKITEM_PAYLOAD jsvu -g;$HELIX_WORKITEM_PAYLOAD/bin/jsvu --os=linux64 --engines=v8,javascriptcore;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"' - - HelixPreCommandStemMsul: 'export ORIGPYPATH=$PYTHONPATH;sudo apk add icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib;sudo apk add cargo --repository http://dl-cdn.alpinelinux.org/alpine/v3.12/community ;sudo apk add libgdiplus --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing; python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/bin/activate;export PYTHONPATH=;python3 -m pip install -U pip;pip3 install azure.storage.blob==12.7.1;pip3 install azure.storage.queue==12.1.5;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"' + - HelixPreCommandStemMusl: 'export ORIGPYPATH=$PYTHONPATH;sudo apk add icu-libs krb5-libs libgcc libintl libssl1.1 libstdc++ zlib cargo;sudo apk add libgdiplus --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing; python3 -m venv $HELIX_WORKITEM_PAYLOAD/.venv;source $HELIX_WORKITEM_PAYLOAD/.venv/bin/activate;export PYTHONPATH=;python3 -m pip install -U pip;pip3 install azure.storage.blob==12.7.1;pip3 install azure.storage.queue==12.1.5;export PERFLAB_UPLOAD_TOKEN="$(PerfCommandUploadTokenLinux)"' - ExtraMSBuildLogsWindows: 'set MSBUILDDEBUGCOMM=1;set "MSBUILDDEBUGPATH=%HELIX_WORKITEM_UPLOAD_ROOT%"' - ExtraMSBuildLogsLinux: 'export MSBUILDDEBUGCOMM=1;export "MSBUILDDEBUGPATH=$HELIX_WORKITEM_UPLOAD_ROOT"' - HelixPreCommand: '' @@ -70,7 +70,7 @@ jobs: - IsInternal: -Internal - ${{ if ne(parameters.osGroup, 'windows') }}: - ${{ if eq(parameters.osSubGroup, '_musl') }}: - - HelixPreCommand: $(HelixPreCommandStemMsul);$(ExtraMSBuildLogsLinux) + - HelixPreCommand: $(HelixPreCommandStemMusl);$(ExtraMSBuildLogsLinux) - HelixPostCommand: 'export PYTHONPATH=$ORIGPYPATH' - IsInternal: --internal - ${{ if ne(parameters.osSubGroup, '_musl') }}: @@ -85,7 +85,7 @@ jobs: - HelixPreCommand: $(ExtraMSBuildLogsWindows) - ${{ if ne(parameters.osGroup, 'windows') }}: - HelixPreCommand: $(ExtraMSBuildLogsLinux);npm install --prefix $HELIX_WORKITEM_PAYLOAD jsvu -g;$HELIX_WORKITEM_PAYLOAD/bin/jsvu --os=linux64 --engines=v8,javascriptcore - + - ${{ if and(eq(parameters.codeGenType, 'Interpreter'), eq(parameters.runtimeType, 'mono')) }}: - ${{ if eq( parameters.osGroup, 'windows') }}: diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 880aa8939932c0..5a82951839ff4a 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -29,7 +29,8 @@ jobs: # Linux arm - ${{ if eq(parameters.platform, 'Linux_arm') }}: - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}: - - (Debian.9.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-9-helix-arm32v7-bfcd90a-20200121150037 + - (Debian.10.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-arm32v7-20210304164340-6616c63 + - (Debian.11.Arm32.Open)Ubuntu.1804.ArmArch.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-arm32v7-20210304164347-5a7c380 # Linux arm64 - ${{ if eq(parameters.platform, 'Linux_arm64') }}: @@ -40,15 +41,14 @@ jobs: # Linux musl x64 - ${{ if eq(parameters.platform, 'Linux_musl_x64') }}: - - ${{ if eq(parameters.jobParameters.isFullMatrix, false) }}: - - (Alpine.312.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.12-helix-20200602002622-e06dc59 + - (Alpine.314.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.14-helix-amd64-20210910135833-1848e19 - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}: - - (Alpine.312.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.12-helix-20200601195603-e06dc59 + - (Alpine.313.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.13-helix-amd64-20210910135845-8a6f4f3 # Linux musl arm64 - - ${{ if eq(parameters.platform, 'Linux_musl_arm64') }}: - - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}: - - (Alpine.312.Arm64.Open)ubuntu.1804.armarch.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.12-helix-arm64v8-20200602002604-25f8a3e + - ${{ if and(eq(parameters.platform, 'Linux_musl_arm64'), eq(parameters.jobParameters.isFullMatrix, true)) }}: + - (Alpine.313.Arm64.Open)ubuntu.1804.armarch.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.13-helix-arm64v8-20210910135808-8a6f4f3 + - (Alpine.314.Arm64.Open)ubuntu.1804.armarch.open@mcr.microsoft.com/dotnet-buildtools/prereqs:alpine-3.14-helix-arm64v8-20210910135810-8a6f4f3 # Linux x64 - ${{ if eq(parameters.platform, 'Linux_x64') }}: @@ -57,33 +57,30 @@ jobs: - (Centos.8.Amd64.Open)Ubuntu.1604.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-8-helix-20201229003624-c1bf759 - RedHat.7.Amd64.Open - SLES.15.Amd64.Open - - (Fedora.34.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-34-helix-20210728124700-4f64125 + - (Fedora.34.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-34-helix-20210913123654-4f64125 - (Ubuntu.1910.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-19.10-helix-amd64-cfcfd50-20191030180623 - (Debian.10.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-amd64-bfcd90a-20200121150006 - ${{ if or(ne(parameters.jobParameters.testScope, 'outerloop'), ne(parameters.jobParameters.runtimeFlavor, 'mono')) }}: - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}: + - (Centos.7.Amd64.Open)Ubuntu.1604.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-7-mlnet-helix-20210714125435-dde38af - (Centos.8.Amd64.Open)Ubuntu.1604.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-8-helix-20201229003624-c1bf759 - RedHat.7.Amd64.Open - - Debian.9.Amd64.Open - - Ubuntu.1604.Amd64.Open - Ubuntu.1804.Amd64.Open - SLES.12.Amd64.Open - SLES.15.Amd64.Open - - (Fedora.34.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-34-helix-20210728124700-4f64125 + - (Fedora.34.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-34-helix-20210913123654-4f64125 - (Ubuntu.1910.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:ubuntu-19.10-helix-amd64-cfcfd50-20191030180623 - - (Debian.10.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-amd64-bfcd90a-20200121150006 + - (Debian.10.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-amd64-20210304164434-56c6673 + - (Debian.11.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-11-helix-amd64-20210304164428-5a7c380 - (Mariner.1.0.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:cbl-mariner-1.0-helix-20210528192219-92bf620 - ${{ if eq(parameters.jobParameters.isFullMatrix, false) }}: - - (Centos.8.Amd64.Open)Ubuntu.1604.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-8-helix-20201229003624-c1bf759 + - (Centos.7.Amd64.Open)Ubuntu.1604.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:centos-7-mlnet-helix-20210714125435-dde38af - RedHat.7.Amd64.Open - - (Debian.10.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-amd64-bfcd90a-20200121150006 - - Ubuntu.1604.Amd64.Open + - (Debian.10.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-amd64-20210304164434-56c6673 - Ubuntu.1804.Amd64.Open - - SLES.15.Amd64.Open - - (Fedora.34.Amd64.Open)ubuntu.1604.amd64.open@mcr.microsoft.com/dotnet-buildtools/prereqs:fedora-34-helix-20210728124700-4f64125 - ${{ if or(eq(parameters.jobParameters.interpreter, 'true'), eq(parameters.jobParameters.isSingleFile, true)) }}: # Limiting interp runs as we don't need as much coverage. - - Debian.9.Amd64.Open + - (Debian.10.Amd64.Open)Ubuntu.1804.Amd64.Open@mcr.microsoft.com/dotnet-buildtools/prereqs:debian-10-helix-amd64-20210304164434-56c6673 # OSX arm64 - ${{ if eq(parameters.platform, 'OSX_arm64') }}: @@ -92,11 +89,9 @@ jobs: # OSX x64 - ${{ if eq(parameters.platform, 'OSX_x64') }}: - ${{ if eq(parameters.jobParameters.isFullMatrix, true) }}: - - OSX.1013.Amd64.Open - OSX.1014.Amd64.Open - OSX.1015.Amd64.Open - ${{ if eq(parameters.jobParameters.isFullMatrix, false) }}: - - OSX.1014.Amd64.Open - OSX.1015.Amd64.Open # Android @@ -139,6 +134,7 @@ jobs: - ${{ if ne(parameters.jobParameters.isFullMatrix, true) }}: - Windows.81.Amd64.Open - Windows.10.Amd64.Server19H1.ES.Open + - Windows.11.Amd64.ClientPre.Open - ${{ if eq(parameters.jobParameters.testScope, 'outerloop') }}: - (Windows.Server.Core.1909.Amd64.Open)windows.10.amd64.server20h1.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-2004-helix-amd64-20200904200251-272704c - ${{ if ne(parameters.jobParameters.runtimeFlavor, 'mono') }}: diff --git a/eng/pipelines/libraries/stress/http.yml b/eng/pipelines/libraries/stress/http.yml index b2f586f805b676..41a74be067832e 100644 --- a/eng/pipelines/libraries/stress/http.yml +++ b/eng/pipelines/libraries/stress/http.yml @@ -50,7 +50,7 @@ jobs: - bash: | cd '$(httpStressProject)' - export HTTPSTRESS_CLIENT_ARGS="$HTTPSTRESS_CLIENT_ARGS -http 3.0 -xops 10" + export HTTPSTRESS_CLIENT_ARGS="$HTTPSTRESS_CLIENT_ARGS -http 3.0" export HTTPSTRESS_SERVER_ARGS="$HTTPSTRESS_SERVER_ARGS -http 3.0" docker-compose up --abort-on-container-exit --no-color displayName: Run HttpStress - HTTP 3.0 diff --git a/eng/pipelines/official/stages/publish.yml b/eng/pipelines/official/stages/publish.yml index 10c6297566ad5a..6ecc48c3835cf9 100644 --- a/eng/pipelines/official/stages/publish.yml +++ b/eng/pipelines/official/stages/publish.yml @@ -19,7 +19,8 @@ stages: publishUsingPipelines: true dependsOn: PrepareSignedArtifacts pool: - vmImage: vs2017-win2016 + name: NetCore1ESPool-Svc-Internal + demands: ImageOverride -equals Build.Windows.10.Amd64.VS2019 # Stages-based publishing entry point - template: /eng/common/templates/post-build/post-build.yml diff --git a/global.json b/global.json index 38978a4a66c62a..a8cba13f4f7149 100644 --- a/global.json +++ b/global.json @@ -12,10 +12,10 @@ "python3": "3.7.1" }, "msbuild-sdks": { - "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "6.0.0-beta.21560.2", - "Microsoft.DotNet.Arcade.Sdk": "6.0.0-beta.21560.2", - "Microsoft.DotNet.Helix.Sdk": "6.0.0-beta.21560.2", - "Microsoft.DotNet.SharedFramework.Sdk": "6.0.0-beta.21560.2", + "Microsoft.DotNet.Build.Tasks.TargetFramework.Sdk": "6.0.0-beta.21609.4", + "Microsoft.DotNet.Arcade.Sdk": "6.0.0-beta.21609.4", + "Microsoft.DotNet.Helix.Sdk": "6.0.0-beta.21609.4", + "Microsoft.DotNet.SharedFramework.Sdk": "6.0.0-beta.21609.4", "Microsoft.Build.NoTargets": "3.1.0", "Microsoft.Build.Traversal": "3.0.23", "Microsoft.NET.Sdk.IL": "6.0.0-rc.1.21415.6" diff --git a/src/coreclr/debug/dbgutil/machoreader.cpp b/src/coreclr/debug/dbgutil/machoreader.cpp index 48fea72682f205..d2801547cb9ba9 100644 --- a/src/coreclr/debug/dbgutil/machoreader.cpp +++ b/src/coreclr/debug/dbgutil/machoreader.cpp @@ -126,19 +126,41 @@ MachOModule::TryLookupSymbol(const char* symbolName, uint64_t* symbolValue) _ASSERTE(m_nlists != nullptr); _ASSERTE(m_strtabAddress != 0); - for (int i = 0; i < m_dysymtabCommand->nextdefsym; i++) + // First, search just the "external" export symbols + if (TryLookupSymbol(m_dysymtabCommand->iextdefsym, m_dysymtabCommand->nextdefsym, symbolName, symbolValue)) { - std::string name = GetSymbolName(i); - // Skip the leading underscores to match Linux externs - if (name[0] == '_') - { - name.erase(0, 1); - } - if (strcmp(name.c_str(), symbolName) == 0) - { - *symbolValue = m_loadBias + m_nlists[i].n_value; - return true; - } + m_reader.Trace("SYM: Found '%s' in external symbols\n", symbolName); + return true; + } + m_reader.Trace("SYM: Missed '%s' in external symbols\n", symbolName); + + // If not found in external symbols, search all of them + if (TryLookupSymbol(0, m_symtabCommand->nsyms, symbolName, symbolValue)) + { + m_reader.Trace("SYM: Found '%s' in all symbols\n", symbolName); + return true; + } + m_reader.Trace("SYM: Missed '%s' in all symbols\n", symbolName); + } + *symbolValue = 0; + return false; +} + +bool +MachOModule::TryLookupSymbol(int start, int nsyms, const char* symbolName, uint64_t* symbolValue) +{ + for (int i = 0; i < nsyms; i++) + { + std::string name = GetSymbolName(start + i); + + // Skip the leading underscores to match Linux externs + const char* currentName = name.length() > 0 && name[0] == '_' ? name.c_str() + 1 : name.c_str(); + + // Does this symbol match? + if (strcmp(currentName, symbolName) == 0) + { + *symbolValue = m_loadBias + m_nlists[start + i].n_value; + return true; } } *symbolValue = 0; @@ -263,26 +285,30 @@ MachOModule::ReadSymbolTable() _ASSERTE(m_symtabCommand != nullptr); _ASSERTE(m_strtabAddress == 0); - m_reader.TraceVerbose("SYM: symoff %08x nsyms %d stroff %08x strsize %d iext %d next %d\n", + m_reader.TraceVerbose("SYM: symoff %08x nsyms %d stroff %08x strsize %d iext %d next %d iundef %d nundef %d extref %d nextref %d\n", m_symtabCommand->symoff, m_symtabCommand->nsyms, m_symtabCommand->stroff, m_symtabCommand->strsize, m_dysymtabCommand->iextdefsym, - m_dysymtabCommand->nextdefsym); - - // Read the external symbol part of symbol table. An array of "nlist" structs. - void* extSymbolTableAddress = (void*)(GetAddressFromFileOffset(m_symtabCommand->symoff) + (m_dysymtabCommand->iextdefsym * sizeof(nlist_64))); - size_t symtabSize = sizeof(nlist_64) * m_dysymtabCommand->nextdefsym; + m_dysymtabCommand->nextdefsym, + m_dysymtabCommand->iundefsym, + m_dysymtabCommand->nundefsym, + m_dysymtabCommand->extrefsymoff, + m_dysymtabCommand->nextrefsyms); + + // Read the entire symbol part of symbol table. An array of "nlist" structs. + void* symbolTableAddress = (void*)GetAddressFromFileOffset(m_symtabCommand->symoff); + size_t symtabSize = sizeof(nlist_64) * m_symtabCommand->nsyms; m_nlists = (nlist_64*)malloc(symtabSize); if (m_nlists == nullptr) { - m_reader.Trace("ERROR: Failed to allocate %zu byte external symbol table\n", symtabSize); + m_reader.Trace("ERROR: Failed to allocate %zu byte symtab\n", symtabSize); return false; } - if (!m_reader.ReadMemory(extSymbolTableAddress, m_nlists, symtabSize)) + if (!m_reader.ReadMemory(symbolTableAddress, m_nlists, symtabSize)) { - m_reader.Trace("ERROR: Failed to read external symtab at %p of %zu\n", extSymbolTableAddress, symtabSize); + m_reader.Trace("ERROR: Failed to read symtab at %p of %zu\n", symbolTableAddress, symtabSize); return false; } diff --git a/src/coreclr/debug/dbgutil/machoreader.h b/src/coreclr/debug/dbgutil/machoreader.h index bb9ffe0fdd7ceb..a5f458b17ff2d5 100644 --- a/src/coreclr/debug/dbgutil/machoreader.h +++ b/src/coreclr/debug/dbgutil/machoreader.h @@ -37,6 +37,7 @@ class MachOModule bool ReadHeader(); bool TryLookupSymbol(const char* symbolName, uint64_t* symbolValue); + bool TryLookupSymbol(int start, int nsyms, const char* symbolName, uint64_t* symbolValue); bool EnumerateSegments(); private: diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index dcf1768c60a7dd..4ba948ec4793c5 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -486,13 +486,14 @@ regMaskTP CodeGenInterface::genGetRegMask(const LclVarDsc* varDsc) assert(varDsc->lvIsInReg()); - if (varTypeUsesFloatReg(varDsc->TypeGet())) + regNumber reg = varDsc->GetRegNum(); + if (genIsValidFloatReg(reg)) { - regMask = genRegMaskFloat(varDsc->GetRegNum(), varDsc->TypeGet()); + regMask = genRegMaskFloat(reg, varDsc->GetRegisterType()); } else { - regMask = genRegMask(varDsc->GetRegNum()); + regMask = genRegMask(reg); } return regMask; } @@ -7148,8 +7149,9 @@ void CodeGen::genFnProlog() if (isInReg) { - regMaskTP regMask = genRegMask(varDsc->GetRegNum()); - if (!varDsc->IsFloatRegType()) + regNumber regForVar = varDsc->GetRegNum(); + regMaskTP regMask = genRegMask(regForVar); + if (!genIsValidFloatReg(regForVar)) { initRegs |= regMask; @@ -12551,6 +12553,17 @@ void CodeGen::genPoisonFrame(regMaskTP regLiveIn) assert(varDsc->lvOnFrame); + int size = (int)compiler->lvaLclSize(varNum); + + if ((size / TARGET_POINTER_SIZE) > 16) + { + // For very large structs the offsets in the movs we emit below can + // grow too large to be handled properly by JIT. Furthermore, while + // this is only debug code, for very large structs this can bloat + // the code too much due to the singular movs used. + continue; + } + if (!hasPoisonImm) { #ifdef TARGET_64BIT @@ -12568,8 +12581,7 @@ void CodeGen::genPoisonFrame(regMaskTP regLiveIn) #else int addr = 0; #endif - int size = (int)compiler->lvaLclSize(varNum); - int end = addr + size; + int end = addr + size; for (int offs = addr; offs < end;) { #ifdef TARGET_64BIT diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index f58a8db0997e3c..94da35b01c172e 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -51,19 +51,16 @@ void CodeGen::genInitializeRegisterState() continue; } - // Is this a floating-point argument? - if (varDsc->IsFloatRegType()) + if (varDsc->lvAddrExposed) { continue; } - noway_assert(!varTypeUsesFloatReg(varDsc->TypeGet())); - // Mark the register as holding the variable - assert(varDsc->GetRegNum() != REG_STK); - if (!varDsc->lvAddrExposed) + regNumber reg = varDsc->GetRegNum(); + if (genIsValidIntReg(reg)) { - regSet.verifyRegUsed(varDsc->GetRegNum()); + regSet.verifyRegUsed(reg); } } } diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 2c35262a5df0db..cca34ff20bbb38 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -2170,7 +2170,7 @@ VarName Compiler::compVarName(regNumber reg, bool isFloatReg) /* If the variable is not in a register, or not in the register we're looking for, quit. */ /* Also, if it is a compiler generated variable (i.e. slot# > info.compVarScopesCount), don't bother. */ if ((varDsc->lvRegister != 0) && (varDsc->GetRegNum() == reg) && - (varDsc->IsFloatRegType() || !isFloatReg) && (varDsc->lvSlotNum < info.compVarScopesCount)) + (varDsc->lvSlotNum < info.compVarScopesCount)) { /* check if variable in that register is live */ if (VarSetOps::IsMember(this, compCurLife, varDsc->lvVarIndex)) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index cabde31d62a11f..b928060d722480 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -961,10 +961,6 @@ class LclVarDsc Compiler* pComp, RefCountState state = RCS_NORMAL, bool propagate = true); - bool IsFloatRegType() const - { - return varTypeUsesFloatReg(lvType) || lvIsHfaRegArg(); - } var_types GetHfaType() const { diff --git a/src/coreclr/utilcode/clrconfig.cpp b/src/coreclr/utilcode/clrconfig.cpp index 59d32c0c43091d..ca6e095504313b 100644 --- a/src/coreclr/utilcode/clrconfig.cpp +++ b/src/coreclr/utilcode/clrconfig.cpp @@ -410,7 +410,7 @@ namespace // // Arguments: // * info - see file:../inc/CLRConfig.h for details. -// +// * isDefault - the value was not set or had an invalid format so the default was returned. // * result - the result. // // Return value: @@ -431,9 +431,7 @@ DWORD CLRConfig::GetConfigValue(const ConfigDWORDInfo & info, /* [Out] */ bool * DWORD resultMaybe; HRESULT hr = GetConfigDWORD(info.name, info.defaultValue, &resultMaybe, info.options); - - // Ignore the default value even if it's set explicitly. - if (resultMaybe != info.defaultValue) + if (SUCCEEDED(hr)) { *isDefault = false; return resultMaybe; diff --git a/src/coreclr/vm/ilmarshalers.h b/src/coreclr/vm/ilmarshalers.h index ba07cd5b55c175..8d24d07500472d 100644 --- a/src/coreclr/vm/ilmarshalers.h +++ b/src/coreclr/vm/ilmarshalers.h @@ -988,11 +988,19 @@ class ILMarshaler m_nativeHome.InitHome(ILStubMarshalHome::HomeType_ILByrefLocal, pcsSetup->NewLocal(nativeFieldTypeByRef), &nativeType, /* unalignedIndirectStore */ true); + // During the cleanup pass, the managed typed is explicitly passed as null - see DestroyStructure(). This works + // except if the type has nested non-blittable fields. Not checking for null will compute invalid offsets that + // can cause an access violation during the field clean-up. + ILCodeLabel *pSkipComputeOffsetLabel = pcsSetup->NewCodeLabel(); + pcsSetup->EmitNOP("// field setup {"); pcsSetup->EmitNOP("// managed field setup {"); pcsSetup->EmitLDARG(StructMarshalStubs::MANAGED_STRUCT_ARGIDX); + pcsSetup->EmitDUP(); + pcsSetup->EmitBRFALSE(pSkipComputeOffsetLabel); pcsSetup->EmitLDC(managedOffset); pcsSetup->EmitADD(); + pcsSetup->EmitLabel(pSkipComputeOffsetLabel); EmitStoreManagedHomeAddr(pcsSetup); pcsSetup->EmitNOP("// } managed field setup"); pcsSetup->EmitNOP("// native field setup {"); diff --git a/src/installer/pkg/sfx/installers/dotnet-host.proj b/src/installer/pkg/sfx/installers/dotnet-host.proj index 7a54d385a4fa50..184770cb8c6089 100644 --- a/src/installer/pkg/sfx/installers/dotnet-host.proj +++ b/src/installer/pkg/sfx/installers/dotnet-host.proj @@ -4,6 +4,7 @@ true dotnet-host dotnet-host-internal + / Host NetCore.SharedHost true @@ -18,9 +19,6 @@ false osx_scripts/host The .NET Shared Host. - $(MSBuildThisFileDirectory)rpm_scripts/host - $(RpmScriptsDirectory)/after_install.sh - $(RpmScriptsDirectory)/after_remove.sh {FD6988BF-5CCB-4202-3752-072442B1070B} {97C9F490-5379-6902-7B80-D2723CA59D95} @@ -44,21 +42,37 @@ + + <_DestinationPath>$(OutputPath) + <_DestinationPath Condition="'$(BuildRpmPackage)' == 'true'">$(OutputPath)usr/share/dotnet/ + <_UsrBinPath>$(OutputPath)usr/bin/ + + + + + + Destination="$(_DestinationPath)dotnet$(ExeSuffix)" /> + Destination="$(_DestinationPath)ThirdPartyNotices.txt" /> + + + + @@ -80,8 +94,6 @@ - - diff --git a/src/installer/tests/HostActivation.Tests/StartupHooks.cs b/src/installer/tests/HostActivation.Tests/StartupHooks.cs index a0533a60fd4772..3e1685356167f9 100644 --- a/src/installer/tests/HostActivation.Tests/StartupHooks.cs +++ b/src/installer/tests/HostActivation.Tests/StartupHooks.cs @@ -13,6 +13,7 @@ public class StartupHooks : IClassFixture { private SharedTestState sharedTestState; private string startupHookVarName = "DOTNET_STARTUP_HOOKS"; + private string startupHookRuntimeConfigName = "STARTUP_HOOKS"; private string startupHookSupport = "System.StartupHookProvider.IsSupported"; public StartupHooks(StartupHooks.SharedTestState fixture) @@ -105,6 +106,64 @@ public void Muxer_activation_of_Multiple_StartupHooks_Succeeds() .And.HaveStdOutContaining("Hello World"); } + [Fact] + public void Muxer_activation_of_RuntimeConfig_StartupHook_Succeeds() + { + var fixture = sharedTestState.PortableAppFixture.Copy(); + var dotnet = fixture.BuiltDotnet; + var appDll = fixture.TestProject.AppDll; + + var startupHookFixture = sharedTestState.StartupHookFixture.Copy(); + var startupHookDll = startupHookFixture.TestProject.AppDll; + + RuntimeConfig.FromFile(fixture.TestProject.RuntimeConfigJson) + .WithProperty(startupHookRuntimeConfigName, startupHookDll) + .Save(); + + // RuntimeConfig defined startup hook + dotnet.Exec(appDll) + .CaptureStdOut() + .CaptureStdErr() + .Execute() + .Should().Pass() + .And.HaveStdOutContaining("Hello from startup hook!") + .And.HaveStdOutContaining("Hello World"); + } + + [Fact] + public void Muxer_activation_of_RuntimeConfig_And_Environment_StartupHooks_SucceedsInExpectedOrder() + { + var fixture = sharedTestState.PortableAppFixture.Copy(); + var dotnet = fixture.BuiltDotnet; + var appDll = fixture.TestProject.AppDll; + + var startupHookFixture = sharedTestState.StartupHookFixture.Copy(); + var startupHookDll = startupHookFixture.TestProject.AppDll; + + RuntimeConfig.FromFile(fixture.TestProject.RuntimeConfigJson) + .WithProperty(startupHookRuntimeConfigName, startupHookDll) + .Save(); + + var startupHook2Fixture = sharedTestState.StartupHookWithDependencyFixture.Copy(); + var startupHook2Dll = startupHook2Fixture.TestProject.AppDll; + + // include any char to counter output from other threads such as in #57243 + const string wildcardPattern = @"[\r\n\s.]*"; + + // RuntimeConfig and Environment startup hooks in expected order + dotnet.Exec(appDll) + .EnvironmentVariable(startupHookVarName, startupHook2Dll) + .CaptureStdOut() + .CaptureStdErr() + .Execute() + .Should().Pass() + .And.HaveStdOutMatching("Hello from startup hook with dependency!" + + wildcardPattern + + "Hello from startup hook!" + + wildcardPattern + + "Hello World"); + } + // Empty startup hook variable [Fact] public void Muxer_activation_of_Empty_StartupHook_Variable_Succeeds() diff --git a/src/installer/tests/Microsoft.DotNet.CoreSetup.Packaging.Tests/NETCoreTests.cs b/src/installer/tests/Microsoft.DotNet.CoreSetup.Packaging.Tests/NETCoreTests.cs index 65d19d7983c413..cda507f61480de 100644 --- a/src/installer/tests/Microsoft.DotNet.CoreSetup.Packaging.Tests/NETCoreTests.cs +++ b/src/installer/tests/Microsoft.DotNet.CoreSetup.Packaging.Tests/NETCoreTests.cs @@ -18,7 +18,7 @@ public void NETCoreTargetingPackIsValid() "Microsoft.NETCore.App.Ref")) { // Allow no targeting pack in case this is a servicing build. - // This condition should be tightened: https://github.com/dotnet/core-setup/issues/8830 + // This condition should be tightened: https://github.com/dotnet/runtime/issues/3836 if (tester == null) { return; diff --git a/src/installer/tests/Microsoft.DotNet.CoreSetup.Packaging.Tests/NuGetArtifactTester.cs b/src/installer/tests/Microsoft.DotNet.CoreSetup.Packaging.Tests/NuGetArtifactTester.cs index 4af9206f6b3513..292e3522d961e1 100644 --- a/src/installer/tests/Microsoft.DotNet.CoreSetup.Packaging.Tests/NuGetArtifactTester.cs +++ b/src/installer/tests/Microsoft.DotNet.CoreSetup.Packaging.Tests/NuGetArtifactTester.cs @@ -41,10 +41,7 @@ public static NuGetArtifactTester OpenOrNull( "Shipping", $"{id}.{dirs.MicrosoftNETCoreAppVersion}.nupkg"); - // If the nuspec exists, the nupkg should exist. - Assert.True(File.Exists(nupkgPath)); - - return new NuGetArtifactTester(nupkgPath); + return File.Exists(nupkgPath) ? new NuGetArtifactTester(nupkgPath) : null; } public PackageIdentity Identity { get; } diff --git a/src/libraries/Common/src/Internal/Cryptography/HashProviderCng.cs b/src/libraries/Common/src/Internal/Cryptography/HashProviderCng.cs index 3b864790b25252..c905ca1bd6996e 100644 --- a/src/libraries/Common/src/Internal/Cryptography/HashProviderCng.cs +++ b/src/libraries/Common/src/Internal/Cryptography/HashProviderCng.cs @@ -127,10 +127,15 @@ public override void Reset() { if (_reusable && !_running) return; + DestroyHash(); + BCryptCreateHashFlags flags = _reusable ? + BCryptCreateHashFlags.BCRYPT_HASH_REUSABLE_FLAG : + BCryptCreateHashFlags.None; + SafeBCryptHashHandle hHash; - NTSTATUS ntStatus = Interop.BCrypt.BCryptCreateHash(_hAlgorithm, out hHash, IntPtr.Zero, 0, _key, _key == null ? 0 : _key.Length, BCryptCreateHashFlags.None); + NTSTATUS ntStatus = Interop.BCrypt.BCryptCreateHash(_hAlgorithm, out hHash, IntPtr.Zero, 0, _key, _key == null ? 0 : _key.Length, flags); if (ntStatus != NTSTATUS.STATUS_SUCCESS) throw Interop.BCrypt.CreateCryptographicException(ntStatus); diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs b/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs index 35121fc86ebc34..d9fa37e8cf8343 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/src/MemoryCache.cs @@ -395,9 +395,10 @@ public void Compact(double percentage) private void Compact(long removalSizeTarget, Func computeEntrySize) { var entriesToRemove = new List(); - var lowPriEntries = new List(); - var normalPriEntries = new List(); - var highPriEntries = new List(); + // cache LastAccessed outside of the CacheEntry so it is stable during compaction + var lowPriEntries = new List(); + var normalPriEntries = new List(); + var highPriEntries = new List(); long removedSize = 0; // Sort items by expired & priority status @@ -415,13 +416,13 @@ private void Compact(long removalSizeTarget, Func computeEntry switch (entry.Priority) { case CacheItemPriority.Low: - lowPriEntries.Add(entry); + lowPriEntries.Add(new CompactPriorityEntry(entry, entry.LastAccessed)); break; case CacheItemPriority.Normal: - normalPriEntries.Add(entry); + normalPriEntries.Add(new CompactPriorityEntry(entry, entry.LastAccessed)); break; case CacheItemPriority.High: - highPriEntries.Add(entry); + highPriEntries.Add(new CompactPriorityEntry(entry, entry.LastAccessed)); break; case CacheItemPriority.NeverRemove: break; @@ -445,7 +446,7 @@ private void Compact(long removalSizeTarget, Func computeEntry // ?. Items with the soonest absolute expiration. // ?. Items with the soonest sliding expiration. // ?. Larger objects - estimated by object graph size, inaccurate. - static void ExpirePriorityBucket(ref long removedSize, long removalSizeTarget, Func computeEntrySize, List entriesToRemove, List priorityEntries) + static void ExpirePriorityBucket(ref long removedSize, long removalSizeTarget, Func computeEntrySize, List entriesToRemove, List priorityEntries) { // Do we meet our quota by just removing expired entries? if (removalSizeTarget <= removedSize) @@ -458,9 +459,10 @@ static void ExpirePriorityBucket(ref long removedSize, long removalSizeTarget, F // TODO: Refine policy // LRU - priorityEntries.Sort((e1, e2) => e1.LastAccessed.CompareTo(e2.LastAccessed)); - foreach (CacheEntry entry in priorityEntries) + priorityEntries.Sort(static (e1, e2) => e1.LastAccessed.CompareTo(e2.LastAccessed)); + foreach (CompactPriorityEntry priorityEntry in priorityEntries) { + CacheEntry entry = priorityEntry.Entry; entry.SetExpired(EvictionReason.Capacity); entriesToRemove.Add(entry); removedSize += computeEntrySize(entry); @@ -473,6 +475,20 @@ static void ExpirePriorityBucket(ref long removedSize, long removalSizeTarget, F } } + // use a struct instead of a ValueTuple to avoid adding a new dependency + // on System.ValueTuple on .NET Framework in a servicing release + private readonly struct CompactPriorityEntry + { + public readonly CacheEntry Entry; + public readonly DateTimeOffset LastAccessed; + + public CompactPriorityEntry(CacheEntry entry, DateTimeOffset lastAccessed) + { + Entry = entry; + LastAccessed = lastAccessed; + } + } + public void Dispose() { Dispose(true); diff --git a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/CompactTests.cs b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/CompactTests.cs index 3d9c2625b19ed9..10b9cce7c4d459 100644 --- a/src/libraries/Microsoft.Extensions.Caching.Memory/tests/CompactTests.cs +++ b/src/libraries/Microsoft.Extensions.Caching.Memory/tests/CompactTests.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Threading; +using System.Threading.Tasks; using Microsoft.Extensions.Internal; using Xunit; @@ -83,4 +85,60 @@ public void CompactPrioritizesLRU() Assert.Equal("value4", cache.Get("key4")); } } + + [CollectionDefinition(nameof(DisableParallelization), DisableParallelization = true)] + public class DisableParallelization { } + + [Collection(nameof(DisableParallelization))] + public class CompactTestsDisableParallelization + { + /// + /// Tests a race condition in Compact where CacheEntry.LastAccessed is getting updated + /// by a different thread than what is doing the Compact, leading to sorting failing. + /// + /// See https://github.com/dotnet/runtime/issues/61032. + /// + [Fact] + public void CompactLastAccessedRaceCondition() + { + const int numEntries = 100; + MemoryCache cache = new MemoryCache(new MemoryCacheOptions()); + Random random = new Random(); + + void FillCache() + { + for (int i = 0; i < numEntries; i++) + { + cache.Set($"key{i}", $"value{i}"); + } + } + + // start a few tasks to access entries in the background + Task[] backgroundAccessTasks = new Task[Environment.ProcessorCount]; + bool done = false; + + for (int i = 0; i < backgroundAccessTasks.Length; i++) + { + backgroundAccessTasks[i] = Task.Run(async () => + { + while (!done) + { + cache.TryGetValue($"key{random.Next(numEntries)}", out _); + await Task.Yield(); + } + }); + } + + for (int i = 0; i < 1000; i++) + { + FillCache(); + + cache.Compact(1); + } + + done = true; + + Task.WaitAll(backgroundAccessTasks); + } + } } diff --git a/src/libraries/Microsoft.VisualBasic.Core/Directory.Build.props b/src/libraries/Microsoft.VisualBasic.Core/Directory.Build.props index fac4b55f49cd7d..74f97da58b5daf 100644 --- a/src/libraries/Microsoft.VisualBasic.Core/Directory.Build.props +++ b/src/libraries/Microsoft.VisualBasic.Core/Directory.Build.props @@ -1,7 +1,13 @@  - $([MSBuild]::Add($(MajorVersion), 5)).$(MinorVersion).0.0 + + $([MSBuild]::Add($(MajorVersion), 5)) + $(MajorVersion).$(MinorVersion).0.0 + + 1 Microsoft true diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj b/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj index d9839c121271df..0fd6475b632d72 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj +++ b/src/libraries/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj @@ -1,4 +1,4 @@ - + true true diff --git a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Linux.cs b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Linux.cs index d67782f40ad36b..a2619871edecb4 100644 --- a/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Linux.cs +++ b/src/libraries/System.DirectoryServices.Protocols/src/System/DirectoryServices/Protocols/Interop/LdapPal.Linux.cs @@ -111,7 +111,7 @@ internal static int BindToDirectory(ConnectionHandle ld, string who, string pass passwordPtr = LdapPal.StringToPtr(passwd); berval passwordBerval = new berval { - bv_len = passwd.Length, + bv_len = passwd?.Length ?? 0, bv_val = passwordPtr, }; diff --git a/src/libraries/System.DirectoryServices.Protocols/tests/LdapConnectionTests.cs b/src/libraries/System.DirectoryServices.Protocols/tests/LdapConnectionTests.cs index 9a8074bf5222ad..a0522a61abc182 100644 --- a/src/libraries/System.DirectoryServices.Protocols/tests/LdapConnectionTests.cs +++ b/src/libraries/System.DirectoryServices.Protocols/tests/LdapConnectionTests.cs @@ -112,6 +112,16 @@ public void AuthType_SetValid_GetReturnsExpected() Assert.Equal(AuthType.Basic, connection.AuthType); } + [Fact] + public void AuthType_Anonymous_DoesNotThrowNull() + { + var connection = new LdapConnection("server"); + connection.AuthType = AuthType.Anonymous; + // When calling Bind we make sure that the exception thrown is not that there was a NullReferenceException + // trying to retrive a null password's lenght, but instead an LdapException given the server cannot be reached. + Assert.Throws(() => connection.Bind()); + } + [Theory] [InlineData(AuthType.Anonymous - 1)] [InlineData(AuthType.Kerberos + 1)] diff --git a/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs b/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs index eae275bc0b1a3e..c36ba960230ce6 100644 --- a/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs +++ b/src/libraries/System.Globalization/tests/System/Globalization/TextInfoTests.cs @@ -287,7 +287,7 @@ public static IEnumerable ToLower_TestData() } yield return new object[] { cultureName, "\u0130", "i" }; yield return new object[] { cultureName, "i", "i" }; - + } // ICU has special tailoring for the en-US-POSIX locale which treats "i" and "I" as different letters @@ -478,5 +478,13 @@ public void ToStringTest(string name, string expected) { Assert.Equal(expected, new CultureInfo(name).TextInfo.ToString()); } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] + [InlineData("es-ES")] + [InlineData("es-ES_tradnl")] + public void TestAsciiCodePageWithCulturesWithAlternativeSortNames(string cultureName) + { + Assert.Equal(1252, CultureInfo.GetCultureInfo(cultureName).TextInfo.ANSICodePage); + } } } diff --git a/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs b/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs index 9a0f5802d7dba0..d9b0b8c7a99ebc 100644 --- a/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs +++ b/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/Pipe.cs @@ -1082,7 +1082,7 @@ private void WriteMultiSegment(ReadOnlySpan source) } // We filled the segment - _writingHead.End += writable; + _writingHead.End += _writingHeadBytesBuffered; _writingHeadBytesBuffered = 0; // This is optimized to use pooled memory. That's why we pass 0 instead of diff --git a/src/libraries/System.IO.Pipelines/tests/PipeLengthTests.cs b/src/libraries/System.IO.Pipelines/tests/PipeLengthTests.cs index fcf9d7af55b053..fd9fc83833a8b1 100644 --- a/src/libraries/System.IO.Pipelines/tests/PipeLengthTests.cs +++ b/src/libraries/System.IO.Pipelines/tests/PipeLengthTests.cs @@ -277,5 +277,19 @@ public async Task NullExaminedAndConsumedNoops() ReadResult result = await _pipe.Reader.ReadAsync(); _pipe.Reader.AdvanceTo(default, default); } + + [Fact] + public async Task AdvanceFollowedByWriteAsyncTest() + { + Memory buffer = new byte[26]; + Pipe pipe = new(new PipeOptions(minimumSegmentSize: 1)); + + var mem = pipe.Writer.GetMemory(14)[..14]; + buffer[..14].CopyTo(mem); + pipe.Writer.Advance(14); + await pipe.Writer.WriteAsync(buffer[14..]); + ReadResult res = await pipe.Reader.ReadAsync(); + Assert.Equal(res.Buffer.Length, buffer.Length); + } } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs index c31e628159db0e..ee53b9e626c751 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeaders.cs @@ -1051,7 +1051,7 @@ private HeaderDescriptor GetHeaderDescriptor(string name) throw new InvalidOperationException(SR.Format(SR.net_http_headers_not_allowed_header_name, name)); } - private bool TryGetHeaderDescriptor(string name, out HeaderDescriptor descriptor) + internal bool TryGetHeaderDescriptor(string name, out HeaderDescriptor descriptor) { if (string.IsNullOrEmpty(name)) { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeadersNonValidated.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeadersNonValidated.cs index ad1a1850ea83c4..5e67476d116a99 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeadersNonValidated.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpHeadersNonValidated.cs @@ -32,7 +32,7 @@ namespace System.Net.Http.Headers /// true if the collection contains the header; otherwise, false. public bool Contains(string headerName) => _headers is HttpHeaders headers && - HeaderDescriptor.TryGet(headerName, out HeaderDescriptor descriptor) && + headers.TryGetHeaderDescriptor(headerName, out HeaderDescriptor descriptor) && headers.TryGetHeaderValue(descriptor, out _); /// Gets the values for the specified header name. @@ -62,7 +62,7 @@ public HeaderStringValues this[string headerName] public bool TryGetValues(string headerName, out HeaderStringValues values) { if (_headers is HttpHeaders headers && - HeaderDescriptor.TryGet(headerName, out HeaderDescriptor descriptor) && + headers.TryGetHeaderDescriptor(headerName, out HeaderDescriptor descriptor) && headers.TryGetHeaderValue(descriptor, out object? info)) { HttpHeaders.GetStoreValuesAsStringOrStringArray(descriptor, info, out string? singleValue, out string[]? multiValue); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs index 2879d37cb405c0..75b83fbe8bae61 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs @@ -1979,7 +1979,12 @@ public bool CleanCacheAndDisposeIfUnused() } // Dispose the stale connections outside the pool lock, to avoid holding the lock too long. - toDispose?.ForEach(c => c.Dispose()); + // Dispose them asynchronously to not to block the caller on closing the SslStream or NetworkStream. + if (toDispose is not null) + { + Task.Factory.StartNew(static s => ((List)s!).ForEach(c => c.Dispose()), toDispose, + CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); + } // Pool is active. Should not be removed. return false; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs index e257cb4c3e692f..f118d151c692ae 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs @@ -462,7 +462,7 @@ private void SetCleaningTimer(TimeSpan timeout) { try { - _cleaningTimer!.Change(timeout, timeout); + _cleaningTimer!.Change(timeout, Timeout.InfiniteTimeSpan); _timerIsRunning = timeout != Timeout.InfiniteTimeSpan; } catch (ObjectDisposedException) @@ -492,13 +492,10 @@ private void RemoveStalePools() } } - // Stop running the timer if we don't have any pools to clean up. + // Restart the timer if we have any pools to clean up. lock (SyncObj) { - if (_pools.IsEmpty) - { - SetCleaningTimer(Timeout.InfiniteTimeSpan); - } + SetCleaningTimer(!_pools.IsEmpty ? _cleanPoolTimeout : Timeout.InfiniteTimeSpan); } // NOTE: There is a possible race condition with regards to a pool getting cleaned up at the same diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile index 28c10ddfa8a086..02378956718778 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile @@ -10,9 +10,9 @@ COPY . . # Pulling the msquic Debian package from msquic-ci public pipeline and from a hardcoded build. # Note that this is a temporary solution until we have properly published Linux packages. # Also note that in order to update to a newer msquic build, you have update this link. -ARG MSQUIC_PACKAGE=libmsquic_1.6.0_amd64.deb -ARG PACKAGES_DIR=LinuxPackages -RUN wget 'https://dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_apis/build/builds/1266893/artifacts?artifactName=LinuxPackages&api-version=6.0&%24format=zip' -O "$PACKAGES_DIR".zip +ARG MSQUIC_PACKAGE=libmsquic_1.9.0_amd64.deb +ARG PACKAGES_DIR=UnsignedUnixPackages +RUN wget 'https://dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_apis/build/builds/1426627/artifacts?artifactName=UnsignedUnixPackages&api-version=6.0&%24format=zip' -O "$PACKAGES_DIR".zip RUN apt-get update RUN apt-get install unzip RUN unzip $PACKAGES_DIR.zip diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/HttpStress.csproj b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/HttpStress.csproj index 80b4aa21b108ba..770f3370a79ad4 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/HttpStress.csproj +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/HttpStress.csproj @@ -5,6 +5,7 @@ net6.0 preview enable + True @@ -20,4 +21,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeadersTest.cs b/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeadersTest.cs index f56f85ac5bd0d4..139422163a95bc 100644 --- a/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeadersTest.cs +++ b/src/libraries/System.Net.Http/tests/UnitTests/Headers/HttpHeadersTest.cs @@ -2112,6 +2112,44 @@ public void AddHeaders_SourceHasInvalidHeaderValues_InvalidHeadersRemovedFromSou Assert.False(destination.Contains("custom"), "destination contains 'custom' header."); } + [Fact] + public void AddHeaders_ResponseHeaderToRequestHeaders_Success() + { + const string Name = "WWW-Authenticate"; + const string Value = "Basic realm=\"Access to the staging site\", charset=\"UTF-8\""; + + var request = new HttpRequestMessage(); + Assert.True(request.Headers.TryAddWithoutValidation(Name, Value)); + + Assert.True(request.Headers.Contains(Name)); + Assert.True(request.Headers.NonValidated.Contains(Name)); + + Assert.True(request.Headers.TryGetValues(Name, out IEnumerable values)); + Assert.Equal(Value, values.Single()); + + Assert.True(request.Headers.NonValidated.TryGetValues(Name, out HeaderStringValues nvValues)); + Assert.Equal(Value, nvValues.Single()); + } + + [Fact] + public void AddHeaders_RequestHeaderToResponseHeaders_Success() + { + const string Name = "Referer"; + const string Value = "https://dot.net"; + + var response = new HttpResponseMessage(); + Assert.True(response.Headers.TryAddWithoutValidation(Name, Value)); + + Assert.True(response.Headers.Contains(Name)); + Assert.True(response.Headers.NonValidated.Contains(Name)); + + Assert.True(response.Headers.TryGetValues(Name, out IEnumerable values)); + Assert.Equal(Value, values.Single()); + + Assert.True(response.Headers.NonValidated.TryGetValues(Name, out HeaderStringValues nvValues)); + Assert.Equal(Value, nvValues.Single()); + } + [Fact] public void HeaderStringValues_Default_Empty() { diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index 9e3cc64cae132d..809b9a3ba8035a 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -104,7 +104,6 @@ public async Task ConnectWithCertificateChain() } [Fact] - [PlatformSpecific(TestPlatforms.Windows)] public async Task UntrustedClientCertificateFails() { var listenerOptions = new QuicListenerOptions(); @@ -330,7 +329,6 @@ public async Task ConnectWithCertificateForLoopbackIP_IndicatesExpectedError(str } [Theory] - [PlatformSpecific(TestPlatforms.Windows)] [InlineData(true)] // [InlineData(false)] [ActiveIssue("https://github.com/dotnet/runtime/issues/57308")] public async Task ConnectWithClientCertificate(bool sendCerttificate) diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs index 10dd32c0316519..adb6680fb999bf 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SecureChannel.cs @@ -695,11 +695,13 @@ private bool AcquireServerCredentials(ref byte[]? thumbPrint) _sslAuthenticationOptions.CertificateContext = SslStreamCertificateContext.Create(selectedCert); } + Debug.Assert(_sslAuthenticationOptions.CertificateContext != null); // // Note selectedCert is a safe ref possibly cloned from the user passed Cert object // byte[] guessedThumbPrint = selectedCert.GetCertHash(); - SafeFreeCredentials? cachedCredentialHandle = SslSessionsCache.TryCachedCredential(guessedThumbPrint, _sslAuthenticationOptions.EnabledSslProtocols, _sslAuthenticationOptions.IsServer, _sslAuthenticationOptions.EncryptionPolicy); + bool sendTrustedList = _sslAuthenticationOptions.CertificateContext!.Trust?._sendTrustInHandshake ?? false; + SafeFreeCredentials? cachedCredentialHandle = SslSessionsCache.TryCachedCredential(guessedThumbPrint, _sslAuthenticationOptions.EnabledSslProtocols, _sslAuthenticationOptions.IsServer, _sslAuthenticationOptions.EncryptionPolicy, sendTrustedList); if (cachedCredentialHandle != null) { @@ -763,6 +765,7 @@ private SecurityStatusPal GenerateToken(ReadOnlySpan inputBuffer, ref byte byte[]? result = Array.Empty(); SecurityStatusPal status = default; bool cachedCreds = false; + bool sendTrustList = false; byte[]? thumbPrint = null; // @@ -779,6 +782,11 @@ private SecurityStatusPal GenerateToken(ReadOnlySpan inputBuffer, ref byte cachedCreds = _sslAuthenticationOptions.IsServer ? AcquireServerCredentials(ref thumbPrint) : AcquireClientCredentials(ref thumbPrint); + + if (cachedCreds && _sslAuthenticationOptions.IsServer) + { + sendTrustList = _sslAuthenticationOptions.CertificateContext?.Trust?._sendTrustInHandshake ?? false; + } } if (_sslAuthenticationOptions.IsServer) @@ -820,7 +828,7 @@ private SecurityStatusPal GenerateToken(ReadOnlySpan inputBuffer, ref byte // if (!cachedCreds && _securityContext != null && !_securityContext.IsInvalid && _credentialsHandle != null && !_credentialsHandle.IsInvalid) { - SslSessionsCache.CacheCredential(_credentialsHandle, thumbPrint, _sslAuthenticationOptions.EnabledSslProtocols, _sslAuthenticationOptions.IsServer, _sslAuthenticationOptions.EncryptionPolicy); + SslSessionsCache.CacheCredential(_credentialsHandle, thumbPrint, _sslAuthenticationOptions.EnabledSslProtocols, _sslAuthenticationOptions.IsServer, _sslAuthenticationOptions.EncryptionPolicy, sendTrustList); } } } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslSessionsCache.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslSessionsCache.cs index 13e4f772f6b3b9..35eb4ec534b83d 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslSessionsCache.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslSessionsCache.cs @@ -25,18 +25,20 @@ internal static class SslSessionsCache private readonly int _allowedProtocols; private readonly EncryptionPolicy _encryptionPolicy; private readonly bool _isServerMode; + private readonly bool _sendTrustList; // // SECURITY: X509Certificate.GetCertHash() is virtual hence before going here, // the caller of this ctor has to ensure that a user cert object was inspected and // optionally cloned. // - internal SslCredKey(byte[]? thumbPrint, int allowedProtocols, bool isServerMode, EncryptionPolicy encryptionPolicy) + internal SslCredKey(byte[]? thumbPrint, int allowedProtocols, bool isServerMode, EncryptionPolicy encryptionPolicy, bool sendTrustList) { _thumbPrint = thumbPrint ?? Array.Empty(); _allowedProtocols = allowedProtocols; _encryptionPolicy = encryptionPolicy; _isServerMode = isServerMode; + _sendTrustList = sendTrustList; } public override int GetHashCode() @@ -65,6 +67,7 @@ public override int GetHashCode() hashCode ^= _allowedProtocols; hashCode ^= (int)_encryptionPolicy; hashCode ^= _isServerMode ? 0x10000 : 0x20000; + hashCode ^= _sendTrustList ? 0x40000 : 0x80000; return hashCode; } @@ -96,6 +99,11 @@ public bool Equals(SslCredKey other) return false; } + if (_sendTrustList != other._sendTrustList) + { + return false; + } + for (int i = 0; i < thumbPrint.Length; ++i) { if (thumbPrint[i] != otherThumbPrint[i]) @@ -114,7 +122,7 @@ public bool Equals(SslCredKey other) // ATTN: The returned handle can be invalid, the callers of InitializeSecurityContext and AcceptSecurityContext // must be prepared to execute a back-out code if the call fails. // - internal static SafeFreeCredentials? TryCachedCredential(byte[]? thumbPrint, SslProtocols sslProtocols, bool isServer, EncryptionPolicy encryptionPolicy) + internal static SafeFreeCredentials? TryCachedCredential(byte[]? thumbPrint, SslProtocols sslProtocols, bool isServer, EncryptionPolicy encryptionPolicy, bool sendTrustList = false) { if (s_cachedCreds.IsEmpty) { @@ -122,7 +130,7 @@ public bool Equals(SslCredKey other) return null; } - var key = new SslCredKey(thumbPrint, (int)sslProtocols, isServer, encryptionPolicy); + var key = new SslCredKey(thumbPrint, (int)sslProtocols, isServer, encryptionPolicy, sendTrustList); //SafeCredentialReference? cached; SafeFreeCredentials? credentials = GetCachedCredential(key); @@ -147,7 +155,7 @@ public bool Equals(SslCredKey other) // // ATTN: The thumbPrint must be from inspected and possibly cloned user Cert object or we get a security hole in SslCredKey ctor. // - internal static void CacheCredential(SafeFreeCredentials creds, byte[]? thumbPrint, SslProtocols sslProtocols, bool isServer, EncryptionPolicy encryptionPolicy) + internal static void CacheCredential(SafeFreeCredentials creds, byte[]? thumbPrint, SslProtocols sslProtocols, bool isServer, EncryptionPolicy encryptionPolicy, bool sendTrustList = false) { Debug.Assert(creds != null, "creds == null"); @@ -157,7 +165,7 @@ internal static void CacheCredential(SafeFreeCredentials creds, byte[]? thumbPri return; } - SslCredKey key = new SslCredKey(thumbPrint, (int)sslProtocols, isServer, encryptionPolicy); + SslCredKey key = new SslCredKey(thumbPrint, (int)sslProtocols, isServer, encryptionPolicy, sendTrustList); SafeFreeCredentials? credentials = GetCachedCredential(key); diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs index 29ab3bed0ee8c6..1824e9b0233123 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs @@ -124,8 +124,8 @@ public static SafeFreeCredentials AcquireCredentialsHandle(SslStreamCertificateC { // New crypto API supports TLS1.3 but it does not allow to force NULL encryption. SafeFreeCredentials cred = !UseNewCryptoApi || policy == EncryptionPolicy.NoEncryption ? - AcquireCredentialsHandleSchannelCred(certificateContext?.Certificate, protocols, policy, isServer) : - AcquireCredentialsHandleSchCredentials(certificateContext?.Certificate, protocols, policy, isServer); + AcquireCredentialsHandleSchannelCred(certificateContext, protocols, policy, isServer) : + AcquireCredentialsHandleSchCredentials(certificateContext, protocols, policy, isServer); if (certificateContext != null && certificateContext.Trust != null && certificateContext.Trust._sendTrustInHandshake) { AttachCertificateStore(cred, certificateContext.Trust._store!); @@ -157,8 +157,9 @@ private static unsafe void AttachCertificateStore(SafeFreeCredentials cred, X509 // This is legacy crypto API used on .NET Framework and older Windows versions. // It only supports TLS up to 1.2 - public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchannelCred(X509Certificate2? certificate, SslProtocols protocols, EncryptionPolicy policy, bool isServer) + public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchannelCred(SslStreamCertificateContext? certificateContext, SslProtocols protocols, EncryptionPolicy policy, bool isServer) { + X509Certificate2? certificate = certificateContext?.Certificate; int protocolFlags = GetProtocolFlagsFromSslProtocols(protocols, isServer); Interop.SspiCli.SCHANNEL_CRED.Flags flags; Interop.SspiCli.CredentialUse direction; @@ -183,6 +184,10 @@ public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchannelCred(X5 { direction = Interop.SspiCli.CredentialUse.SECPKG_CRED_INBOUND; flags = Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_SEND_AUX_RECORD; + if (certificateContext?.Trust?._sendTrustInHandshake == true) + { + flags |= Interop.SspiCli.SCHANNEL_CRED.Flags.SCH_CRED_NO_SYSTEM_MAPPER; + } } if (NetEventSource.Log.IsEnabled()) NetEventSource.Info($"flags=({flags}), ProtocolFlags=({protocolFlags}), EncryptionPolicy={policy}"); @@ -203,8 +208,9 @@ public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchannelCred(X5 } // This function uses new crypto API to support TLS 1.3 and beyond. - public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchCredentials(X509Certificate2? certificate, SslProtocols protocols, EncryptionPolicy policy, bool isServer) + public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchCredentials(SslStreamCertificateContext? certificateContext, SslProtocols protocols, EncryptionPolicy policy, bool isServer) { + X509Certificate2? certificate = certificateContext?.Certificate; int protocolFlags = GetProtocolFlagsFromSslProtocols(protocols, isServer); Interop.SspiCli.SCH_CREDENTIALS.Flags flags; Interop.SspiCli.CredentialUse direction; @@ -212,6 +218,10 @@ public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchCredentials( { direction = Interop.SspiCli.CredentialUse.SECPKG_CRED_INBOUND; flags = Interop.SspiCli.SCH_CREDENTIALS.Flags.SCH_SEND_AUX_RECORD; + if (certificateContext?.Trust?._sendTrustInHandshake == true) + { + flags |= Interop.SspiCli.SCH_CREDENTIALS.Flags.SCH_CRED_NO_SYSTEM_MAPPER; + } } else { diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs index be1b108e4e05c3..12f289c3beaef9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs @@ -47,8 +47,8 @@ internal static unsafe int GetLocaleInfoEx(string lpLocaleName, uint lcType, cha private string NlsGetLocaleInfo(LocaleStringData type) { Debug.Assert(ShouldUseUserOverrideNlsData); - Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfo] Expected _sWindowsName to be populated by already"); - return NlsGetLocaleInfo(_sWindowsName, type); + Debug.Assert(_sRealName != null, "[CultureData.DoGetLocaleInfo] Expected _sRealName to be populated by already"); + return NlsGetLocaleInfo(_sRealName, type); } // For LOCALE_SPARENT we need the option of using the "real" name (forcing neutral names) instead of the @@ -74,15 +74,15 @@ private int NlsGetLocaleInfo(LocaleNumberData type) // Ask OS for data, note that we presume it returns success, so we have to know that // sWindowsName is valid before calling. - Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already"); - return GetLocaleInfoExInt(_sWindowsName, lctype); + Debug.Assert(_sRealName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sRealName to be populated already"); + return GetLocaleInfoExInt(_sRealName, lctype); } private int[] NlsGetLocaleInfo(LocaleGroupingData type) { Debug.Assert(ShouldUseUserOverrideNlsData); - Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already"); - return ConvertWin32GroupString(GetLocaleInfoFromLCType(_sWindowsName, (uint)type, _bUseOverrides)); + Debug.Assert(_sRealName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sRealName to be populated by already"); + return ConvertWin32GroupString(GetLocaleInfoFromLCType(_sRealName, (uint)type, _bUseOverrides)); } internal static bool NlsIsEnsurePredefinedLocaleName(string name) @@ -94,16 +94,16 @@ internal static bool NlsIsEnsurePredefinedLocaleName(string name) private string? NlsGetTimeFormatString() { Debug.Assert(ShouldUseUserOverrideNlsData); - Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already"); - return ReescapeWin32String(GetLocaleInfoFromLCType(_sWindowsName, Interop.Kernel32.LOCALE_STIMEFORMAT, _bUseOverrides)); + Debug.Assert(_sRealName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sRealName to be populated by already"); + return ReescapeWin32String(GetLocaleInfoFromLCType(_sRealName, Interop.Kernel32.LOCALE_STIMEFORMAT, _bUseOverrides)); } private int NlsGetFirstDayOfWeek() { Debug.Assert(ShouldUseUserOverrideNlsData); - Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already"); + Debug.Assert(_sRealName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sRealName to be populated by already"); - int result = GetLocaleInfoExInt(_sWindowsName, Interop.Kernel32.LOCALE_IFIRSTDAYOFWEEK | (!_bUseOverrides ? Interop.Kernel32.LOCALE_NOUSEROVERRIDE : 0)); + int result = GetLocaleInfoExInt(_sRealName, Interop.Kernel32.LOCALE_IFIRSTDAYOFWEEK | (!_bUseOverrides ? Interop.Kernel32.LOCALE_NOUSEROVERRIDE : 0)); // Win32 and .NET disagree on the numbering for days of the week, so we have to convert. return ConvertFirstDayOfWeekMonToSun(result); @@ -529,7 +529,7 @@ internal bool NlsIsReplacementCulture for (int i = 0; i < context.strings.Count; i++) { - if (string.Equals(context.strings[i], _sWindowsName, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(context.strings[i], _sRealName, StringComparison.OrdinalIgnoreCase)) return true; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs index 9b4fc5df0395ad..549147bacd9f3a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs @@ -389,6 +389,7 @@ public int Count } internal bool loggingEnabled; + private bool _dispatchTimeSensitiveWorkFirst; internal readonly ConcurrentQueue workItems = new ConcurrentQueue(); // SOS's ThreadPool command depends on this name internal readonly ConcurrentQueue? timeSensitiveWorkQueue = ThreadPool.SupportsTimeSensitiveWorkItems ? new ConcurrentQueue() : null; @@ -650,6 +651,21 @@ internal static bool Dispatch() int startTickCount = Environment.TickCount; object? workItem = null; +#pragma warning disable CS0162 // Unreachable code detected. SupportsTimeSensitiveWorkItems may be a constant in some runtimes. + if (ThreadPool.SupportsTimeSensitiveWorkItems) + { + // Alternate between checking for time-sensitive work or other work first, that way both sets of work items + // get a chance to run in situations where worker threads are starved and work items that run also take over + // the thread, sustaining starvation. For example, if time-sensitive work is always checked last here, timer + // callbacks may not run when worker threads are continually starved. + bool dispatchTimeSensitiveWorkFirst = workQueue._dispatchTimeSensitiveWorkFirst; + workQueue._dispatchTimeSensitiveWorkFirst = !dispatchTimeSensitiveWorkFirst; + if (dispatchTimeSensitiveWorkFirst) + { + workItem = workQueue.TryDequeueTimeSensitiveWorkItem(); + } + } +#pragma warning restore CS0162 // // Loop until our quantum expires or there is no work. diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/StructureToPtrTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/StructureToPtrTests.cs index f174ab1cb03f62..ea55d5c177c54e 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/StructureToPtrTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/Marshal/StructureToPtrTests.cs @@ -256,6 +256,30 @@ public unsafe void StructureToPtr_OpaqueStruct_In_NonBlittableStructure_Success( Assert.Equal(*opaqueData, *marshaledOpaqueData); } + [Fact] + public void StructureToPtr_Flat_And_Nested_NonBlittableStructure_Success() + { + MarshalAndDestroy(new NonBlittableStruct_Flat + { + del = null, + b = 0x55, + }); + + MarshalAndDestroy(new NonBlittableStruct_Nested + { + s = { del = null }, + b = 0x55, + }); + + static unsafe void MarshalAndDestroy(T value) where T : struct + { + int sizeof_T = Marshal.SizeOf(); + void* ptr = stackalloc byte[sizeof_T]; + Marshal.StructureToPtr(value, (IntPtr)ptr, false); + Marshal.DestroyStructure((IntPtr)ptr); + } + } + public struct StructWithIntField { public int value; @@ -318,5 +342,22 @@ public struct NonBlittableWithOpaque public OpaqueStruct opaque; public string str; } + + public struct NonBlittableStruct_Flat + { + public Delegate del; + public byte b; + } + + public struct NonBlittableStruct_Nested + { + public struct InnerStruct + { + public Delegate del; + } + + public InnerStruct s; + public byte b; + } } } diff --git a/src/libraries/System.Security.Cryptography.Algorithms/tests/HashAlgorithmTest.cs b/src/libraries/System.Security.Cryptography.Algorithms/tests/HashAlgorithmTest.cs index dc5738441db564..38f57040589962 100644 --- a/src/libraries/System.Security.Cryptography.Algorithms/tests/HashAlgorithmTest.cs +++ b/src/libraries/System.Security.Cryptography.Algorithms/tests/HashAlgorithmTest.cs @@ -488,6 +488,30 @@ public void Initialize_TransformBlock_Unused() } } + [Fact] + public void Initialize_DoubleInitialize_Works() + { + byte[] hashInput = new byte[] { 1, 2, 3, 4, 5 }; + byte[] expectedDigest; + + using (HashAlgorithm hash = Create()) + { + expectedDigest = hash.ComputeHash(hashInput); + } + + using (HashAlgorithm hash = Create()) + { + byte[] buffer = new byte[1024]; + hash.TransformBlock(buffer, 0, buffer.Length, buffer, 0); + hash.Initialize(); + hash.TransformFinalBlock(Array.Empty(), 0, 0); + hash.Initialize(); + hash.TransformFinalBlock(hashInput, 0, hashInput.Length); + + Assert.Equal(expectedDigest, hash.Hash); + } + } + protected class DataRepeatingStream : Stream { private int _remaining; diff --git a/src/mono/mono/component/mini-wasm-debugger.c b/src/mono/mono/component/mini-wasm-debugger.c index f70738d7cb0c15..3c385102979e66 100644 --- a/src/mono/mono/component/mini-wasm-debugger.c +++ b/src/mono/mono/component/mini-wasm-debugger.c @@ -370,6 +370,12 @@ mono_wasm_set_is_debugger_attached (gboolean is_attached) EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_send_dbg_command_with_parms (int id, MdbgProtCommandSet command_set, int command, guint8* data, unsigned int size, int valtype, char* newvalue) { + if (!debugger_enabled) { + EM_ASM ({ + MONO.mono_wasm_add_dbg_command_received ($0, $1, $2, $3); + }, 0, id, 0, 0); + return TRUE; + } MdbgProtBuffer bufWithParms; buffer_init (&bufWithParms, 128); m_dbgprot_buffer_add_data (&bufWithParms, data, size); @@ -387,6 +393,12 @@ mono_wasm_send_dbg_command_with_parms (int id, MdbgProtCommandSet command_set, i EMSCRIPTEN_KEEPALIVE gboolean mono_wasm_send_dbg_command (int id, MdbgProtCommandSet command_set, int command, guint8* data, unsigned int size) { + if (!debugger_enabled) { + EM_ASM ({ + MONO.mono_wasm_add_dbg_command_received ($0, $1, $2, $3); + }, 0, id, 0, 0); + return TRUE; + } ss_calculate_framecount (NULL, NULL, TRUE, NULL, NULL); MdbgProtBuffer buf; buffer_init (&buf, 128); diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs index be7d729dd019e4..c2d8f544650eac 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs @@ -524,10 +524,19 @@ public unsafe AssemblyInfo(string url, byte[] assembly, byte[] pdb) asmStream = new MemoryStream(assembly); peReader = new PEReader(asmStream); asmMetadataReader = PEReaderExtensions.GetMetadataReader(peReader); + Name = asmMetadataReader.GetAssemblyDefinition().GetAssemblyName().Name + ".dll"; + AssemblyNameUnqualified = Name; if (pdb != null) { pdbStream = new MemoryStream(pdb); - pdbMetadataReader = MetadataReaderProvider.FromPortablePdbStream(pdbStream).GetMetadataReader(); + try + { + pdbMetadataReader = MetadataReaderProvider.FromPortablePdbStream(pdbStream).GetMetadataReader(); + } + catch (BadImageFormatException) + { + Console.WriteLine($"Warning: Unable to read debug information of: {Name} (use DebugType=Portable/Embedded)"); + } } else { @@ -538,8 +547,6 @@ public unsafe AssemblyInfo(string url, byte[] assembly, byte[] pdb) pdbMetadataReader = peReader.ReadEmbeddedPortablePdbDebugDirectoryData(embeddedPdbEntry).GetMetadataReader(); } } - Name = asmMetadataReader.GetAssemblyDefinition().GetAssemblyName().Name + ".dll"; - AssemblyNameUnqualified = asmMetadataReader.GetAssemblyDefinition().GetAssemblyName().Name + ".dll"; Populate(); } diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs index 013fd92970a30e..450a789ad6806d 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs @@ -553,7 +553,7 @@ private async Task CallOnFunction(MessageId id, JObject args, Cancellation args["details"] = await SdbHelper.GetPointerContent(id, int.Parse(objectId.Value), token); break; case "array": - args["details"] = await SdbHelper.GetArrayValues(id, int.Parse(objectId.Value), token); + args["details"] = await SdbHelper.GetArrayValuesProxy(id, int.Parse(objectId.Value), token); break; case "cfo_res": { diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs index dee4b5ac0f5fde..a484cc4cbeefc1 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs @@ -358,6 +358,52 @@ internal enum StepSize Line } + internal record ArrayDimensions + { + internal int Rank { get; } + internal int [] Bounds { get; } + internal int TotalLength { get; } + public ArrayDimensions(int [] rank) + { + Rank = rank.Length; + Bounds = rank; + TotalLength = 1; + for (int i = 0 ; i < Rank ; i++) + TotalLength *= Bounds[i]; + } + + public override string ToString() + { + return $"{string.Join(", ", Bounds)}"; + } + internal string GetArrayIndexString(int idx) + { + if (idx < 0 || idx >= TotalLength) + return "Invalid Index"; + int boundLimit = 1; + int lastBoundLimit = 1; + int[] arrayStr = new int[Rank]; + int rankStart = 0; + while (idx > 0) + { + boundLimit = 1; + for (int i = Rank - 1; i >= rankStart; i--) + { + lastBoundLimit = boundLimit; + boundLimit *= Bounds[i]; + if (idx < boundLimit) + { + arrayStr[i] = (int)(idx / lastBoundLimit); + idx -= arrayStr[i] * lastBoundLimit; + rankStart = i; + break; + } + } + } + return $"{string.Join(", ", arrayStr)}"; + } + } + internal record MethodInfoWithDebugInformation(MethodInfo Info, int DebugId, string Name); internal class TypeInfoWithDebugInformation @@ -1400,7 +1446,8 @@ public async Task GetTypeName(SessionId sessionId, int typeId, Cancellat string className = await GetTypeNameOriginal(sessionId, typeId, token); className = className.Replace("+", "."); className = Regex.Replace(className, @"`\d+", ""); - className = className.Replace("[]", "__SQUARED_BRACKETS__"); + className = Regex.Replace(className, @"[[, ]+]", "__SQUARED_BRACKETS__"); + //className = className.Replace("[]", "__SQUARED_BRACKETS__"); className = className.Replace("[", "<"); className = className.Replace("]", ">"); className = className.Replace("__SQUARED_BRACKETS__", "[]"); @@ -1451,15 +1498,20 @@ public async Task GetStringValue(SessionId sessionId, int string_id, Can } return null; } - public async Task GetArrayLength(SessionId sessionId, int object_id, CancellationToken token) + public async Task GetArrayDimensions(SessionId sessionId, int object_id, CancellationToken token) { var commandParams = new MemoryStream(); var commandParamsWriter = new MonoBinaryWriter(commandParams); commandParamsWriter.Write(object_id); var retDebuggerCmdReader = await SendDebuggerAgentCommand(sessionId, CmdArray.GetLength, commandParams, token); var length = retDebuggerCmdReader.ReadInt32(); - length = retDebuggerCmdReader.ReadInt32(); - return length; + var rank = new int[length]; + for (int i = 0 ; i < length; i++) + { + rank[i] = retDebuggerCmdReader.ReadInt32(); + retDebuggerCmdReader.ReadInt32(); //lower_bound + } + return new ArrayDimensions(rank); } public async Task> GetTypeIdFromObject(SessionId sessionId, int object_id, bool withParents, CancellationToken token) { @@ -1778,9 +1830,14 @@ public async Task CreateJObjectForString(SessionId sessionId, MonoBinar public async Task CreateJObjectForArray(SessionId sessionId, MonoBinaryReader retDebuggerCmdReader, CancellationToken token) { var objectId = retDebuggerCmdReader.ReadInt32(); - var value = await GetClassNameFromObject(sessionId, objectId, token); - var length = await GetArrayLength(sessionId, objectId, token); - return CreateJObject(null, "object", $"{value.ToString()}({length})", false, value.ToString(), "dotnet:array:" + objectId, null, "array"); + var className = await GetClassNameFromObject(sessionId, objectId, token); + var arrayType = className.ToString(); + var length = await GetArrayDimensions(sessionId, objectId, token); + if (arrayType.LastIndexOf('[') > 0) + arrayType = arrayType.Insert(arrayType.LastIndexOf('[')+1, length.ToString()); + if (className.LastIndexOf('[') > 0) + className = className.Insert(arrayType.LastIndexOf('[')+1, new string(',', length.Rank-1)); + return CreateJObject(null, "object", description : arrayType, writable : false, className.ToString(), "dotnet:array:" + objectId, null, subtype : length.Rank == 1 ? "array" : null); } public async Task CreateJObjectForObject(SessionId sessionId, MonoBinaryReader retDebuggerCmdReader, int typeIdFromAttribute, bool forDebuggerDisplayAttribute, CancellationToken token) @@ -2206,21 +2263,33 @@ public async Task GetValueTypeProxy(SessionId sessionId, int valueTypeId public async Task GetArrayValues(SessionId sessionId, int arrayId, CancellationToken token) { - var length = await GetArrayLength(sessionId, arrayId, token); + var dimensions = await GetArrayDimensions(sessionId, arrayId, token); var commandParams = new MemoryStream(); var commandParamsWriter = new MonoBinaryWriter(commandParams); commandParamsWriter.Write(arrayId); commandParamsWriter.Write(0); - commandParamsWriter.Write(length); + commandParamsWriter.Write(dimensions.TotalLength); var retDebuggerCmdReader = await SendDebuggerAgentCommand(sessionId, CmdArray.GetValues, commandParams, token); JArray array = new JArray(); - for (int i = 0 ; i < length ; i++) + for (int i = 0 ; i < dimensions.TotalLength; i++) { - var var_json = await CreateJObjectForVariableValue(sessionId, retDebuggerCmdReader, i.ToString(), false, -1, false, token); + var var_json = await CreateJObjectForVariableValue(sessionId, retDebuggerCmdReader, dimensions.GetArrayIndexString(i), isOwn : false, -1, forDebuggerDisplayAttribute : false, token); array.Add(var_json); } return array; } + + public async Task GetArrayValuesProxy(SessionId sessionId, int arrayId, CancellationToken token) + { + var length = await GetArrayDimensions(sessionId, arrayId, token); + var arrayProxy = JObject.FromObject(new + { + items = await GetArrayValues(sessionId, arrayId, token), + dimensionsDetails = length.Bounds + }); + return arrayProxy; + } + public async Task EnableExceptions(SessionId sessionId, PauseOnExceptionsKind state, CancellationToken token) { if (state == PauseOnExceptionsKind.Unset) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs index dfe99aed5a7694..22447a87c88806 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs @@ -198,6 +198,24 @@ public async Task InspectGenericValueTypeArrayLocals2(int line, int col, string frame_idx: frame_idx, use_cfo: use_cfo); + async Task GetObjectWithCFO(string objectId, JObject fn_args = null) + { + var fn_decl = "function () { return this; }"; + var cfo_args = JObject.FromObject(new + { + functionDeclaration = fn_decl, + objectId = objectId + }); + + if (fn_args != null) + cfo_args["arguments"] = fn_args; + + // callFunctionOn + var result = await cli.SendCommand("Runtime.callFunctionOn", cfo_args, token); + + return await GetProperties(result.Value["result"]["objectId"]?.Value(), fn_args); + } + async Task TestSimpleArrayLocals(int line, int col, string entry_method_name, string method_name, string etype_name, string local_var_name_prefix, object[] array, object[] array_elem_props, bool test_prev_frame = false, int frame_idx = 0, bool use_cfo = false) @@ -215,8 +233,8 @@ async Task TestSimpleArrayLocals(int line, int col, string entry_method_name, st var locals = await GetProperties(pause_location["callFrames"][frame_idx]["callFrameId"].Value()); Assert.Equal(4, locals.Count()); - CheckArray(locals, $"{local_var_name_prefix}_arr", $"{etype_name}[]", array?.Length ?? 0); - CheckArray(locals, $"{local_var_name_prefix}_arr_empty", $"{etype_name}[]", 0); + CheckArray(locals, $"{local_var_name_prefix}_arr", $"{etype_name}[]", $"{etype_name}[{array?.Length ?? 0}]"); + CheckArray(locals, $"{local_var_name_prefix}_arr_empty", $"{etype_name}[]", $"{etype_name}[0]"); CheckObject(locals, $"{local_var_name_prefix}_arr_null", $"{etype_name}[]", is_null: true); CheckBool(locals, "call_other", test_prev_frame); @@ -264,24 +282,6 @@ async Task TestSimpleArrayLocals(int line, int col, string entry_method_name, st var props = await GetObjectOnFrame(pause_location["callFrames"][frame_idx], $"{local_var_name_prefix}_arr_empty"); await CheckProps(props, new object[0], "${local_var_name_prefix}_arr_empty"); - - async Task GetObjectWithCFO(string objectId, JObject fn_args = null) - { - var fn_decl = "function () { return this; }"; - var cfo_args = JObject.FromObject(new - { - functionDeclaration = fn_decl, - objectId = objectId - }); - - if (fn_args != null) - cfo_args["arguments"] = fn_args; - - // callFunctionOn - var result = await cli.SendCommand("Runtime.callFunctionOn", cfo_args, token); - - return await GetProperties(result.Value["result"]["objectId"]?.Value(), fn_args); - } } [Theory] @@ -313,10 +313,10 @@ public async Task InspectObjectArrayMembers(bool use_cfo) await CheckProps(c_props, new { id = TString("c#id"), - ClassArrayProperty = TArray("DebuggerTests.SimpleClass[]", 3), - ClassArrayField = TArray("DebuggerTests.SimpleClass[]", 3), - PointsProperty = TArray("DebuggerTests.Point[]", 2), - PointsField = TArray("DebuggerTests.Point[]", 2) + ClassArrayProperty = TArray("DebuggerTests.SimpleClass[]", "DebuggerTests.SimpleClass[3]"), + ClassArrayField = TArray("DebuggerTests.SimpleClass[]", "DebuggerTests.SimpleClass[3]"), + PointsProperty = TArray("DebuggerTests.Point[]", "DebuggerTests.Point[2]"), + PointsField = TArray("DebuggerTests.Point[]", "DebuggerTests.Point[2]") }, "c" ); @@ -382,8 +382,8 @@ public async Task InspectValueTypeArrayLocalsStaticAsync(bool use_cfo) await CheckProps(frame_locals, new { call_other = TBool(false), - gvclass_arr = TArray("DebuggerTests.SimpleGenericStruct[]", 2), - gvclass_arr_empty = TArray("DebuggerTests.SimpleGenericStruct[]"), + gvclass_arr = TArray("DebuggerTests.SimpleGenericStruct[]", "DebuggerTests.SimpleGenericStruct[2]"), + gvclass_arr_empty = TArray("DebuggerTests.SimpleGenericStruct[]", "DebuggerTests.SimpleGenericStruct[0]"), gvclass_arr_null = TObject("DebuggerTests.SimpleGenericStruct[]", is_null: true), gvclass = TValueType("DebuggerTests.SimpleGenericStruct"), // BUG: this shouldn't be null! @@ -448,7 +448,7 @@ public async Task InspectValueTypeArrayLocalsInstanceAsync(bool use_cfo) { t1 = TObject("DebuggerTests.SimpleGenericStruct"), @this = TObject("DebuggerTests.ArrayTestsClass"), - point_arr = TArray("DebuggerTests.Point[]", 2), + point_arr = TArray("DebuggerTests.Point[]", "DebuggerTests.Point[2]"), point = TValueType("DebuggerTests.Point") }, "InspectValueTypeArrayLocalsInstanceAsync#locals"); @@ -642,6 +642,59 @@ public async Task InvalidAccessors() => await CheckInspectLocalsAtBreakpointSite AssertEqual("undefined", res.Value["result"]?["type"]?.ToString(), "Expected to get undefined result for non-existant accessor"); } }); + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task InspectPrimitiveTypeMultiArrayLocals(bool use_cfo) + { + var debugger_test_loc = "dotnet://debugger-test.dll/debugger-array-test.cs"; + + var eval_expr = "window.setTimeout(function() { invoke_static_method (" + + $"'[debugger-test] DebuggerTests.MultiDimensionalArray:run'" + + "); }, 1);"; + var pause_location = await EvaluateAndCheck(eval_expr, debugger_test_loc, 343, 12, "run"); + + var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); + Assert.Equal(3, locals.Count()); + var int_arr_1 = !use_cfo ? + await GetProperties(locals[0]["value"]["objectId"].Value()) : + await GetObjectWithCFO((locals[0]["value"]["objectId"].Value())); + + CheckNumber(int_arr_1, "0", 0); + CheckNumber(int_arr_1, "1", 1); + var int_arr_2 = !use_cfo ? + await GetProperties(locals[1]["value"]["objectId"].Value()) : + await GetObjectWithCFO((locals[1]["value"]["objectId"].Value())); + CheckNumber(int_arr_2, "0, 0", 0); + CheckNumber(int_arr_2, "0, 1", 1); + CheckNumber(int_arr_2, "0, 2", 2); + CheckNumber(int_arr_2, "1, 0", 10); + CheckNumber(int_arr_2, "1, 1", 11); + CheckNumber(int_arr_2, "1, 2", 12); + + var int_arr_3 = !use_cfo ? + await GetProperties(locals[2]["value"]["objectId"].Value()) : + await GetObjectWithCFO((locals[2]["value"]["objectId"].Value())); + CheckNumber(int_arr_3, "0, 0, 0", 0); + CheckNumber(int_arr_3, "0, 0, 1", 1); + CheckNumber(int_arr_3, "0, 0, 2", 2); + CheckNumber(int_arr_3, "0, 1, 0", 10); + CheckNumber(int_arr_3, "0, 1, 1", 11); + CheckNumber(int_arr_3, "0, 1, 2", 12); + CheckNumber(int_arr_3, "0, 2, 0", 20); + CheckNumber(int_arr_3, "0, 2, 1", 21); + CheckNumber(int_arr_3, "0, 2, 2", 22); + CheckNumber(int_arr_3, "1, 0, 0", 100); + CheckNumber(int_arr_3, "1, 0, 1", 101); + CheckNumber(int_arr_3, "1, 0, 2", 102); + CheckNumber(int_arr_3, "1, 1, 0", 110); + CheckNumber(int_arr_3, "1, 1, 1", 111); + CheckNumber(int_arr_3, "1, 1, 2", 112); + CheckNumber(int_arr_3, "1, 2, 0", 120); + CheckNumber(int_arr_3, "1, 2, 1", 121); + CheckNumber(int_arr_3, "1, 2, 2", 122); + } } } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs index 1afa97939d5ef1..0601552db6b606 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/AssignmentTests.cs @@ -19,7 +19,7 @@ public class AssignmentTests : DebuggerTestBase { "MONO_TYPE_CHAR", TSymbol("0 '\u0000'"), TSymbol("97 'a'") }, { "MONO_TYPE_STRING", TString(default), TString("hello") }, { "MONO_TYPE_ENUM", TEnum("DebuggerTests.RGB", "Red"), TEnum("DebuggerTests.RGB", "Blue") }, - { "MONO_TYPE_ARRAY", TObject("byte[]", is_null: true), TArray("byte[]", 2) }, + { "MONO_TYPE_ARRAY", TObject("byte[]", is_null: true), TArray("byte[]", "byte[2]") }, { "MONO_TYPE_VALUETYPE", TValueType("DebuggerTests.Point"), TValueType("DebuggerTests.Point") }, { "MONO_TYPE_VALUETYPE2", TValueType("System.Decimal","0"), TValueType("System.Decimal", "1.1") }, { "MONO_TYPE_GENERICINST", TObject("System.Func", is_null: true), TDelegate("System.Func", "int Prepare ()") }, diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs index 5b101f0236d040..e80fe46224695e 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/CallFunctionOnTests.cs @@ -361,7 +361,7 @@ public async Task RunOnJSObject(bool roundtrip) => await RunCallFunctionOn( await CheckProps(obj_own_val, new { a_obj = TObject("Object"), - b_arr = TArray("Array", 2) + b_arr = TArray("Array", "Array(2)") }, "obj_own"); }); @@ -641,7 +641,7 @@ public async Task PropertyGettersTest(string eval_fn, string method_name, int li // Check arrays through getters res = await InvokeGetter(obj, get_args_fn(new[] { "IntArray" }), cfo_fn); - await CheckValue(res.Value["result"], TArray("int[]", 2), $"{local_name}.IntArray"); + await CheckValue(res.Value["result"], TArray("int[]", "int[2]"), $"{local_name}.IntArray"); { var arr_elems = await GetProperties(res.Value["result"]?["objectId"]?.Value()); var exp_elems = new[] @@ -654,7 +654,7 @@ public async Task PropertyGettersTest(string eval_fn, string method_name, int li } res = await InvokeGetter(obj, get_args_fn(new[] { "DTArray" }), cfo_fn); - await CheckValue(res.Value["result"], TArray("System.DateTime[]", 2), $"{local_name}.DTArray"); + await CheckValue(res.Value["result"], TArray("System.DateTime[]", "System.DateTime[2]"), $"{local_name}.DTArray"); { var dt0 = new DateTime(6, 7, 8, 9, 10, 11); var dt1 = new DateTime(1, 2, 3, 4, 5, 6); @@ -944,7 +944,7 @@ async Task CheckCFOResult(Result result) if (res_array_len < 0) await CheckValue(result.Value["result"], TObject("Object"), $"cfo-res"); else - await CheckValue(result.Value["result"], TArray("Array", res_array_len), $"cfo-res"); + await CheckValue(result.Value["result"], TArray("Array", $"Array({res_array_len})"), $"cfo-res"); } } } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/CustomViewTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/CustomViewTests.cs index 52087e598624fc..06516155b7d399 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/CustomViewTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/CustomViewTests.cs @@ -51,7 +51,7 @@ public async Task UsingDebuggerTypeProxy() var props = await GetObjectOnFrame(frame, "myList"); Assert.Equal(1, props.Count()); - CheckArray(props, "Items", "int[]", 4); + CheckArray(props, "Items", "int[]", "int[4]"); CheckObject(locals, "b", "DebuggerTests.WithProxy", description:"DebuggerTests.WithProxy"); props = await GetObjectOnFrame(frame, "b"); diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs index 1d30086b6b2d9c..fb4c0cf63f05e8 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DebuggerTestBase.cs @@ -352,10 +352,10 @@ internal JToken CheckEnum(JToken locals, string name, string class_name, string return l; } - internal void CheckArray(JToken locals, string name, string class_name, int length) + internal void CheckArray(JToken locals, string name, string class_name, string description) => CheckValue( GetAndAssertObjectWithName(locals, name)["value"], - TArray(class_name, length), name).Wait(); + TArray(class_name, description), name).Wait(); internal JToken GetAndAssertObjectWithName(JToken obj, string name, string label = "") { @@ -974,7 +974,7 @@ internal static JObject TObject(string className, string description = null, boo JObject.FromObject(new { type = "object", className = className, description = description ?? className, subtype = is_null ? "null" : null }) : JObject.FromObject(new { type = "object", className = className, description = description ?? className }); - internal static JObject TArray(string className, int length = 0) => JObject.FromObject(new { type = "object", className = className, description = $"{className}({length})", subtype = "array" }); + internal static JObject TArray(string className, string description) => JObject.FromObject(new { type = "object", className, description, subtype = "array" }); internal static JObject TBool(bool value) => JObject.FromObject(new { type = "boolean", value = @value, description = @value ? "true" : "false" }); diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/DelegateTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/DelegateTests.cs index 2fc0fb52ce99f9..cdbee2079e72aa 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/DelegateTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/DelegateTests.cs @@ -32,19 +32,19 @@ await CheckInspectLocalsAtBreakpointSite( { fn_func = TDelegate("System.Func", "bool |(Math)"), fn_func_null = TObject("System.Func", is_null: true), - fn_func_arr = TArray("System.Func[]", 1), + fn_func_arr = TArray("System.Func[]", "System.Func[1]"), fn_del = TDelegate("Math.IsMathNull", "bool IsMathNullDelegateTarget (Math)"), fn_del_null = TObject("Math.IsMathNull", is_null: true), - fn_del_arr = TArray("Math.IsMathNull[]", 1), + fn_del_arr = TArray("Math.IsMathNull[]", "Math.IsMathNull[1]"), // Unused locals fn_func_unused = TDelegate("System.Func", "bool |(Math)"), fn_func_null_unused = TObject("System.Func", is_null: true), - fn_func_arr_unused = TArray("System.Func[]", 1), + fn_func_arr_unused = TArray("System.Func[]", "System.Func[1]"), fn_del_unused = TDelegate("Math.IsMathNull", "bool IsMathNullDelegateTarget (Math)"), fn_del_null_unused = TObject("Math.IsMathNull", is_null: true), - fn_del_arr_unused = TArray("Math.IsMathNull[]", 1), + fn_del_arr_unused = TArray("Math.IsMathNull[]", "Math.IsMathNull[1]"), res = TBool(false), m_obj = TObject("Math") @@ -105,7 +105,7 @@ public async Task InspectDelegateSignaturesWithFunc(int frame, int line, int col fn_func_null = TObject("System.Func>, Math.GenericStruct>", is_null: true), fn_func_only_ret = TDelegate("System.Func", "bool |()"), - fn_func_arr = TArray("System.Func>, Math.GenericStruct>[]", 1), + fn_func_arr = TArray("System.Func>, Math.GenericStruct>[]", "System.Func>, Math.GenericStruct>[1]"), fn_del = TDelegate("Math.DelegateForSignatureTest", "Math.GenericStruct DelegateTargetForSignatureTest (Math,Math.GenericStruct>)"), @@ -114,16 +114,16 @@ public async Task InspectDelegateSignaturesWithFunc(int frame, int line, int col "Math.GenericStruct |(Math,Math.GenericStruct>)"), fn_del_null = TObject("Math.DelegateForSignatureTest", is_null: true), - fn_del_arr = TArray("Math.DelegateForSignatureTest[]", 2), + fn_del_arr = TArray("Math.DelegateForSignatureTest[]", "Math.DelegateForSignatureTest[2]"), m_obj = TObject("Math"), gs_gs = TValueType("Math.GenericStruct>"), fn_void_del = TDelegate("Math.DelegateWithVoidReturn", "void DelegateTargetWithVoidReturn (Math.GenericStruct)"), - fn_void_del_arr = TArray("Math.DelegateWithVoidReturn[]", 1), + fn_void_del_arr = TArray("Math.DelegateWithVoidReturn[]", "Math.DelegateWithVoidReturn[1]"), fn_void_del_null = TObject("Math.DelegateWithVoidReturn", is_null: true), gs = TValueType("Math.GenericStruct"), - rets = TArray("Math.GenericStruct[]", 6) + rets = TArray("Math.GenericStruct[]", "Math.GenericStruct[6]") }, "locals"); await CompareObjectPropertiesFor(locals, "fn_func_arr", new[] @@ -176,7 +176,7 @@ public async Task ActionTSignatureTest(int frame, int line, int col, string bp_m fn_action_null = TObject("System.Action>", is_null: true), - fn_action_arr = TArray("System.Action>[]", 3), + fn_action_arr = TArray("System.Action>[]", "System.Action>[3]"), gs = TValueType("Math.GenericStruct"), }, "locals"); @@ -212,8 +212,8 @@ public async Task NestedDelegatesTest(int frame, int line, int col, string bp_me fn_func = TDelegate("System.Func, bool>", "bool |(Func)"), fn_func_null = TObject("System.Func, bool>", is_null: true), - fn_func_arr = TArray("System.Func, bool>[]", 1), - fn_del_arr = TArray("System.Func, bool>[]", 1), + fn_func_arr = TArray("System.Func, bool>[]", "System.Func, bool>[1]"), + fn_del_arr = TArray("System.Func, bool>[]", "System.Func, bool>[1]"), m_obj = TObject("Math"), fn_del_null = TObject("System.Func, bool>", is_null: true), @@ -253,7 +253,7 @@ public async Task DelegatesAsMethodArgsTest(int frame, int line, int col, string await CheckProps(locals, new { @this = TObject("Math"), - dst_arr = TArray("Math.DelegateForSignatureTest[]", 2), + dst_arr = TArray("Math.DelegateForSignatureTest[]", "Math.DelegateForSignatureTest[2]"), fn_func = TDelegate("System.Func", "bool |(char[])"), fn_action = TDelegate("System.Action[]>", @@ -284,7 +284,7 @@ public async Task MethodWithDelegatesAsyncTest(bool use_cfo) => await CheckInspe await CheckProps(locals, new { @this = TObject("Math"), - _dst_arr = TArray("Math.DelegateForSignatureTest[]", 2), + _dst_arr = TArray("Math.DelegateForSignatureTest[]", "Math.DelegateForSignatureTest[2]"), _fn_func = TDelegate("System.Func", "bool |(char[])"), _fn_action = TDelegate("System.Action[]>", diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs index ee703b29648bb1..891eea7352c8aa 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/PointerTests.cs @@ -81,7 +81,7 @@ public async Task InspectLocalPointerArrays(string eval_fn, string type, string var dt = new DateTime(5, 6, 7, 8, 9, 10); await CheckProps(locals, new { - ipa = TArray("int*[]", 3) + ipa = TArray("int*[]", "int*[3]") }, "locals", num_fields: 26); var ipa_elems = await CompareObjectPropertiesFor(locals, "ipa", new[] @@ -112,7 +112,7 @@ public async Task InspectLocalDoublePointerToPrimitiveTypeArrays(string eval_fn, var dt = new DateTime(5, 6, 7, 8, 9, 10); await CheckProps(locals, new { - ippa = TArray("int**[]", 5) + ippa = TArray("int**[]", "int**[5]") }, "locals", num_fields: 26); var ippa_elems = await CompareObjectPropertiesFor(locals, "ippa", new[] @@ -223,7 +223,7 @@ public async Task InspectLocalPointersToValueTypeArrays(string eval_fn, string t var dt = new DateTime(5, 6, 7, 8, 9, 10); await CheckProps(locals, new { - dtpa = TArray("System.DateTime*[]", 2) + dtpa = TArray("System.DateTime*[]", "System.DateTime*[2]") }, "locals", num_fields: 26); // dtpa @@ -256,7 +256,7 @@ public async Task InspectLocalPointersToGenericValueTypeArrays(string eval_fn, s var dt = new DateTime(5, 6, 7, 8, 9, 10); await CheckProps(locals, new { - gspa = TArray("DebuggerTests.GenericStructWithUnmanagedT*[]", 3), + gspa = TArray("DebuggerTests.GenericStructWithUnmanagedT*[]", "DebuggerTests.GenericStructWithUnmanagedT*[3]"), }, "locals", num_fields: 26); // dtpa @@ -323,7 +323,7 @@ public async Task InspectLocalDoublePointersToValueTypeArrays(string eval_fn, st var dt = new DateTime(5, 6, 7, 8, 9, 10); await CheckProps(locals, new { - dtppa = TArray("System.DateTime**[]", 3), + dtppa = TArray("System.DateTime**[]", "System.DateTime**[3]"), }, "locals", num_fields: 26); // DateTime**[] dtppa = new DateTime**[] { &dtp, &dtp_null, null }; @@ -395,8 +395,8 @@ public async Task InspectPrimitiveTypePointersAsMethodArgs(string eval_fn, strin { ip = TPointer("int*"), ipp = TPointer("int**"), - ipa = TArray("int*[]", 3), - ippa = TArray("int**[]", 5) + ipa = TArray("int*[]", "int*[3]"), + ippa = TArray("int**[]", "int**[5]") }, "locals", num_fields: 8); // ip @@ -468,8 +468,8 @@ public async Task InspectValueTypePointersAsMethodArgs(string eval_fn, string ty { dtp = TPointer("System.DateTime*"), dtpp = TPointer("System.DateTime**"), - dtpa = TArray("System.DateTime*[]", 2), - dtppa = TArray("System.DateTime**[]", 3) + dtpa = TArray("System.DateTime*[]", "System.DateTime*[2]"), + dtppa = TArray("System.DateTime**[]", "System.DateTime**[3]") }, "locals", num_fields: 8); // *dtp diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs index de1bd7a829b2a4..e1a4a46fd83ea4 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/SteppingTests.cs @@ -354,7 +354,7 @@ public async Task InspectLocalsInAsyncMethods(bool use_cfo) CheckObject(locals, "this", "Math.NestedInMath"); //FIXME: check fields CheckValueType(locals, "ss", "Math.SimpleStruct"); - CheckArray(locals, "ss_arr", "Math.SimpleStruct[]", 0); + CheckArray(locals, "ss_arr", "Math.SimpleStruct[]", "Math.SimpleStruct[0]"); // TODO: struct fields } ); @@ -584,7 +584,7 @@ async Task CheckArrayElements(JToken pause_location, DateTime dt) var locals = await GetProperties(pause_location["callFrames"][0]["callFrameId"].Value()); await CheckProps(locals, new { - ssta = TArray("DebuggerTests.StructForToStringTests[]", 1) + ssta = TArray("DebuggerTests.StructForToStringTests[]", "DebuggerTests.StructForToStringTests[1]") }, "locals"); var ssta = await GetObjectOnLocals(locals, "ssta"); diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs index 9681a02882574c..9a7879190055d2 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/Tests.cs @@ -140,7 +140,7 @@ await CheckInspectLocalsAtBreakpointSite( str_spaces, str_esc, - strings = TArray("string[]", 4) + strings = TArray("string[]", "string[4]") }, "locals"); var strings_arr = await GetObjectOnLocals(locals, "strings"); @@ -204,14 +204,14 @@ await CheckInspectLocalsAtBreakpointSite( CheckObject(locals, "list", "System.Collections.Generic.Dictionary", description: "Count = 0"); CheckObject(locals, "list_null", "System.Collections.Generic.Dictionary", is_null: true); - CheckArray(locals, "list_arr", "System.Collections.Generic.Dictionary[]", 1); + CheckArray(locals, "list_arr", "System.Collections.Generic.Dictionary[]", "System.Collections.Generic.Dictionary[1]"); CheckObject(locals, "list_arr_null", "System.Collections.Generic.Dictionary[]", is_null: true); // Unused locals CheckObject(locals, "list_unused", "System.Collections.Generic.Dictionary", description: "Count = 0"); CheckObject(locals, "list_null_unused", "System.Collections.Generic.Dictionary", is_null: true); - CheckArray(locals, "list_arr_unused", "System.Collections.Generic.Dictionary[]", 1); + CheckArray(locals, "list_arr_unused", "System.Collections.Generic.Dictionary[]", "System.Collections.Generic.Dictionary[1]"); CheckObject(locals, "list_arr_null_unused", "System.Collections.Generic.Dictionary[]", is_null: true); } ); @@ -367,7 +367,7 @@ public async Task InspectBoxedLocals(string method_name, bool is_async) => await o_n_dt = TDateTime(dt), o_null = TObject("object", is_null: true), - o_ia = TArray("int[]", 2), + o_ia = TArray("int[]", "int[2]"), }, "locals"); foreach (var name in new[] { "n_gs", "o_gs", "o_n_gs" }) @@ -541,7 +541,7 @@ public async Task InspectLocalsForToStringDescriptions(int line, int col, string ts = TValueType("System.TimeSpan", ts.ToString()), dec = TValueType("System.Decimal", "123987123"), guid = TValueType("System.Guid", "3D36E07E-AC90-48C6-B7EC-A481E289D014"), - dts = TArray("System.DateTime[]", 2), + dts = TArray("System.DateTime[]", "System.DateTime[2]"), obj = TObject("DebuggerTests.ClassForToStringTests"), sst = TObject("DebuggerTests.StructForToStringTests") }, "locals#0"); @@ -712,7 +712,7 @@ public async Task PreviousFrameForAReflectedCall() => await CheckInspectLocalsAt mi = TObject("System.Reflection.RuntimeMethodInfo"), //this is what is returned when debugging desktop apps using VS dt = TDateTime(new DateTime(4210, 3, 4, 5, 6, 7)), i = TNumber(4), - strings = TArray("string[]", 1), + strings = TArray("string[]", "string[1]"), cs = TValueType("DebuggerTests.GetPropertiesTests.CloneableStruct"), num = TNumber(10), @@ -860,6 +860,34 @@ await EvaluateAndCheck( ); } + [Fact] + public async Task InspectLocalsUsingClassFromLibraryUsingDebugTypeFull() + { + byte[] bytes = File.ReadAllBytes(Path.Combine(DebuggerTestAppPath, "debugger-test-with-full-debug-type.dll")); + string asm_base64 = Convert.ToBase64String(bytes); + + string pdb_base64 = null; + bytes = File.ReadAllBytes(Path.Combine(DebuggerTestAppPath, "debugger-test-with-full-debug-type.pdb")); + pdb_base64 = Convert.ToBase64String(bytes); + + var expression = $"{{ let asm_b64 = '{asm_base64}'; let pdb_b64 = '{pdb_base64}'; invoke_static_method('[debugger-test] DebugTypeFull:CallToEvaluateLocal', asm_b64, pdb_b64); }}"; + + await EvaluateAndCheck( + "window.setTimeout(function() {" + expression + "; }, 1);", + "dotnet://debugger-test.dll/debugger-test.cs", 818, 8, + "CallToEvaluateLocal", + wait_for_event_fn: async (pause_location) => + { + var a_props = await GetObjectOnFrame(pause_location["callFrames"][0], "a"); + await CheckProps(a_props, new + { + a = TNumber(10), + b = TNumber(20), + c = TNumber(30) + }, "a"); + } + ); + } //TODO add tests covering basic stepping behavior as step in/out/over } } diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-array-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-array-test.cs index 26acccf68dc767..f1a2b41bd18a48 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-array-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-array-test.cs @@ -305,4 +305,44 @@ public static void run() new Point { X = 90, Y = -4, Id = "point#Id", Color = RGB.Green }.GenericInstanceMethod(sc); } } + public class MultiDimensionalArray + { + public static void run() + { + var int_arr_1 = new int[2]; + int_arr_1[0] = 0; + int_arr_1[1] = 1; + + var int_arr_2 = new int[2, 3]; + int_arr_2[0, 0] = 0; + int_arr_2[0, 1] = 1; + int_arr_2[0, 2] = 2; + int_arr_2[1, 0] = 10; + int_arr_2[1, 1] = 11; + int_arr_2[1, 2] = 12; + + var int_arr_3 = new int[2, 3, 3]; + int_arr_3[0, 0, 0] = 0; + int_arr_3[0, 0, 1] = 1; + int_arr_3[0, 0, 2] = 2; + int_arr_3[0, 1, 0] = 10; + int_arr_3[0, 1, 1] = 11; + int_arr_3[0, 1, 2] = 12; + int_arr_3[0, 2, 0] = 20; + int_arr_3[0, 2, 1] = 21; + int_arr_3[0, 2, 2] = 22; + int_arr_3[1, 0, 0] = 100; + int_arr_3[1, 0, 1] = 101; + int_arr_3[1, 0, 2] = 102; + int_arr_3[1, 1, 0] = 110; + int_arr_3[1, 1, 1] = 111; + int_arr_3[1, 1, 2] = 112; + int_arr_3[1, 2, 0] = 120; + int_arr_3[1, 2, 1] = 121; + int_arr_3[1, 2, 2] = 122; + + System.Diagnostics.Debugger.Break(); + Console.WriteLine($"int_arr: {int_arr_3.Length}"); + } + } } diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-test.cs index 2338c9e65d624a..df623485bf1576 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-test.cs @@ -807,3 +807,15 @@ public int Increment(int count) return count + 1; } } + +public class DebugTypeFull +{ + public static void CallToEvaluateLocal(string asm_base64, string pdb_base64) + { + var asm = System.Reflection.Assembly.LoadFrom("debugger-test-with-full-debug-type.dll"); + var myType = asm.GetType("DebuggerTests.ClassToInspectWithDebugTypeFull"); + var myMethod = myType.GetConstructor(new Type[] { }); + var a = myMethod.Invoke(new object[]{}); + System.Diagnostics.Debugger.Break(); + } +} \ No newline at end of file diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj b/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj index 145c80e8c20fc6..7e8478cfc07b25 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-test.csproj @@ -22,10 +22,12 @@ + + false $(AppDir) $(MonoProjectRoot)wasm\runtime-test.js @@ -37,6 +39,7 @@ + diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index d40e893135c1e5..8f319841d024ea 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -699,8 +699,11 @@ var MonoSupportLib = { _create_proxy_from_object_id: function (objectId, details) { if (objectId.startsWith ('dotnet:array:')) { - let ret = details.map (p => p.value); - return ret; + if (details.dimensionsDetails == undefined || details.dimensionsDetails.length == 1) + { + const ret = details.items.map (p => p.value); + return ret; + } } let proxy = {}; diff --git a/src/native/corehost/hostpolicy/hostpolicy_context.cpp b/src/native/corehost/hostpolicy/hostpolicy_context.cpp index e213e78e05b426..e4165f01259a70 100644 --- a/src/native/corehost/hostpolicy/hostpolicy_context.cpp +++ b/src/native/corehost/hostpolicy/hostpolicy_context.cpp @@ -287,11 +287,16 @@ int hostpolicy_context_t::initialize(hostpolicy_init_t &hostpolicy_init, const a pal::string_t startup_hooks; if (pal::getenv(_X("DOTNET_STARTUP_HOOKS"), &startup_hooks)) { - if (!coreclr_properties.add(common_property::StartUpHooks, startup_hooks.c_str())) + const pal::char_t *config_startup_hooks; + if (coreclr_properties.try_get(common_property::StartUpHooks, &config_startup_hooks)) { - log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::StartUpHooks)); - return StatusCode::LibHostDuplicateProperty; + // env startup hooks shoold have precedence over config startup hooks + // therefore append config_startup_hooks AFTER startup_hooks + startup_hooks.push_back(PATH_SEPARATOR); + startup_hooks.append(config_startup_hooks); } + + coreclr_properties.add(common_property::StartUpHooks, startup_hooks.c_str()); } // Single-File Bundle Probe @@ -303,7 +308,7 @@ int hostpolicy_context_t::initialize(hostpolicy_init_t &hostpolicy_init, const a if (!coreclr_properties.add(common_property::BundleProbe, ptr_stream.str().c_str())) { - log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::StartUpHooks)); + log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::BundleProbe)); return StatusCode::LibHostDuplicateProperty; } } @@ -318,7 +323,7 @@ int hostpolicy_context_t::initialize(hostpolicy_init_t &hostpolicy_init, const a if (!coreclr_properties.add(common_property::PInvokeOverride, ptr_stream.str().c_str())) { - log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::StartUpHooks)); + log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::PInvokeOverride)); return StatusCode::LibHostDuplicateProperty; } } @@ -327,7 +332,7 @@ int hostpolicy_context_t::initialize(hostpolicy_init_t &hostpolicy_init, const a #if defined(HOSTPOLICY_EMBEDDED) if (!coreclr_properties.add(common_property::HostPolicyEmbedded, _X("true"))) { - log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::StartUpHooks)); + log_duplicate_property_error(coreclr_property_bag_t::common_property_to_string(common_property::HostPolicyEmbedded)); return StatusCode::LibHostDuplicateProperty; } #endif diff --git a/src/tests/JIT/Directed/debugging/poison.cs b/src/tests/JIT/Directed/debugging/poison.cs index 463894a4e6a35d..81c669a8037282 100644 --- a/src/tests/JIT/Directed/debugging/poison.cs +++ b/src/tests/JIT/Directed/debugging/poison.cs @@ -19,6 +19,24 @@ public static unsafe int Main() WithoutGCRef poisoned2; Unsafe.SkipInit(out poisoned2); result &= VerifyPoison(&poisoned2, sizeof(WithoutGCRef)); + + Massive notPoisoned; + Unsafe.SkipInit(out notPoisoned); + // too large to be poisoned, just expose it but don't check return value + VerifyPoison(¬Poisoned, sizeof(Massive)); + + WithoutGCRef poisoned4; + Unsafe.SkipInit(out poisoned4); + result &= VerifyPoison(&poisoned4, sizeof(WithoutGCRef)); + + Massive notPoisoned2; + Unsafe.SkipInit(out notPoisoned2); + // too large to be poisoned, just expose it but don't check return value + VerifyPoison(¬Poisoned2, sizeof(Massive)); + + GCRef zeroed2; + Unsafe.SkipInit(out zeroed2); + result &= VerifyZero(Unsafe.AsPointer(ref zeroed2), Unsafe.SizeOf()); return result ? 100 : 101; } @@ -53,4 +71,9 @@ private struct WithoutGCRef public int ANumber; public float AFloat; } -} + + private unsafe struct Massive + { + public fixed byte Bytes[0x10008]; + } +} \ No newline at end of file diff --git a/src/tests/baseservices/RuntimeConfiguration/TestConfig.cs b/src/tests/baseservices/RuntimeConfiguration/TestConfig.cs new file mode 100644 index 00000000000000..383a5d08f466d3 --- /dev/null +++ b/src/tests/baseservices/RuntimeConfiguration/TestConfig.cs @@ -0,0 +1,159 @@ +// 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.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Reflection; +using System.Runtime; + +using Xunit; + +class TestConfig +{ + const int Success = 100; + const int Fail = 101; + + [Fact] + [EnvVar("DOTNET_gcServer", "1")] + static int Verify_ServerGC_Env_Enable(string[] _) + { + return GCSettings.IsServerGC + ? Success + : Fail; + } + + [Fact] + [ConfigProperty("DOTNET_gcServer", "0")] + static int Verify_ServerGC_Env_Disable(string[] _) + { + return GCSettings.IsServerGC + ? Fail + : Success; + } + + [Fact] + [ConfigProperty("System.GC.Server", "true")] + static int Verify_ServerGC_Prop_Enable(string[] _) + { + return GCSettings.IsServerGC + ? Success + : Fail; + } + + [Fact] + [ConfigProperty("System.GC.Server", "false")] + static int Verify_ServerGC_Prop_Disable(string[] _) + { + return GCSettings.IsServerGC + ? Fail + : Success; + } + + [Fact] + [EnvVar("DOTNET_gcServer", "0")] + [ConfigProperty("System.GC.Server", "true")] + static int Verify_ServerGC_Env_Override_Prop(string[] _) + { + return GCSettings.IsServerGC + ? Fail + : Success; + } + + static int Main(string[] args) + { + if (args.Length == 0) + { + return RunTests(); + } + + MethodInfo infos = typeof(TestConfig).GetMethod(args[0], BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); + if (infos is null) + { + return Fail; + } + return (int)infos.Invoke(null, new object[] { args[1..] }); + } + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] + class EnvVarAttribute : Attribute + { + public EnvVarAttribute(string name, string value) { Name = name; Value = value; } + public string Name { get; init; } + public string Value { get; init; } + } + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] + class ConfigPropertyAttribute : Attribute + { + public ConfigPropertyAttribute(string name, string value) { Name = name; Value = value; } + public string Name { get; init; } + public string Value { get; init; } + } + + static int RunTests() + { + string corerunPath = GetCorerunPath(); + MethodInfo[] infos = typeof(TestConfig).GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); + foreach (var mi in infos) + { + var factMaybe = mi.GetCustomAttributes(typeof(FactAttribute)); + if (!factMaybe.Any()) + { + continue; + } + + using Process process = new(); + + StringBuilder arguments = new(); + var configProperties = mi.GetCustomAttributes(typeof(ConfigPropertyAttribute)); + + foreach (Attribute cp in configProperties) + { + ConfigPropertyAttribute configProp = (ConfigPropertyAttribute)cp; + arguments.Append($"-p {configProp.Name}={configProp.Value} "); + } + + arguments.Append($"\"{System.Reflection.Assembly.GetExecutingAssembly().Location}\" {mi.Name}"); + + process.StartInfo.FileName = corerunPath; + process.StartInfo.Arguments = arguments.ToString(); + + var envVariables = mi.GetCustomAttributes(typeof(EnvVarAttribute)); + foreach (string key in Environment.GetEnvironmentVariables().Keys) + { + process.StartInfo.EnvironmentVariables[key] = Environment.GetEnvironmentVariable(key); + } + + Console.WriteLine($"Running: {process.StartInfo.Arguments}"); + foreach (Attribute ev in envVariables) + { + EnvVarAttribute envVar = (EnvVarAttribute)ev; + process.StartInfo.EnvironmentVariables[envVar.Name] = envVar.Value; + Console.WriteLine($" set {envVar.Name}={envVar.Value}"); + } + + process.Start(); + process.WaitForExit(); + if (process.ExitCode != Success) + { + Console.WriteLine($"Failed: {mi.Name}"); + return process.ExitCode; + } + } + + return Success; + } + + static string GetCorerunPath() + { + string corerunName = "corerun"; + if (TestLibrary.Utilities.IsWindows) + { + corerunName += ".exe"; + } + return Path.Combine(Environment.GetEnvironmentVariable("CORE_ROOT"), corerunName); + } +} \ No newline at end of file diff --git a/src/tests/baseservices/RuntimeConfiguration/TestConfig.csproj b/src/tests/baseservices/RuntimeConfiguration/TestConfig.csproj new file mode 100644 index 00000000000000..efba9444477cd8 --- /dev/null +++ b/src/tests/baseservices/RuntimeConfiguration/TestConfig.csproj @@ -0,0 +1,15 @@ + + + Exe + + true + true + true + + + + + + + + \ No newline at end of file diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 29bf5fee8ffc4c..90f9fa90055d0e 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -987,6 +987,9 @@ Tests features specific to coreclr + + Tests features specific to coreclr + https://github.com/dotnet/runtime/issues/40394