mirror of https://github.com/dotnet/runtime
Merge branch 'main' into dotnet-upstream/fix-typedescription-alc-leak
This commit is contained in:
commit
edfac0ddcd
|
@ -1,7 +1,6 @@
|
|||
# Users referenced in this file will automatically be requested as reviewers for PRs that modify the given paths.
|
||||
# See https://help.github.com/articles/about-code-owners/
|
||||
|
||||
/src/libraries/Common/src/Interop/ @dotnet/platform-deps-team
|
||||
/src/libraries/Common/src/System/Net/Http/aspnetcore/ @dotnet/http
|
||||
/src/libraries/Common/tests/Tests/System/Net/aspnetcore/ @dotnet/http
|
||||
|
||||
|
|
|
@ -37,10 +37,11 @@ In addition to the rules enforced by `.editorconfig`, you SHOULD:
|
|||
- [5.1. How To: Identify Affected Libraries](#51-how-to-identify-affected-libraries)
|
||||
- [5.2. How To: Build and Test Specific Library](#52-how-to-build-and-test-specific-library)
|
||||
- [6. WebAssembly (WASM) Libraries Workflow](#6-webassembly-wasm-libraries-workflow)
|
||||
- [7. Additional Notes](#7-additional-notes)
|
||||
- [7.1. Troubleshooting](#71-troubleshooting)
|
||||
- [7.2. Windows Command Equivalents](#72-windows-command-equivalents)
|
||||
- [7.3. References](#73-references)
|
||||
- [7. Host Workflow](#7-host-workflow)
|
||||
- [8. Additional Notes](#8-additional-notes)
|
||||
- [8.1. Troubleshooting](#81-troubleshooting)
|
||||
- [8.2. Windows Command Equivalents](#82-windows-command-equivalents)
|
||||
- [8.3. References](#83-references)
|
||||
|
||||
## 1. Prerequisites
|
||||
|
||||
|
@ -54,6 +55,7 @@ Identify which components will be impacted by the changes. If in doubt, analyze
|
|||
- **Mono Runtime:** Changes in `src/mono/`
|
||||
- **Libraries:** Changes in `src/libraries/`
|
||||
- **WASM/WASI Libraries:** Changes in `src/libraries/` *and* the affected library targets WASM or WASI *and* the changes are included for the target (see below for details).
|
||||
- **Host:** Changes in `src/native/corehost/`, `src/installer/managed/`, or `src/installer/tests/`
|
||||
- If none above apply, it is most possibly an infra-only or a docs-only change. Skip build and test steps.
|
||||
|
||||
**WASM/WASI Library Change Detection**
|
||||
|
@ -76,6 +78,7 @@ Before applying any changes, ensure you have a full successful build of the need
|
|||
- **Mono Runtime:** `./build.sh mono+libs`
|
||||
- **Libraries:** `./build.sh clr+libs -rc release`
|
||||
- **WASM/WASI Libraries:** `./build.sh mono+libs -os browser`
|
||||
- **Host:** `./build.sh clr+libs+host -rc release -lc release`
|
||||
|
||||
3. Verify the build completed without error.
|
||||
- _If the baseline build failed, report the failure and don't proceed with the changes._
|
||||
|
@ -239,9 +242,24 @@ From the repository root:
|
|||
|
||||
---
|
||||
|
||||
## 7. Additional Notes
|
||||
## 7. Host Workflow
|
||||
|
||||
### 7.1. Troubleshooting
|
||||
From the repository root:
|
||||
|
||||
- Build:
|
||||
`./build.sh host -rc release -lc release`
|
||||
|
||||
- Run all tests:
|
||||
`./build.sh host.tests -rc release -lc release -test`
|
||||
|
||||
- More info can be found in the dedicated workflow docs:
|
||||
- [Building and running host tests](/docs/workflow/testing/host/testing.md)
|
||||
|
||||
---
|
||||
|
||||
## 8. Additional Notes
|
||||
|
||||
### 8.1. Troubleshooting
|
||||
|
||||
- **Shared Framework Missing**
|
||||
|
||||
|
@ -273,7 +291,7 @@ From the repository root:
|
|||
|
||||
---
|
||||
|
||||
### 7.2. Windows Command Equivalents
|
||||
### 8.2. Windows Command Equivalents
|
||||
|
||||
- Use `build.cmd` instead of `build.sh` on Windows.
|
||||
- Set PATH: `set PATH=%CD%\.dotnet;%PATH%`
|
||||
|
@ -281,7 +299,7 @@ From the repository root:
|
|||
|
||||
---
|
||||
|
||||
### 7.3. References
|
||||
### 8.3. References
|
||||
|
||||
- [`.editorconfig`](/.editorconfig)
|
||||
- [Building CoreCLR Guide](/docs/workflow/building/coreclr/README.md)
|
||||
|
@ -292,3 +310,4 @@ From the repository root:
|
|||
- [Testing Libraries](/docs/workflow/testing/libraries/testing.md)
|
||||
- [Build libraries for WebAssembly](/docs/workflow/building/libraries/webassembly-instructions.md)
|
||||
- [Testing Libraries on WebAssembly](/docs/workflow/testing/libraries/testing-wasm.md)
|
||||
- [Building and running host tests](/docs/workflow/testing/host/testing.md)
|
||||
|
|
|
@ -19,7 +19,7 @@ configuration:
|
|||
- adamsitnik
|
||||
- bartonjs
|
||||
- jeffhandley
|
||||
- terrajobst
|
||||
- JeremyKuhne
|
||||
replyTemplate: >-
|
||||
Tagging subscribers to 'binaryformatter-migration': ${mentionees}
|
||||
assignMentionees: False
|
||||
|
|
|
@ -1789,7 +1789,6 @@ configuration:
|
|||
mentionees:
|
||||
- vitek-karas
|
||||
- kotlarmilos
|
||||
- ivanpovazan
|
||||
- steveisok
|
||||
- akoeplinger
|
||||
replyTemplate: >-
|
||||
|
@ -1828,7 +1827,6 @@ configuration:
|
|||
mentionees:
|
||||
- vitek-karas
|
||||
- kotlarmilos
|
||||
- ivanpovazan
|
||||
- steveisok
|
||||
- akoeplinger
|
||||
replyTemplate: >-
|
||||
|
@ -1848,7 +1846,6 @@ configuration:
|
|||
mentionees:
|
||||
- vitek-karas
|
||||
- kotlarmilos
|
||||
- ivanpovazan
|
||||
- steveisok
|
||||
- akoeplinger
|
||||
replyTemplate: >-
|
||||
|
|
|
@ -178,7 +178,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<DotNetHostBinDir>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', '$(TargetRid).$(HostConfiguration)', 'corehost'))</DotNetHostBinDir>
|
||||
<DotNetCdacBinDir>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'mscordaccore_universal', '$(Configuration)', '$(NetCoreAppCurrent)', '$(TargetRid)', 'publish'))</DotNetCdacBinDir>
|
||||
<DotNetCdacBinDir>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'mscordaccore_universal', '$(Configuration)', '$(NetCoreAppCurrent)', '$(PortableTargetRid)', 'publish'))</DotNetCdacBinDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<!--Feature switches -->
|
||||
|
|
|
@ -17,7 +17,7 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi
|
|||
| area-Build-mono | @lewing | @akoeplinger | |
|
||||
| area-Codeflow | @dotnet/dnr-codeflow | @dotnet/dnr-codeflow | Used for automated PRs that ingest code from other repos |
|
||||
| area-Codegen-AOT-mono | @steveisok | @kotlarmilos | |
|
||||
| area-CodeGen-coreclr | @JulieLeeMSFT | @BruceForstall @dotnet/jit-contrib | |
|
||||
| area-CodeGen-coreclr | @JulieLeeMSFT | @dotnet/jit-contrib | |
|
||||
| area-Codegen-Interpreter-coreclr | @vitek-karas | @BrzVlad @janvorli | |
|
||||
| area-Codegen-Interpreter-mono | @vitek-karas | @BrzVlad @kotlarmilos | |
|
||||
| area-Codegen-Intrinsics-mono | @steveisok | | |
|
||||
|
@ -25,87 +25,87 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi
|
|||
| area-Codegen-LLVM-mono | @steveisok | | |
|
||||
| area-Codegen-meta-mono | @steveisok | | |
|
||||
| area-crossgen2-coreclr | @mangod9 | @dotnet/crossgen-contrib | |
|
||||
| area-Debugger-mono | @steveisok | @thaystg @dotnet/dotnet-diag | |
|
||||
| area-DependencyModel | @ericstj | @dotnet/area-dependencymodel | Included:<ul><li>Microsoft.Extensions.DependencyModel</li></ul> |
|
||||
| area-Diagnostics-coreclr | @steveisok | @tommcdon @dotnet/dotnet-diag | |
|
||||
| area-Diagnostics-mono | @steveisok | @tommcdon @mdh1418 @thaystg | |
|
||||
| area-EnC-mono | @steveisok | @dotnet/dotnet-diag @thaystg | Hot Reload on WebAssembly, Android, iOS, etc . @lambdageek to consult |
|
||||
| area-Debugger-mono | @steveisok | @thaystg @dotnet/dotnet-diag | |
|
||||
| area-DependencyModel | @jeffhandley | @dotnet/area-dependencymodel | Included:<ul><li>Microsoft.Extensions.DependencyModel</li></ul> |
|
||||
| area-Diagnostics-coreclr | @steveisok | @tommcdon @dotnet/dotnet-diag | |
|
||||
| area-Diagnostics-mono | @steveisok | @tommcdon @mdh1418 @thaystg | |
|
||||
| area-EnC-mono | @steveisok | @dotnet/dotnet-diag @thaystg | Hot Reload on WebAssembly, Android, iOS, etc. |
|
||||
| area-ExceptionHandling-coreclr | @mangod9 | @janvorli | |
|
||||
| area-Extensions-Caching | @jeffhandley | @dotnet/area-extensions-caching | Consultants: @mgravell, @sebastienros |
|
||||
| area-Extensions-Configuration | @ericstj | @dotnet/area-extensions-configuration | Consultants: @eerhardt |
|
||||
| area-Extensions-DependencyInjection | @ericstj | @dotnet/area-extensions-dependencyinjection | Consultants: @halter73, @benjaminpetit |
|
||||
| area-Extensions-Configuration | @jeffhandley | @dotnet/area-extensions-configuration | Consultants: @eerhardt |
|
||||
| area-Extensions-DependencyInjection | @jeffhandley | @dotnet/area-extensions-dependencyinjection | Consultants: @halter73, @benjaminpetit |
|
||||
| area-Extensions-FileSystem | @jeffhandley | @dotnet/area-extensions-filesystem | |
|
||||
| area-Extensions-Hosting | @ericstj | @dotnet/area-extensions-hosting | Consultants: @halter73, @tratcher |
|
||||
| area-Extensions-Hosting | @jeffhandley | @dotnet/area-extensions-hosting | Consultants: @halter73, @tratcher |
|
||||
| area-Extensions-HttpClientFactory | @karelz | @dotnet/ncl | |
|
||||
| area-Extensions-Logging | @ericstj | @dotnet/area-extensions-logging | Consultants: @brennanconroy |
|
||||
| area-Extensions-Options | @ericstj | @dotnet/area-extensions-options | Consultants: @eerhardt, @brennanconroy |
|
||||
| area-Extensions-Primitives | @ericstj | @dotnet/area-extensions-primitives | |
|
||||
| area-Extensions-Logging | @jeffhandley | @dotnet/area-extensions-logging | Consultants: @brennanconroy |
|
||||
| area-Extensions-Options | @jeffhandley | @dotnet/area-extensions-options | Consultants: @eerhardt, @brennanconroy |
|
||||
| area-Extensions-Primitives | @jeffhandley | @dotnet/area-extensions-primitives | |
|
||||
| area-GC-coreclr | @mangod9 | @Maoni0 | |
|
||||
| area-GC-mono | @mangod9 | @mangod9 | @BrzVlad to consult |
|
||||
| area-Host | @agocke | @jeffschwMSFT @elinor-fung | Issues with dotnet.exe including bootstrapping, framework detection, hostfxr.dll and hostpolicy.dll |
|
||||
| area-HostModel | @agocke | @elinor-fung | |
|
||||
| area-ILTools-coreclr | @JulieLeeMSFT | @BruceForstall @dotnet/jit-contrib | |
|
||||
| area-ILTools-coreclr | @JulieLeeMSFT | @dotnet/jit-contrib | |
|
||||
| area-Infrastructure | @agocke | @jeffschwMSFT @MichaelSimons | |
|
||||
| area-Infrastructure-coreclr | @agocke | @jeffschwMSFT | |
|
||||
| area-Infrastructure-installer | @MichaelSimons | @NikolaMilosavljevic | |
|
||||
| area-Infrastructure-libraries | @ericstj | @dotnet/area-infrastructure-libraries | Covers:<ul><li>Packaging</li><li>Build and test infra for libraries in dotnet/runtime repo</li><li>VS integration</li></ul><br/> |
|
||||
| area-Infrastructure-libraries | @jeffhandley | @dotnet/area-infrastructure-libraries | Covers:<ul><li>Packaging</li><li>Build and test infra for libraries in dotnet/runtime repo</li><li>VS integration</li></ul><br/> |
|
||||
| area-Infrastructure-mono | @steveisok | @agocke | |
|
||||
| area-Interop-coreclr | @agocke | @AaronRobinsonMSFT @jkoritzinsky | |
|
||||
| area-Interop-mono | @agocke | @AaronRobinsonMSFT @jkoritzinsky | |
|
||||
| area-Meta | @jeffhandley | @dotnet/area-meta | Cross-cutting concerns that span many or all areas, including project-wide code/test patterns and documentation. |
|
||||
| area-Microsoft.CSharp | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) |
|
||||
| area-Microsoft.VisualBasic | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) |
|
||||
| area-Microsoft.Win32 | @ericstj | @dotnet/area-microsoft-win32 | Included:<ul><li>System.Windows.Extensions</li></ul> |
|
||||
| area-Microsoft.Win32 | @jeffhandley | @dotnet/area-microsoft-win32 | Included:<ul><li>System.Windows.Extensions</li></ul> |
|
||||
| area-NativeAOT-coreclr | @agocke | @dotnet/ilc-contrib | |
|
||||
| area-PAL-coreclr | @mangod9 | @janvorli | |
|
||||
| area-R2RDump-coreclr | @mangod9 | | |
|
||||
| area-ReadyToRun-coreclr | @mangod9 | | |
|
||||
| area-Serialization | @HongGit | @StephenMolloy @HongGit | Packages:<ul><li>System.Runtime.Serialization.Xml</li><li>System.Runtime.Serialization.Json</li><li>System.Private.DataContractSerialization</li><li>System.Xml.XmlSerializer</li></ul> Excluded:<ul><li>System.Runtime.Serialization.Formatters</li></ul> |
|
||||
| area-Serialization | @StephenMolloy | @StephenMolloy @dotnet/Tellurium | Packages:<ul><li>System.Runtime.Serialization.Xml</li><li>System.Runtime.Serialization.Json</li><li>System.Private.DataContractSerialization</li><li>System.Xml.XmlSerializer</li></ul> Excluded:<ul><li>System.Runtime.Serialization.Formatters</li></ul> |
|
||||
| area-Setup | @MichaelSimons | @NikolaMilosavljevic | Distro-specific (Linux, Mac and Windows) setup packages and msi files |
|
||||
| area-Single-File | @agocke | @elinor-fung @vsadov | |
|
||||
| area-Snap | @MichaelSimons | @NikolaMilosavljevic @leecow @MichaelSimons | |
|
||||
| area-System.Buffers | @jeffhandley | @dotnet/area-system-buffers | |
|
||||
| area-System.ClientModel | @terrajobst | @dotnet/fxdc | Bugs and feature requests should go to https://github.com/Azure/azure-sdk-for-net/issues. We don't own the code, but FXDC reviews changes to determine overlap with other `System` concepts. The Azure SDK team will post API updates in this repo for us to review. |
|
||||
| area-System.CodeDom | @ericstj | @dotnet/area-system-codedom | |
|
||||
| area-System.CodeDom | @jeffhandley | @dotnet/area-system-codedom | |
|
||||
| area-System.Collections | @jeffhandley | @dotnet/area-system-collections | Excluded:<ul><li>System.Array -> System.Runtime</li></ul> |
|
||||
| area-System.ComponentModel | @ericstj | @dotnet/area-system-componentmodel | Consultants: @dotnet/dotnet-winforms |
|
||||
| area-System.ComponentModel.Composition | @ericstj | @dotnet/area-system-componentmodel-composition | |
|
||||
| area-System.ComponentModel | @jeffhandley | @dotnet/area-system-componentmodel | Consultants: @dotnet/dotnet-winforms |
|
||||
| area-System.ComponentModel.Composition | @jeffhandley | @dotnet/area-system-componentmodel-composition | |
|
||||
| area-System.ComponentModel.DataAnnotations | @jeffhandley | @dotnet/area-system-componentmodel-dataannotations | Included:<ul><li>System.ComponentModel.Annotations</li></ul> |
|
||||
| area-System.Composition | @ericstj | @dotnet/area-system-composition | |
|
||||
| area-System.Configuration | @ericstj | @dotnet/area-system-configuration | |
|
||||
| area-System.Composition | @jeffhandley | @dotnet/area-system-composition | |
|
||||
| area-System.Configuration | @jeffhandley | @dotnet/area-system-configuration | |
|
||||
| area-System.Console | @jeffhandley | @dotnet/area-system-console | |
|
||||
| area-System.Data | @sammonort | @ajcvickers @roji | <ul><li>Odbc, OleDb - @saurabh500</li></ul> |
|
||||
| area-System.Data.Odbc | @sammonort | @ajcvickers @roji | |
|
||||
| area-System.Data.OleDB | @sammonort | @ajcvickers @roji | |
|
||||
| area-System.Data.SqlClient | @David-Engel | @cheenamalhotra @david-engel | Archived component - limited churn/contributions (see https://devblogs.microsoft.com/dotnet/introducing-the-new-microsoftdatasqlclient/) |
|
||||
| area-System.DateTime | @ericstj | @dotnet/area-system-datetime | System namespace APIs related to dates and times, including DateOnly, DateTime, DateTimeKind, DateTimeOffset, DayOfWeek, TimeOnly, TimeSpan, TimeZone, and TimeZoneInfo |
|
||||
| area-System.DateTime | @jeffhandley | @dotnet/area-system-datetime | System namespace APIs related to dates and times, including DateOnly, DateTime, DateTimeKind, DateTimeOffset, DayOfWeek, TimeOnly, TimeSpan, TimeZone, and TimeZoneInfo |
|
||||
| area-System.Diagnostics | @steveisok | @dotnet/area-system-diagnostics | |
|
||||
| area-System.Diagnostics-coreclr | @steveisok | @dotnet/area-system-diagnostics-coreclr | |
|
||||
| area-System.Diagnostics-mono | @steveisok | @dotnet/dotnet-diag | |
|
||||
| area-System.Diagnostics.Activity | @ericstj | @dotnet/area-system-diagnostics-activity | |
|
||||
| area-System.Diagnostics.EventLog | @ericstj | @dotnet/area-system-diagnostics-eventlog | |
|
||||
| area-System.Diagnostics.Metric | @ericstj | @dotnet/area-system-diagnostics-metric | |
|
||||
| area-System.Diagnostics.PerformanceCounter | @ericstj | @dotnet/area-system-diagnostics-performancecounter | |
|
||||
| area-System.Diagnostics.Activity | @jeffhandley | @dotnet/area-system-diagnostics-activity | |
|
||||
| area-System.Diagnostics.EventLog | @jeffhandley | @dotnet/area-system-diagnostics-eventlog | |
|
||||
| area-System.Diagnostics.Metric | @jeffhandley | @dotnet/area-system-diagnostics-metric | |
|
||||
| area-System.Diagnostics.PerformanceCounter | @jeffhandley | @dotnet/area-system-diagnostics-performancecounter | |
|
||||
| area-System.Diagnostics.Process | @jeffhandley | @dotnet/area-system-diagnostics-process | |
|
||||
| area-System.Diagnostics.Tracing | @steveisok | @dotnet/area-system-diagnostics-tracing | Included:<ul><li>System.Diagnostics.DiagnosticSource</li></ul> |
|
||||
| area-System.Diagnostics.TraceSource | @ericstj | @dotnet/area-system-diagnostics-tracesource | |
|
||||
| area-System.DirectoryServices | @ericstj | @dotnet/area-system-directoryservices | Consultants: @BRDPM @grubioe @jay98014 |
|
||||
| area-System.Drawing | @ericstj | @dotnet/area-system-drawing | Excluded:<ul><li>System.Drawing.Common -> winforms</li></ul> |
|
||||
| area-System.Diagnostics.TraceSource | @jeffhandley | @dotnet/area-system-diagnostics-tracesource | |
|
||||
| area-System.DirectoryServices | @jeffhandley | @dotnet/area-system-directoryservices | Consultants: @BRDPM @grubioe @jay98014 |
|
||||
| area-System.Drawing | @jeffhandley | @dotnet/area-system-drawing | Excluded:<ul><li>System.Drawing.Common -> winforms</li></ul> |
|
||||
| area-System.Dynamic.Runtime | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) |
|
||||
| area-System.Formats.Asn1 | @jeffhandley | @dotnet/area-system-formats-asn1 | Consultants: @bartonjs @vcsjones |
|
||||
| area-System.Formats.Cbor | @jeffhandley | @dotnet/area-system-formats-cbor | Consultants: @bartonjs @vcsjones |
|
||||
| area-System.Formats.Nrbf | @jeffhandley | @dotnet/area-system-formats-nrbf | Consultants: @bartonjs @grabyourpitchforks |
|
||||
| area-System.Formats.Tar | @ericstj | @dotnet/area-system-formats-tar | |
|
||||
| area-System.Globalization | @ericstj | @dotnet/area-system-globalization | |
|
||||
| area-System.Formats.Tar | @jeffhandley | @dotnet/area-system-formats-tar | |
|
||||
| area-System.Globalization | @jeffhandley | @dotnet/area-system-globalization | |
|
||||
| area-System.IO | @jeffhandley | @dotnet/area-system-io | |
|
||||
| area-System.IO.Compression | @ericstj | @dotnet/area-system-io-compression | Included:<ul><li>System.Formats.Tar</li><li>System.IO.Packaging</li></ul> |
|
||||
| area-System.IO.Compression | @jeffhandley | @dotnet/area-system-io-compression | Included:<ul><li>System.Formats.Tar</li><li>System.IO.Packaging</li></ul> |
|
||||
| area-System.IO.Hashing | @jeffhandley | @dotnet/area-system-io-hashing | APIs within the System.IO.Hashing namespace, which align more with cryptography than with I/O |
|
||||
| area-System.IO.Pipelines | @adityamandaleeka | @davidfowl @halter73 | |
|
||||
| area-System.IO.Ports | @jeffhandley | @dotnet/area-system-io-ports | |
|
||||
| area-System.Linq | @jeffhandley | @dotnet/area-system-linq | |
|
||||
| area-System.Linq.Expressions | @jaredpar | @cston @333fred | Archived component - limited churn/contributions (see [#27790](https://github.com/dotnet/runtime/issues/27790)) |
|
||||
| area-System.Linq.Parallel | @jeffhandley | @dotnet/area-system-linq-parallel | Consultants: @stephentoub @kouvel |
|
||||
| area-System.Management | @ericstj | @dotnet/area-system-management | WMI |
|
||||
| area-System.Management | @jeffhandley | @dotnet/area-system-management | WMI |
|
||||
| area-System.Memory | @jeffhandley | @dotnet/area-system-memory | |
|
||||
| area-System.Net | @karelz | @dotnet/ncl | Included:<ul><li>System.Uri</li></ul> |
|
||||
| area-System.Net.Http | @karelz | @dotnet/ncl | |
|
||||
|
@ -114,25 +114,25 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi
|
|||
| area-System.Net.Sockets | @karelz | @dotnet/ncl | |
|
||||
| area-System.Numerics | @jeffhandley | @dotnet/area-system-numerics | |
|
||||
| area-System.Numerics.Tensors | @jeffhandley | @dotnet/area-system-numerics-tensors | |
|
||||
| area-System.Reflection | @ericstj | @dotnet/area-system-reflection | |
|
||||
| area-System.Reflection.Emit | @ericstj | @dotnet/area-system-reflection-emit | |
|
||||
| area-System.Reflection.Metadata | @ericstj | @dotnet/area-system-reflection-metadata | Consultants: @tmat |
|
||||
| area-System.Resources | @ericstj | @dotnet/area-system-resources | |
|
||||
| area-System.Reflection | @jeffhandley | @dotnet/area-system-reflection | |
|
||||
| area-System.Reflection.Emit | @jeffhandley | @dotnet/area-system-reflection-emit | |
|
||||
| area-System.Reflection.Metadata | @jeffhandley | @dotnet/area-system-reflection-metadata | Consultants: @tmat |
|
||||
| area-System.Resources | @jeffhandley | @dotnet/area-system-resources | |
|
||||
| area-System.Runtime | @jeffhandley | @dotnet/area-system-runtime | Included:<ul><li>System.Runtime.Serialization.Formatters</li><li>System.Runtime.InteropServices.RuntimeInfo</li><li>System.Array</li></ul>Excluded:<ul><li>Path -> System.IO</li><li>StopWatch -> System.Diagnostics</li><li>Uri -> System.Net</li><li>WebUtility -> System.Net</li></ul> |
|
||||
| area-System.Runtime.Caching | @HongGit | @StephenMolloy @HongGit | |
|
||||
| area-System.Runtime.CompilerServices | @ericstj | @dotnet/area-system-runtime-compilerservices | |
|
||||
| area-System.Runtime.Caching | @StephenMolloy | @StephenMolloy @dotnet/Tellurium | |
|
||||
| area-System.Runtime.CompilerServices | @jeffhandley | @dotnet/area-system-runtime-compilerservices | |
|
||||
| area-System.Runtime.InteropServices | @agocke | @AaronRobinsonMSFT @jkoritzinsky | Excluded:<ul><li>System.Runtime.InteropServices.RuntimeInfo</li></ul> |
|
||||
| area-System.Runtime.InteropServices.JavaScript | @lewing | @pavelsavara | |
|
||||
| area-System.Runtime.Intrinsics | @jeffhandley | @dotnet/area-system-runtime-intrinsics | Consultants: @echesakovMSFT @kunalspathak |
|
||||
| area-System.Security | @jeffhandley | @dotnet/area-system-security | Consultants: @bartonjs @GrabYourPitchforks @SteveHarter @vcsjones @wfurt |
|
||||
| area-System.ServiceModel | @HongGit | @HongGit @mconnew | Repo: https://github.com/dotnet/WCF<br>Packages:<ul><li>System.ServiceModel.Primitives</li><li>System.ServiceModel.Http</li><li>System.ServiceModel.NetTcp</li><li>System.ServiceModel.Duplex</li><li>System.ServiceModel.Security</li></ul> |
|
||||
| area-System.ServiceModel.Syndication | @HongGit | @StephenMolloy @HongGit | |
|
||||
| area-System.ServiceProcess | @ericstj | @dotnet/area-system-serviceprocess | |
|
||||
| area-System.Speech | @ericstj | @dotnet/area-system-speech | |
|
||||
| area-System.Text.Encoding | @ericstj | @dotnet/area-system-text-encoding | |
|
||||
| area-System.Text.Encodings.Web | @ericstj | @dotnet/area-system-text-encodings-web | |
|
||||
| area-System.Security | @jeffhandley | @dotnet/area-system-security | Consultants: @bartonjs @GrabYourPitchforks @vcsjones @wfurt |
|
||||
| area-System.ServiceModel | @mconnew | @mconnew @dotnet/Tellurium | Repo: https://github.com/dotnet/WCF<br>Packages:<ul><li>System.ServiceModel.Primitives</li><li>System.ServiceModel.Http</li><li>System.ServiceModel.NetTcp</li><li>System.ServiceModel.Duplex</li><li>System.ServiceModel.Security</li></ul> |
|
||||
| area-System.ServiceModel.Syndication | @StephenMolloy | @StephenMolloy @dotnet/Tellurium | |
|
||||
| area-System.ServiceProcess | @jeffhandley | @dotnet/area-system-serviceprocess | |
|
||||
| area-System.Speech | @jeffhandley | @dotnet/area-system-speech | |
|
||||
| area-System.Text.Encoding | @jeffhandley | @dotnet/area-system-text-encoding | |
|
||||
| area-System.Text.Encodings.Web | @jeffhandley | @dotnet/area-system-text-encodings-web | |
|
||||
| area-System.Text.Json | @jeffhandley | @dotnet/area-system-text-json | |
|
||||
| area-System.Text.RegularExpressions | @ericstj | @dotnet/area-system-text-regularexpressions | Consultants: @stephentoub |
|
||||
| area-System.Text.RegularExpressions | @jeffhandley | @dotnet/area-system-text-regularexpressions | Consultants: @stephentoub |
|
||||
| area-System.Threading | @mangod9 | @kouvel @vsadov | |
|
||||
| area-System.Threading.Channels | @jeffhandley | @dotnet/area-system-threading-channels | Consultants: @stephentoub |
|
||||
| area-System.Threading.RateLimiting | @rafikiassumani-msft | @BrennanConroy @halter73 | |
|
||||
|
@ -141,7 +141,7 @@ Note: Editing this file doesn't update the mapping used by `@dotnet-policy-servi
|
|||
| area-System.Xml | @jeffhandley | @dotnet/area-system-xml | |
|
||||
| area-TieredCompilation-coreclr | @mangod9 | @kouvel | |
|
||||
| area-Tools-ILLink | @agocke | @dotnet/illink | |
|
||||
| area-Tools-ILVerification | @JulieLeeMSFT | @BruceForstall @dotnet/jit-contrib | |
|
||||
| area-Tools-ILVerification | @JulieLeeMSFT | @dotnet/jit-contrib | |
|
||||
| area-Tracing-coreclr | @steveisok | @dotnet/area-tracing-coreclr | .NET runtime issues for EventPipe and ICorProfiler |
|
||||
| area-Tracing-mono | @steveisok | @dotnet/dotnet-diag @thaystg | |
|
||||
| area-TypeSystem-coreclr | @mangod9 | @davidwrighton @MichalStrehovsky @janvorli @mangod9 | |
|
||||
|
|
|
@ -15,12 +15,6 @@ We have the following goals related to interop code being used in dotnet/runtime
|
|||
- Ensure maximal managed code reuse across different OS flavors which have the same API but not the same ABI.
|
||||
- This is the case for UNIX and addressing it is a work-in-progress (see issue #2137 and section on "shims" below.)
|
||||
|
||||
## Submitting Changes
|
||||
|
||||
Interop code implicitly defines the native platform dependencies that .NET has. These dependencies are tracked and modeled according to the [Tracking Platform Dependencies design](https://github.com/dotnet/designs/blob/main/accepted/2021/platform-dependencies/platform-dependencies.md). Whenever a PR is submitted that changes interop code, it needs to be reviewed to determine whether a change to the platform dependencies model is required.
|
||||
|
||||
By default, any change to `src/libraries/Common/src/Interop` folder will add @dotnet/platform-deps-team as a reviewer. If necessary, update the corresponding `https://github.com/dotnet/core/blob/main/release-notes/<product-version>/runtime-deps.json` file to reflect the dependency change. The scope of dependencies is at the file/package level, not individual functions, so interop changes rarely require an update to the model.
|
||||
|
||||
## Approach
|
||||
|
||||
### Interop type
|
||||
|
|
|
@ -523,7 +523,7 @@ int ManagedReferencesSum(int[] buffer)
|
|||
|
||||
Vector128<int> sum = Vector128<int>.Zero;
|
||||
|
||||
while (!Unsafe.IsAddressGreaterThan(ref current, ref oneVectorAwayFromEnd))
|
||||
while (Unsafe.IsAddressLessThanOrEqualTo(ref current, ref oneVectorAwayFromEnd))
|
||||
{
|
||||
sum += Vector128.LoadUnsafe(ref current);
|
||||
|
||||
|
@ -561,7 +561,7 @@ do
|
|||
|
||||
return ...;
|
||||
}
|
||||
while (!Unsafe.IsAddressLessThan(ref currentSearchSpace, ref searchSpace));
|
||||
while (Unsafe.IsAddressGreaterThanOrEqualTo(ref currentSearchSpace, ref searchSpace));
|
||||
```
|
||||
|
||||
It was part of `LastIndexOf` implementation, where we were iterating from the end to the beginning of the buffer. In the last iteration of the loop, `currentSearchSpace` could become a pointer to unknown memory that lied before the beginning of the buffer:
|
||||
|
@ -573,7 +573,7 @@ currentSearchSpace = ref Unsafe.Subtract(ref currentSearchSpace, Vector128<TValu
|
|||
And it was fine until GC kicked right after that, moved objects in memory, updated all valid managed references and resumed the execution, which run following condition:
|
||||
|
||||
```csharp
|
||||
while (!Unsafe.IsAddressLessThan(ref currentSearchSpace, ref searchSpace));
|
||||
while (Unsafe.IsAddressGreaterThanOrEqualTo(ref currentSearchSpace, ref searchSpace));
|
||||
```
|
||||
|
||||
Which could return true because `currentSearchSpace` was invalid and not updated. If you are interested in more details, you can check the [issue](https://github.com/dotnet/runtime/issues/75792#issuecomment-1249973858) and the [fix](https://github.com/dotnet/runtime/pull/75857).
|
||||
|
|
|
@ -712,22 +712,82 @@ the first byte of the encoding specify the number of following bytes as follows:
|
|||
|
||||
## Sparse Array
|
||||
|
||||
**TODO**: Document native format sparse array
|
||||
The NativeArray provides O(1) indexed access while maintaining compact storage through null element compression (empty blocks share storage) and variable-sized offset encoding (adapts to data size).
|
||||
|
||||
The array is made up of three parts, the header, block index, and the blocks.
|
||||
|
||||
The header is a variable encoded value where:
|
||||
- Bits 0-1: Entry index size
|
||||
- 0 = uint8 offsets
|
||||
- 1 = uint16 offsets
|
||||
- 2 = uint32 offsets
|
||||
- Bits 2-31: Number of elements in the array
|
||||
|
||||
The block index immediately follows the header in memory and consists of one offset entry per block (dynamic size encoded in the header), where each entry points to the location of a data block relative to the start of the block index section. The array uses a maximum block size of 16 elements, the block index effectively maps every group of 16 consecutive array indices to their corresponding data blocks.
|
||||
|
||||
The following the block index are the actual data blocks. These are made up of two types of nodes. Tree nodes and Data nodes.
|
||||
|
||||
Tree nodes are made up of a variable length encoded uint where:
|
||||
- Bit 0: If set, the node has a lower index child
|
||||
- Bit 1: If set, the node has a higher index child
|
||||
- Bits 2-31: Shifted relative offset of higher index child
|
||||
|
||||
Data nodes contain the user defined data.
|
||||
|
||||
Since each block has at most 16 elements, they have a depth of `4`.
|
||||
|
||||
### Lookup Algorithm Steps
|
||||
|
||||
**Step 1: Read the Header**
|
||||
- Decode the variable-length encoded header value from the array
|
||||
- Extract the entry index size from bits 0-1 (0=uint8, 1=uint16, 2=uint32 offsets)
|
||||
- Extract the total number of elements from bits 2-31 by right-shifting the header value by 2 bits
|
||||
- Use this information to determine how to interpret the block index entries and validate array bounds
|
||||
|
||||
**Step 2: Calculate Block Offset**
|
||||
- Determine the block index `blockIndex` containing the target element by dividing the index by the block size (16).
|
||||
- Calculate the memory location containing the block offset `pBlockOffset = baseOffset + entrySize * blockIndex` where `baseOffset` is the address immediately following the header and `entrySize` is determined by the low bits of the header.
|
||||
- Read the block offset `blockOffset` from the block index table using the calculated `pBlockOffset` and entry size determined by the header.
|
||||
- Add the `baseOffset` to convert the relative `blockOffset` to an absolute position.
|
||||
|
||||
**Step 3: Initialize Tree Navigation**
|
||||
- Using the `blockOffset` calculated above, begin traversal at the root of the block's binary tree structure
|
||||
|
||||
**Step 4: Navigate Binary Tree**
|
||||
For each level of the tree (iterating through bit positions 8, 4, 2, 1):
|
||||
|
||||
**Step 4a: Read Node Descriptor**
|
||||
- Decode the current node's control value, which contains navigation flags and child offset information
|
||||
- Extract flags indicating the presence of left and right child nodes
|
||||
- Extract the relative offset to the right child node (if present)
|
||||
|
||||
**Step 4b: Determine Navigation Direction**
|
||||
- Test the current bit position against the target index
|
||||
- If the bit is set in the target index, attempt to navigate to the right child
|
||||
- If the bit is clear in the target index, attempt to navigate to the left child
|
||||
|
||||
**Step 4c: Follow Navigation Path**
|
||||
- If the desired child exists (indicated by the appropriate flag), update the current position
|
||||
- For right child navigation, add the encoded offset to the current position
|
||||
- For left child navigation, move to the position immediately following the current node
|
||||
- Continue to the next bit level if navigation was successful
|
||||
|
||||
**Step 5: Return Element Location**
|
||||
- Upon successful traversal, return the final offset position which points to the stored data.
|
||||
- If traversal is not successful (child node does not exist), the element can not be found in the array and return a failure status.
|
||||
|
||||
## Hashtable
|
||||
|
||||
Conceptually, a native hash table is a header that describe the dimensions of the table, a table that maps hash values of the keys to buckets followed with a list of buckets that store the values. These three things are stored consecutively in the format.
|
||||
|
||||
To make look up fast, the number of buckets is always a power of 2. The table is simply a sequence of `(1 + number of buckets)` cells, for the first `(number of buckets)` cells, its stores the offset of the bucket list from the beginning of the whole native hash table. The last cell stores the offset to the end of the buckets.
|
||||
|
||||
Each bucket is a sequence of entries. An entry has a hash code and an offset to the object stored. The entries are sorted by hash code.
|
||||
To make look up fast, the number of buckets is always a power of 2. The table is simply a sequence of `(1 + number of buckets)` cells, for the first `(number of buckets)` cells, its stores the offset of the bucket list from the beginning of the whole native hash table. The last cell stores the offset to the end of the buckets. Entries are mapped to buckets using `x` lowest bits of the hash not in the lowest byte where `2^x = (number of buckets)`. For example, if `x=2` the following bits marked with `X` would be used in a 32-bit hash `b00000000_00000000_000000XX_00000000`.
|
||||
|
||||
Physically, the header is a single byte. The most significant six bits is used to store the number of buckets in its base-2 logarithm. The remaining two bits are used for storing the entry size, as explained below:
|
||||
|
||||
Because the offsets to the bucket lists are often small numbers, the table cells are variable sized.
|
||||
It could be either 1 byte, 2 bytes or 4 bytes. The three cases are described with two bits. `00` means it is one byte, `01` means it is two bytes and `10` means it is four bytes.
|
||||
|
||||
The remaining data are the entries. The entries has only the least significant byte of the hash code, followed by the offset to the actual object stored in the hash table.
|
||||
The remaining data are the entries. The entries has only the least significant byte of the hash code, followed by the offset to the actual object stored in the hash table. The entries are sorted by hash code.
|
||||
|
||||
To perform a lookup, one starts with reading the header, computing the hash code, using the number of buckets to determine the number of bits to mask away from the hash code, look it up in the table using the right pointer size, find the bucket list, find the next bucket list (or the end of the table) so that we know where to stop, search the entries in that list and then we will find the object if we have a hit, or we have a miss.
|
||||
|
||||
|
@ -740,23 +800,23 @@ To see this in action, we can take a look at the following example, with these o
|
|||
| P | 0x1231 |
|
||||
| Q | 0x1232 |
|
||||
| R | 0x1234 |
|
||||
| S | 0x1238 |
|
||||
| S | 0x1338 |
|
||||
|
||||
Suppose we decided to have only two buckets, then only the least significant digit will be used to index the table, the whole hash table will look like this:
|
||||
Suppose we decided to have only two buckets, then only the 9th bit will be used to index the table, the whole hash table will look like this:
|
||||
|
||||
| Part | Offset | Content | Meaning |
|
||||
|:--------|:-------|:--------:|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Header | 0 | 0x04 | This is the header, the least significant bit is `00`, therefore the table cell is just one byte. The most significant six bit represents 1, which means the number of buckets is 2^1 = 2. |
|
||||
| Table | 1 | 0x08 | This is the representation of the unsigned integer 4, which correspond to the offset of the bucket correspond to hash code `0`. |
|
||||
| Table | 2 | 0x14 | This is the representation of the unsigned integer 10, which correspond to the offset of the bucket correspond to hash code `1`. |
|
||||
| Table | 3 | 0x18 | This is the representation of the unsigned integer 12, which correspond to the offset of the end of the whole hash table. |
|
||||
| Bucket1 | 4 | 0x32 | This is the least significant byte of the hash code of P |
|
||||
| Table | 1 | 0x04 | This is the representation of the unsigned integer 4, which correspond to the offset of the bucket correspond to hash code `0`. |
|
||||
| Table | 2 | 0x0A | This is the representation of the unsigned integer 10, which correspond to the offset of the bucket correspond to hash code `1`. |
|
||||
| Table | 3 | 0x0C | This is the representation of the unsigned integer 12, which correspond to the offset of the end of the whole hash table. |
|
||||
| Bucket1 | 4 | 0x31 | This is the least significant byte of the hash code of P |
|
||||
| Bucket1 | 5 | P | This should be the offset to the object P |
|
||||
| Bucket1 | 6 | 0x34 | This is the least significant byte of the hash code of Q |
|
||||
| Bucket1 | 6 | 0x32 | This is the least significant byte of the hash code of Q |
|
||||
| Bucket1 | 7 | Q | This should be the offset to the object Q |
|
||||
| Bucket1 | 8 | 0x38 | This is the least significant byte of the hash code of R |
|
||||
| Bucket1 | 8 | 0x34 | This is the least significant byte of the hash code of R |
|
||||
| Bucket1 | 9 | R | This should be the offset to the object R |
|
||||
| Bucket2 | 10 | 0x31 | This is the least significant byte of the hash code of S |
|
||||
| Bucket2 | 10 | 0x38 | This is the least significant byte of the hash code of S |
|
||||
| Bucket2 | 11 | S | This should be the offset to the object S |
|
||||
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ IEnumerable<ILCodeVersionHandle> ICodeVersions.GetILCodeVersions(TargetPointer m
|
|||
// CodeVersionManager::GetILCodeVersions
|
||||
GetModuleAndMethodDesc(methodDesc, out TargetPointer module, out uint methodDefToken);
|
||||
|
||||
ModuleHandle moduleHandle = _target.Contracts.Loader.GetModuleHandle(module);
|
||||
ModuleHandle moduleHandle = _target.Contracts.Loader.GetModuleHandleFromModulePtr(module);
|
||||
TargetPointer ilCodeVersionTable = _target.Contracts.Loader.GetLookupTables(moduleHandle).MethodDefToILCodeVersioningState;
|
||||
TargetPointer ilVersionStateAddress = _target.Contracts.Loader.GetModuleLookupMapElement(ilCodeVersionTable, methodDefToken, out var _);
|
||||
|
||||
|
@ -247,7 +247,7 @@ bool ICodeVersions.CodeVersionManagerSupportsMethod(TargetPointer methodDescAddr
|
|||
TypeHandle mt = rts.GetTypeHandle(mtAddr);
|
||||
TargetPointer modAddr = rts.GetModule(mt);
|
||||
ILoader loader = _target.Contracts.Loader;
|
||||
ModuleHandle mod = loader.GetModuleHandle(modAddr);
|
||||
ModuleHandle mod = loader.GetModuleHandleFromModulePtr(modAddr);
|
||||
ModuleFlags modFlags = loader.GetFlags(mod);
|
||||
if (modFlags.HasFlag(ModuleFlags.EditAndContinue))
|
||||
return false;
|
||||
|
|
|
@ -52,9 +52,12 @@ record struct ModuleLookupTables(
|
|||
```
|
||||
|
||||
``` csharp
|
||||
ModuleHandle GetModuleHandle(TargetPointer module);
|
||||
IEnumerable<ModuleHandle> GetModules(TargetPointer appDomain, AssemblyIterationFlags iterationFlags);
|
||||
ModuleHandle GetModuleHandleFromModulePtr(TargetPointer module);
|
||||
ModuleHandle GetModuleHandleFromAssemblyPtr(TargetPointer assemblyPointer);
|
||||
IEnumerable<ModuleHandle> GetModuleHandles(TargetPointer appDomain, AssemblyIterationFlags iterationFlags);
|
||||
TargetPointer GetRootAssembly();
|
||||
string GetAppDomainFriendlyName();
|
||||
TargetPointer GetModule(ModuleHandle handle);
|
||||
TargetPointer GetAssembly(ModuleHandle handle);
|
||||
TargetPointer GetPEAssembly(ModuleHandle handle);
|
||||
bool TryGetLoadedImageContents(ModuleHandle handle, out TargetPointer baseAddress, out uint size, out uint imageFlags);
|
||||
|
@ -64,12 +67,16 @@ ModuleFlags GetFlags(ModuleHandle handle);
|
|||
string GetPath(ModuleHandle handle);
|
||||
string GetFileName(ModuleHandle handle);
|
||||
TargetPointer GetLoaderAllocator(ModuleHandle handle);
|
||||
TargetPointer GetThunkHeap(ModuleHandle handle);
|
||||
TargetPointer GetILBase(ModuleHandle handle);
|
||||
TargetPointer GetAssemblyLoadContext(ModuleHandle handle);
|
||||
ModuleLookupTables GetLookupTables(ModuleHandle handle);
|
||||
TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out TargetNUInt flags);
|
||||
bool IsCollectible(ModuleHandle handle);
|
||||
bool IsAssemblyLoaded(ModuleHandle handle);
|
||||
TargetPointer GetGlobalLoaderAllocator();
|
||||
TargetPointer GetHighFrequencyHeap(TargetPointer loaderAllocatorPointer);
|
||||
TargetPointer GetLowFrequencyHeap(TargetPointer loaderAllocatorPointer);
|
||||
TargetPointer GetStubHeap(TargetPointer loaderAllocatorPointer);
|
||||
```
|
||||
|
||||
## Version 1
|
||||
|
@ -82,7 +89,6 @@ bool IsAssemblyLoaded(ModuleHandle handle);
|
|||
| `Module` | `Base` | Pointer to start of PE file in memory |
|
||||
| `Module` | `Flags` | Assembly of the Module |
|
||||
| `Module` | `LoaderAllocator` | LoaderAllocator of the Module |
|
||||
| `Module` | `ThunkHeap` | Pointer to the thunk heap |
|
||||
| `Module` | `Path` | Path of the Module (UTF-16, null-terminated) |
|
||||
| `Module` | `FileName` | File name of the Module (UTF-16, null-terminated) |
|
||||
| `Module` | `GrowableSymbolStream` | Pointer to the in memory symbol stream |
|
||||
|
@ -102,6 +108,8 @@ bool IsAssemblyLoaded(ModuleHandle handle);
|
|||
| `Assembly` | `NotifyFlags` | Flags relating to the debugger/profiler notification state of the assembly |
|
||||
| `Assembly` | `Level` | File load level of the assembly |
|
||||
| `PEAssembly` | `PEImage` | Pointer to the PEAssembly's PEImage |
|
||||
| `PEAssembly` | `AssemblyBinder` | Pointer to the PEAssembly's binder |
|
||||
| `AssemblyBinder` | `ManagedAssemblyLoadContext` | Pointer to the AssemblyBinder's ManagedAssemblyLoadContext |
|
||||
| `PEImage` | `LoadedImageLayout` | Pointer to the PEImage's loaded PEImageLayout |
|
||||
| `PEImage` | `ProbeExtensionResult` | PEImage's ProbeExtensionResult |
|
||||
| `ProbeExtensionResult` | `Type` | Type of ProbeExtensionResult |
|
||||
|
@ -112,18 +120,24 @@ bool IsAssemblyLoaded(ModuleHandle handle);
|
|||
| `CGrowableSymbolStream` | `Size` | Size of the raw symbol stream buffer |
|
||||
| `AppDomain` | `RootAssembly` | Pointer to the root assembly |
|
||||
| `AppDomain` | `DomainAssemblyList` | ArrayListBase of assemblies in the AppDomain |
|
||||
| `AppDomain` | `FriendlyName` | Friendly name of the AppDomain |
|
||||
| `LoaderAllocator` | `ReferenceCount` | Reference count of LoaderAllocator |
|
||||
| `LoaderAllocator` | `HighFrequencyHeap` | High-frequency heap of LoaderAllocator |
|
||||
| `LoaderAllocator` | `LowFrequencyHeap` | Low-frequency heap of LoaderAllocator |
|
||||
| `LoaderAllocator` | `StubHeap` | Stub heap of LoaderAllocator |
|
||||
| `ArrayListBase` | `Count` | Total number of elements in the ArrayListBase |
|
||||
| `ArrayListBase` | `FirstBlock` | First ArrayListBlock |
|
||||
| `ArrayListBlock` | `Next` | Next ArrayListBlock in chain |
|
||||
| `ArrayListBlock` | `Size` | Size of data section in block |
|
||||
| `ArrayListBlock` | `ArrayStart` | Start of data section in block |
|
||||
| `SystemDomain` | `GlobalLoaderAllocator` | global LoaderAllocator |
|
||||
|
||||
|
||||
### Global variables used:
|
||||
| Global Name | Type | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `AppDomain` | TargetPointer | Pointer to the global AppDomain |
|
||||
| `SystemDomain` | TargetPointer | Pointer to the global SystemDomain |
|
||||
|
||||
|
||||
### Contract Constants:
|
||||
|
@ -146,12 +160,18 @@ private enum ModuleFlags_1 : uint
|
|||
|
||||
### Method Implementations
|
||||
``` csharp
|
||||
ModuleHandle GetModuleHandle(TargetPointer modulePointer)
|
||||
ModuleHandle GetModuleHandleFromModulePtr(TargetPointer modulePointer)
|
||||
{
|
||||
return new ModuleHandle(modulePointer);
|
||||
}
|
||||
|
||||
IEnumerable<ModuleHandle> GetModules(TargetPointer appDomain, AssemblyIterationFlags iterationFlags)
|
||||
ModuleHandle ILoader.GetModuleHandleFromAssemblyPtr(TargetPointer assemblyPointer)
|
||||
{
|
||||
Data.Assembly assembly = // read Assembly object at assemblyPointer
|
||||
return new ModuleHandle(assembly.Module);
|
||||
}
|
||||
|
||||
IEnumerable<ModuleHandle> GetModuleHandles(TargetPointer appDomain, AssemblyIterationFlags iterationFlags)
|
||||
{
|
||||
if (appDomain == TargetPointer.Null) throw new ArgumentException("appDomain must not be null");
|
||||
|
||||
|
@ -255,6 +275,20 @@ TargetPointer GetRootAssembly()
|
|||
return appDomain.RootAssembly;
|
||||
}
|
||||
|
||||
string ILoader.GetAppDomainFriendlyName()
|
||||
{
|
||||
TargetPointer appDomainPointer = target.ReadGlobalPointer(Constants.Globals.AppDomain);
|
||||
TargetPointer appDomain = target.ReadPointer(appDomainPointer)
|
||||
TargetPointer pathStart = appDomain + /* AppDomain::FriendlyName offset */;
|
||||
char[] name = // Read<char> from target starting at pathStart until null terminator
|
||||
return new string(name);
|
||||
}
|
||||
|
||||
TargetPointer ILoader.GetModule(ModuleHandle handle)
|
||||
{
|
||||
return handle.Address;
|
||||
}
|
||||
|
||||
TargetPointer GetAssembly(ModuleHandle handle)
|
||||
{
|
||||
return target.ReadPointer(handle.Address + /* Module::Assembly offset */);
|
||||
|
@ -348,16 +382,19 @@ TargetPointer GetLoaderAllocator(ModuleHandle handle)
|
|||
return target.ReadPointer(handle.Address + /* Module::LoaderAllocator offset */);
|
||||
}
|
||||
|
||||
TargetPointer GetThunkHeap(ModuleHandle handle)
|
||||
{
|
||||
return target.ReadPointer(handle.Address + /* Module::ThunkHeap offset */);
|
||||
}
|
||||
|
||||
TargetPointer GetILBase(ModuleHandle handle)
|
||||
{
|
||||
return target.ReadPointer(handle.Address + /* Module::Base offset */);
|
||||
}
|
||||
|
||||
TargetPointer ILoader.GetAssemblyLoadContext(ModuleHandle handle)
|
||||
{
|
||||
PEAssembly peAssembly = target.ReadPointer(handle.Address + /* Module::PEAssembly offset */);
|
||||
AssemblyBinder binder = target.ReadPointer(peAssembly + /* PEAssembly::AssemblyBinder offset */);
|
||||
ObjectHandle objectHandle = new ObjectHandle(binder);
|
||||
return objectHandle.Object;
|
||||
}
|
||||
|
||||
ModuleLookupTables GetLookupTables(ModuleHandle handle)
|
||||
{
|
||||
return new ModuleLookupTables(
|
||||
|
@ -380,38 +417,59 @@ TargetPointer GetModuleLookupMapElement(TargetPointer table, uint token, out Tar
|
|||
uint index = rid;
|
||||
// have to read lookupMap an extra time upfront because only the first map
|
||||
// has valid supportedFlagsMask
|
||||
TargetNUInt supportedFlagsMask = _target.ReadNUInt(table + /* ModuleLookupMap::SupportedFlagsMask */);
|
||||
TargetNUInt supportedFlagsMask = target.ReadNUInt(table + /* ModuleLookupMap::SupportedFlagsMask */);
|
||||
do
|
||||
{
|
||||
if (index < _target.Read<uint>(table + /*ModuleLookupMap::Count*/))
|
||||
if (index < target.Read<uint>(table + /*ModuleLookupMap::Count*/))
|
||||
{
|
||||
TargetPointer entryAddress = _target.ReadPointer(lookupMap + /*ModuleLookupMap::TableData*/) + (ulong)(index * _target.PointerSize);
|
||||
TargetPointer rawValue = _target.ReadPointer(entryAddress);
|
||||
TargetPointer entryAddress = target.ReadPointer(lookupMap + /*ModuleLookupMap::TableData*/) + (ulong)(index * target.PointerSize);
|
||||
TargetPointer rawValue = target.ReadPointer(entryAddress);
|
||||
flags = rawValue & supportedFlagsMask;
|
||||
return rawValue & ~(supportedFlagsMask.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
table = _target.ReadPointer(lookupMap + /*ModuleLookupMap::Next*/);
|
||||
index -= _target.Read<uint>(lookupMap + /*ModuleLookupMap::Count*/);
|
||||
table = target.ReadPointer(lookupMap + /*ModuleLookupMap::Next*/);
|
||||
index -= target.Read<uint>(lookupMap + /*ModuleLookupMap::Count*/);
|
||||
}
|
||||
} while (table != TargetPointer.Null);
|
||||
return TargetPointer.Null;
|
||||
}
|
||||
```
|
||||
|
||||
```csharp
|
||||
bool ILoader.IsCollectible(ModuleHandle handle)
|
||||
bool IsCollectible(ModuleHandle handle)
|
||||
{
|
||||
TargetPointer assembly = _target.ReadPointer(handle.Address + /*Module::Assembly*/);
|
||||
byte isCollectible = _target.Read<byte>(assembly + /* Assembly::IsCollectible*/);
|
||||
TargetPointer assembly = target.ReadPointer(handle.Address + /*Module::Assembly*/);
|
||||
byte isCollectible = target.Read<byte>(assembly + /* Assembly::IsCollectible*/);
|
||||
return isCollectible != 0;
|
||||
}
|
||||
|
||||
bool ILoader.IsAssemblyLoaded(ModuleHandle handle)
|
||||
bool IsAssemblyLoaded(ModuleHandle handle)
|
||||
{
|
||||
TargetPointer assembly = _target.ReadPointer(handle.Address + /*Module::Assembly*/);
|
||||
uint loadLevel = _target.Read<uint>(assembly + /* Assembly::Level*/);
|
||||
TargetPointer assembly = target.ReadPointer(handle.Address + /*Module::Assembly*/);
|
||||
uint loadLevel = target.Read<uint>(assembly + /* Assembly::Level*/);
|
||||
return assembly.Level >= ASSEMBLY_LEVEL_LOADED;
|
||||
}
|
||||
|
||||
TargetPointer GetGlobalLoaderAllocator()
|
||||
{
|
||||
TargetPointer systemDomainPointer = target.ReadGlobalPointer(Constants.Globals.SystemDomain);
|
||||
TargetPointer systemDomain = target.ReadPointer(systemDomainPointer);
|
||||
return target.ReadPointer(systemDomain + /* SystemDomain::GlobalLoaderAllocator offset */);
|
||||
}
|
||||
|
||||
TargetPointer GetHighFrequencyHeap(TargetPointer loaderAllocatorPointer)
|
||||
{
|
||||
return target.ReadPointer(loaderAllocatorPointer + /* LoaderAllocator::HighFrequencyHeap offset */);
|
||||
}
|
||||
|
||||
TargetPointer GetLowFrequencyHeap(TargetPointer loaderAllocatorPointer)
|
||||
{
|
||||
return target.ReadPointer(loaderAllocatorPointer + /* LoaderAllocator::LowFrequencyHeap offset */);
|
||||
}
|
||||
|
||||
TargetPointer GetStubHeap(TargetPointer loaderAllocatorPointer)
|
||||
{
|
||||
return target.ReadPointer(loaderAllocatorPointer + /* LoaderAllocator::StubHeap offset */);
|
||||
}
|
||||
|
||||
```
|
||||
|
|
|
@ -51,14 +51,18 @@ partial interface IRuntimeTypeSystem : IContract
|
|||
// True if the MethodTable represents a type that contains managed references
|
||||
public virtual bool ContainsGCPointers(TypeHandle typeHandle);
|
||||
public virtual bool IsDynamicStatics(TypeHandle typeHandle);
|
||||
public virtual ushort GetNumMethods(TypeHandle typeHandle);
|
||||
public virtual ushort GetNumInterfaces(TypeHandle typeHandle);
|
||||
|
||||
// Returns an ECMA-335 TypeDef table token for this type, or for its generic type definition if it is a generic instantiation
|
||||
public virtual uint GetTypeDefToken(TypeHandle typeHandle);
|
||||
public virtual ushort GetNumMethods(TypeHandle typeHandle);
|
||||
// Returns the ECMA 335 TypeDef table Flags value (a bitmask of TypeAttributes) for this type,
|
||||
// or for its generic type definition if it is a generic instantiation
|
||||
public virtual uint GetTypeDefTypeAttributes(TypeHandle typeHandle);
|
||||
public ushort GetNumInstanceFields(TypeHandle typeHandle);
|
||||
public ushort GetNumStaticFields(TypeHandle typeHandle);
|
||||
public ushort GetNumThreadStaticFields(TypeHandle typeHandle);
|
||||
public TargetPointer GetFieldDescList(TypeHandle typeHandle);
|
||||
public virtual ReadOnlySpan<TypeHandle> GetInstantiation(TypeHandle typeHandle);
|
||||
public virtual bool IsGenericTypeDefinition(TypeHandle typeHandle);
|
||||
|
||||
|
@ -348,6 +352,10 @@ The contract additionally depends on these data descriptors
|
|||
| `EEClass` | `NumMethods` | Count of methods attached to the EEClass |
|
||||
| `EEClass` | `NumNonVirtualSlots` | Count of non-virtual slots for the EEClass |
|
||||
| `EEClass` | `CorTypeAttr` | Various flags |
|
||||
| `EEClass` | `NumInstanceFields` | Count of instance fields of the EEClass |
|
||||
| `EEClass` | `NumStaticFields` | Count of static fields of the EEClass |
|
||||
| `EEClass` | `NumThreadStaticFields` | Count of threadstatic fields of the EEClass |
|
||||
| `EEClass` | `FieldDescList` | A list of fields in the type |
|
||||
| `ArrayClass` | `Rank` | Rank of the associated array MethodTable |
|
||||
| `TypeDesc` | `TypeAndFlags` | The lower 8 bits are the CorElementType of the `TypeDesc`, the upper 24 bits are reserved for flags |
|
||||
| `ParamTypeDesc` | `TypeArg` | Associated type argument |
|
||||
|
@ -374,32 +382,6 @@ The contract additionally depends on these data descriptors
|
|||
return TypeHandle { Address = typeHandlePointer }
|
||||
}
|
||||
|
||||
internal static EEClassOrCanonMTBits GetEEClassOrCanonMTBits(TargetPointer eeClassOrCanonMTPtr)
|
||||
{
|
||||
return (EEClassOrCanonMTBits)(eeClassOrCanonMTPtr & (ulong)EEClassOrCanonMTBits.Mask);
|
||||
}
|
||||
|
||||
public uint GetBaseSize(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? (uint)0 : _methodTables[TypeHandle.Address].Flags.BaseSize;
|
||||
|
||||
public uint GetComponentSize(TypeHandle TypeHandle) =>!typeHandle.IsMethodTable() ? (uint)0 : GetComponentSize(_methodTables[TypeHandle.Address]);
|
||||
|
||||
private TargetPointer GetClassPointer(TypeHandle TypeHandle)
|
||||
{
|
||||
... // if the MethodTable stores a pointer to the EEClass, return it
|
||||
// otherwise the MethodTable stores a pointer to the canonical MethodTable
|
||||
// in that case, return the canonical MethodTable's EEClass.
|
||||
// Canonical MethodTables always store an EEClass pointer.
|
||||
}
|
||||
|
||||
private Data.EEClass GetClassData(TypeHandle TypeHandle)
|
||||
{
|
||||
TargetPointer eeClassPtr = GetClassPointer(TypeHandle);
|
||||
... // read Data.EEClass data from eeClassPtr
|
||||
}
|
||||
|
||||
|
||||
public TargetPointer GetCanonicalMethodTable(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : GetClassData(TypeHandle).MethodTable;
|
||||
|
||||
public TargetPointer GetModule(TypeHandle TypeHandle)
|
||||
{
|
||||
if (typeHandle.IsMethodTable())
|
||||
|
@ -420,13 +402,43 @@ The contract additionally depends on these data descriptors
|
|||
return TargetPointer.Null;
|
||||
}
|
||||
|
||||
internal static EEClassOrCanonMTBits GetEEClassOrCanonMTBits(TargetPointer eeClassOrCanonMTPtr)
|
||||
{
|
||||
return (EEClassOrCanonMTBits)(eeClassOrCanonMTPtr & (ulong)EEClassOrCanonMTBits.Mask);
|
||||
}
|
||||
|
||||
public TargetPointer GetCanonicalMethodTable(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : GetClassData(TypeHandle).MethodTable;
|
||||
|
||||
public TargetPointer GetParentMethodTable(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : _methodTables[TypeHandle.Address].ParentMethodTable;
|
||||
|
||||
public uint GetBaseSize(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? (uint)0 : _methodTables[TypeHandle.Address].Flags.BaseSize;
|
||||
|
||||
public uint GetComponentSize(TypeHandle TypeHandle) =>!typeHandle.IsMethodTable() ? (uint)0 : GetComponentSize(_methodTables[TypeHandle.Address]);
|
||||
|
||||
private TargetPointer GetClassPointer(TypeHandle TypeHandle)
|
||||
{
|
||||
... // if the MethodTable stores a pointer to the EEClass, return it
|
||||
// otherwise the MethodTable stores a pointer to the canonical MethodTable
|
||||
// in that case, return the canonical MethodTable's EEClass.
|
||||
// Canonical MethodTables always store an EEClass pointer.
|
||||
}
|
||||
|
||||
private Data.EEClass GetClassData(TypeHandle TypeHandle)
|
||||
{
|
||||
TargetPointer eeClassPtr = GetClassPointer(TypeHandle);
|
||||
... // read Data.EEClass data from eeClassPtr
|
||||
}
|
||||
|
||||
public bool IsFreeObjectMethodTable(TypeHandle TypeHandle) => FreeObjectMethodTablePointer == TypeHandle.Address;
|
||||
|
||||
public bool IsString(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.IsString;
|
||||
|
||||
public bool ContainsGCPointers(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.ContainsGCPointers;
|
||||
|
||||
public bool IsDynamicStatics(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.IsDynamicStatics;
|
||||
|
||||
public ushort GetNumInterfaces(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? 0 : _methodTables[TypeHandle.Address].NumInterfaces;
|
||||
|
||||
public uint GetTypeDefToken(TypeHandle TypeHandle)
|
||||
{
|
||||
if (!typeHandle.IsMethodTable())
|
||||
|
@ -438,11 +450,15 @@ The contract additionally depends on these data descriptors
|
|||
|
||||
public ushort GetNumMethods(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? 0 : GetClassData(TypeHandle).NumMethods;
|
||||
|
||||
public ushort GetNumInterfaces(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? 0 : _methodTables[TypeHandle.Address].NumInterfaces;
|
||||
|
||||
public uint GetTypeDefTypeAttributes(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? 0 : GetClassData(TypeHandle).CorTypeAttr;
|
||||
|
||||
public bool IsDynamicStatics(TypeHandle TypeHandle) => !typeHandle.IsMethodTable() ? false : _methodTables[TypeHandle.Address].Flags.IsDynamicStatics;
|
||||
public ushort GetNumInstanceFields(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : GetClassData(typeHandle).NumInstanceFields;
|
||||
|
||||
public ushort GetNumStaticFields(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : GetClassData(typeHandle).NumStaticFields;
|
||||
|
||||
public ushort GetNumThreadStaticFields(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? (ushort)0 : GetClassData(typeHandle).NumThreadStaticFields;
|
||||
|
||||
public TargetPointer GetFieldDescList(TypeHandle typeHandle) => !typeHandle.IsMethodTable() ? TargetPointer.Null : GetClassData(typeHandle).FieldDescList;
|
||||
|
||||
public ReadOnlySpan<TypeHandle> GetInstantiation(TypeHandle TypeHandle)
|
||||
{
|
||||
|
@ -1004,7 +1020,7 @@ Determining if a method is in a collectible module:
|
|||
{
|
||||
MethodDesc md = _methodDescs[methodDesc.Address];
|
||||
TargetPointer loaderModuleAddr = GetLoaderModule(md);
|
||||
ModuleHandle mod = _target.Contracts.Loader.GetModuleHandle(loaderModuleAddr);
|
||||
ModuleHandle mod = _target.Contracts.Loader.GetModuleHandleFromModulePtr(loaderModuleAddr);
|
||||
return _target.Contracts.Loader.IsCollectible(mod);
|
||||
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@ record struct ThreadData (
|
|||
ThreadStoreData GetThreadStoreData();
|
||||
ThreadStoreCounts GetThreadCounts();
|
||||
ThreadData GetThreadData(TargetPointer threadPointer);
|
||||
TargetPointer GetManagedThreadObject(TargetPointer threadPointer);
|
||||
```
|
||||
|
||||
## Version 1
|
||||
|
@ -128,10 +127,4 @@ ThreadData GetThreadData(TargetPointer address)
|
|||
NextThread: target.ReadPointer(address + /* Thread::LinkNext offset */) - threadLinkOffset;
|
||||
);
|
||||
}
|
||||
|
||||
TargetPointer GetManagedThreadObject(TargetPointer threadPointer)
|
||||
{
|
||||
var runtimeThread = new Thread(Target, threadPointer);
|
||||
return Contracts.GCHandle.GetObject(new DacGCHandle(runtimeThread.m_ExposedObject));
|
||||
}
|
||||
```
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# Debug Interface Globals
|
||||
|
||||
The following document lists the global variables that are used directly in the debug interface managed code (SOSDacImpl.cs, etc.)
|
||||
|
||||
Global variables used
|
||||
| Global Name | Type | Purpose |
|
||||
| --- | --- | --- |
|
||||
| StringMethodTable | TargetPointer | Identify where the string MethodTable exists |
|
||||
| ObjectMethodTable | TargetPointer | Identify where the object MethodTable exists |
|
||||
| SystemDomain | TargetPointer | Identify where the SystemDomain exists |
|
||||
| DirectorySeparator | TargetPointer | Identify where the directory separator exists |
|
||||
| FeatureCOMInterop | TargetPointer | Identify where the flag for FeatureCOMInterop exists |
|
||||
| StressLog | TargetPointer | Identify where the StressLog exists |
|
||||
| AppDomain | TargetPointer | Identify where the AppDomain exists |
|
||||
| ObjectArrayMethodTable | TargetPointer | Identify where the ObjectArrayMethodTable exists |
|
||||
| ExceptionMethodTable | TargetPointer | Identify where the ExceptionMethodTable exists |
|
||||
| FreeObjectMethodTable | TargetPointer | Identify where the FreeObjectMethodTable exists |
|
||||
| SOSBreakingChangeVersion | TargetPointer | Identify where the SOSBreakingChangeVersion exists |
|
||||
| DacNotificationFlags | TargetPointer | Identify where the DacNotificationFlags exists |
|
||||
| MaxClrNotificationArgs | uint32 | Identify the maximum number of CLR notification arguments |
|
||||
| ClrNotificationArguments | TargetPointer | Identify where the ClrNotificationArguments exists |
|
||||
| DefaultADID | uint | Identify the default AppDomain ID |
|
|
@ -41,7 +41,7 @@ Each IR instruction is represented by a MonoInst structure. The fields of the st
|
|||
|
||||
- ins-\>opcode contains the opcode of the instruction. It is always set.
|
||||
|
||||
- ins-\>dreg, ins-\>sreg1, ins-\>sreg2 contain the the destination and source vregs of the instruction. If the instruction doesn't have a destination/and our source, the corresponding field is set to -1.
|
||||
- ins-\>dreg, ins-\>sreg1, ins-\>sreg2 contain the destination and source vregs of the instruction. If the instruction doesn't have a destination/and our source, the corresponding field is set to -1.
|
||||
|
||||
- ins-\>backend is used for various purposes:
|
||||
- for MonoInst's representing vtype variables, it indicates that the variable is in unmanaged format (used during marshalling)
|
||||
|
|
|
@ -392,7 +392,7 @@ Each command requires at least one TypeID (of type id) parameter before any addi
|
|||
| GET_FIELD_CATTRS | 11 | Returns a list of custom attributes of a type's field. Custom attribute definition is given below. | Ask for a FieldID of one the type field and a TypeID of an custom attribute type | INVALID_TYPEID, INVALID_FIELDID |
|
||||
| GET_PROPERTY_CATTRS | 12 | Returns a list of custom attributes of a type's property. Custom attribute definition is given below. | Ask for a PropertyID of one the type field and a TypeID of an custom attribute type | INVALID_TYPEID, INVALID_PROPERTYID |
|
||||
| GET_SOURCE_FILES_2 | 13 | Returns a list of source file full paths (string) where the type is defined | None | INVALID_TYPEID |
|
||||
| GET_VALUES_2 | 14 | Returns a number of variant value equals to the number of FieldID that was passed as parameter. If the field had a ThreadStatic attribute applied to it, value fetched are from the thread parameter point of view. | Ask for an ObjectID representing a System.Thread instance and a list of FieldID representing this type static fields to the the value of. Only static field are supported. | INVALID_OBJECT, INVALID_TYPEID, INVALID_FIELDID |
|
||||
| GET_VALUES_2 | 14 | Returns a number of variant value equals to the number of FieldID that was passed as parameter. If the field had a ThreadStatic attribute applied to it, value fetched are from the thread parameter point of view. | Ask for an ObjectID representing a System.Thread instance and a list of FieldID representing this type static fields to the value of. Only static field are supported. | INVALID_OBJECT, INVALID_TYPEID, INVALID_FIELDID |
|
||||
|
||||
The main functions handling these commands are `type_commands` and `type_commands_internal` and are situated at `debugger-agent.c:6726` and `debugger-agent.c:6403` respectively.
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ Concretely, in the face of adversarial input:
|
|||
|
||||
## Implementation
|
||||
|
||||
The `HashCode` type uses the [**xxHash32**](https://github.com/Cyan4973/xxHash) algorithm, which is a non-cryptographic hash algorithm with a 32-bit seed and a 32-bit digest. All instances of the `HashCode` type use the same seed value, generated randomly at app start. This value is chosen independently of other random seed values in the runtime, such as the the global 64-bit seed used in `string.GetHashCode`'s Marvin32 routine.
|
||||
The `HashCode` type uses the [**xxHash32**](https://github.com/Cyan4973/xxHash) algorithm, which is a non-cryptographic hash algorithm with a 32-bit seed and a 32-bit digest. All instances of the `HashCode` type use the same seed value, generated randomly at app start. This value is chosen independently of other random seed values in the runtime, such as the global 64-bit seed used in `string.GetHashCode`'s Marvin32 routine.
|
||||
|
||||
The xxHash32 repo's README file touts good performance and avalanching. This can be validated through a simple C# program.
|
||||
|
||||
|
|
|
@ -95,6 +95,24 @@ static IEnumerable<int> TestLocalVariable ()
|
|||
}
|
||||
```
|
||||
|
||||
## Attribute propagation via CompilerLoweringPreserveAttribute
|
||||
|
||||
To address the challenges of propagating user-authored attributes to compiler-generated code, .NET 10 introduced a general mechanism: `[CompilerLoweringPreserveAttribute]`. This attribute can be applied to other attribute types to instruct compilers to propagate those attributes to compiler-generated code.
|
||||
|
||||
`DynamicallyAccessedMembersAttribute` is now marked with `[CompilerLoweringPreserve]`, so when the compiler generates new fields or type parameters (such as for local functions, iterator/async state machines, or primary constructor parameters), the relevant `DynamicallyAccessedMembers` annotations are automatically applied to the generated members. This allows trimming tools to directly use the annotations present in the generated code, without needing to reverse-engineer the mapping to user code.
|
||||
|
||||
### .NET 10 and later
|
||||
|
||||
For .NET 10 and later, trimming tools should rely on the compiler to propagate attributes such as `DynamicallyAccessedMembersAttribute` to all relevant compiler-generated code, as indicated by `[CompilerLoweringPreserve]`. No heuristics are needed for these assemblies. This isn't perfect because it's possible for such assemblies to be compiled with new Roslyn versions that could use different lowering strategies, so it's possible that the existing heuristics will break for new releases of a pre-`net10.0` assembly.
|
||||
|
||||
To mitigate this there are a few options:
|
||||
|
||||
1. Multitarget the library to `net10.0` (so that it is built with the new `CompilerLoweringPreserve` behavior and will avoid the heuristics)
|
||||
2. Fix the heuristics to work for code produced by new Roslyn versions
|
||||
3. The trimming tools could detect the presence of a polyfilled `DynamicallyAccessedMembersAttribute` type with `CompilerLoweringPreserve`. When present this would turn off the heuristics for the containing assembly.
|
||||
|
||||
Another issue is that .NET 10 libraries might be built with `<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>`, and the tooling would not be able to detect the TargetFramework. Aside from setting `<GenerateTargetFrameworkAttribute>true</GenerateTargetFrameworkAttribute>`, mitigations 1. and 2. above would also apply to this scenario.
|
||||
|
||||
### Compiler dependent behavior
|
||||
|
||||
Since the problems are all caused by compiler generated code, the behaviors depend on the specific compiler in use. The main focus of this document is the Roslyn C# compiler right now. Mainly since it's by far the most used compiler for .NET code. That said, we would like to design the solution in such a way that other compilers using similar patterns could also benefit from it.
|
||||
|
@ -560,9 +578,9 @@ and fields on the closure types.
|
|||
### Long term solution
|
||||
|
||||
Detecting which compiler generated items are used by any given user method is currently relatively tricky.
|
||||
There's no definitive marker in the IL which would let the trimmer confidently determine this information.
|
||||
Good long term solution will need the compilers to produce some kind of marker in the IL so that
|
||||
static analysis tools can reliably detect all of the compiler generated items.
|
||||
There's no definitive marker in the IL which would let the trimmer confidently determine this information
|
||||
for all of the above cases. Good long term solution will need the compilers to produce some kind of marker
|
||||
in the IL so that static analysis tools can reliably detect all of the compiler generated items.
|
||||
|
||||
This ask can be described as:
|
||||
For a given user method, ability to determine all of the items (methods, fields, types, IL code) which were
|
||||
|
@ -573,6 +591,10 @@ helpers and other infrastructure which may be needed but is not directly attribu
|
|||
|
||||
This should be enough to implement solutions for both suppression propagation and data flow analysis.
|
||||
|
||||
For `DynamicallyAccessedMembersAttribute`, we have a long-term solution that relies on the
|
||||
`[CompilerLoweringPreserve]` attribute, which tells Roslyn to propagate `DynamicallyAccessedMembers`
|
||||
annotations to compiler-generated code.
|
||||
|
||||
### Possible short term solution
|
||||
|
||||
#### Heuristic based solution
|
||||
|
|
|
@ -116,6 +116,7 @@ The PR that reveals the implementation of the `<IncludeInternalObsoleteAttribute
|
|||
| __`SYSLIB0059`__ | SystemEvents.EventsThreadShutdown callbacks are not run before the process exits. Use AppDomain.ProcessExit instead. |
|
||||
| __`SYSLIB0060`__ | The constructors on Rfc2898DeriveBytes are obsolete. Use the static Pbkdf2 method instead. |
|
||||
| __`SYSLIB0061`__ | The Queryable MinBy and MaxBy taking an IComparer\<TSource\> are obsolete. Use the new ones that take an IComparer\<TKey\>. |
|
||||
| __`SYSLIB0062`__ | XSLT Script blocks are not supported. |
|
||||
|
||||
## Analyzer Warnings
|
||||
|
||||
|
@ -296,7 +297,7 @@ The diagnostic id values reserved for .NET Libraries analyzer warnings are `SYSL
|
|||
APIs can be marked as `[Experimental]` if their shape or functionality is included in a release but not yet officially supported. Experimental APIs offer the opportunity to collect customer feedback on these APIs in a major release, usually refining the APIs and removing the `[Experimental]` attribute in the next release. The `[Experimental]` attribute differs from `[RequiresPreviewFeatures]`, wherein:
|
||||
|
||||
* `[RequiresPreviewFeatures]` APIs require a corresponding preview feature in another product area such as the compiler or SDK
|
||||
- Using these APIs requires enabling preview features for the the project and all its consumers
|
||||
- Using these APIs requires enabling preview features for the project and all its consumers
|
||||
* `[Experimental]` APIs are self-contained within the libraries and do not require preview features in other parts of the product
|
||||
- These APIs can be used by suppressing specific diagnostics without enabling preview features for the project
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ To build the runtime repo, you will also need to install the following dependenc
|
|||
|
||||
- `CMake` 3.20 or newer
|
||||
- `icu4c`
|
||||
- `openssl@1.1` or `openssl@3`
|
||||
- `pkg-config`
|
||||
- `python3`
|
||||
- `ninja` (This one is optional. It is an alternative tool to `make` for building native code)
|
||||
|
|
|
@ -46,9 +46,9 @@ It is highly recommended to use the *Workloads* approach, as that installs the f
|
|||
- .NET desktop development
|
||||
- Desktop development with C++
|
||||
|
||||
To build the tests and do ARM32/ARM64 development, you'll need some additional components. You can find them by clicking on the *Individual components* tab in the *Visual Studio Installer*:
|
||||
To build the tests and do ARM64 development, you'll need some additional components. You can find them by clicking on the *Individual components* tab in the *Visual Studio Installer*:
|
||||
|
||||
- For ARM stuff: *MSVC v143 - VS 2022 C++ ARM64/ARM64EC build tools (Latest)* for Arm64, and *MSVC v143 - VS 2022 C++ ARM build tools (Latest)* for Arm32.
|
||||
- For Arm64: *MSVC v143 - VS 2022 C++ ARM64/ARM64EC build tools (Latest)*
|
||||
- For building tests: *C++/CLI support for v143 build tools (Latest)*
|
||||
|
||||
Alternatively, there is also a `.vsconfig` file included at the root of the runtime repo. It includes all the necessary components required, outlined in a JSON format that Visual Studio can read and parse. You can boot up Visual Studio directly and [import this `.vsconfig` file](https://learn.microsoft.com/visualstudio/install/import-export-installation-configurations?view=vs-2022#import-a-configuration) instead of installing the workloads yourself. It is worth mentioning however, that while we are very careful in maintaining this file up-to-date, sometimes it might get a tad obsolete and miss important components. So, it is always a good idea to double check that the full workloads are installed.
|
||||
|
|
|
@ -118,11 +118,9 @@ Console.WriteLine($"The location of System.Private.CoreLib.dll is '{typeof(objec
|
|||
The following command will build and publish your app:
|
||||
|
||||
```cmd
|
||||
dotnet publish -r win-x64
|
||||
dotnet publish --self-contained
|
||||
```
|
||||
|
||||
Adjust the `win-x64` to match your machine's OS and architecture.
|
||||
|
||||
Running this little app should yield an output like the following:
|
||||
|
||||
```text
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<MonoAOTCrossCompilerSupported Condition="'$(_MonoAotCrossSupportedOS)' == 'true' and '$(_MonoAotCrossSupportedArch)' == 'true'">true</MonoAOTCrossCompilerSupported>
|
||||
|
||||
<!-- Determine if the NativeAOT runtime can run on the specified target. -->
|
||||
<_NativeAotSupportedOS Condition="'$(TargetOS)' == 'windows' or '$(TargetOS)' == 'linux' or '$(TargetOS)' == 'osx' or '$(TargetOS)' == 'maccatalyst' or '$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvossimulator' or '$(TargetOS)' == 'tvos' or '$(TargetOS)' == 'freebsd'">true</_NativeAotSupportedOS>
|
||||
<_NativeAotSupportedOS Condition="'$(TargetOS)' != 'browser' and '$(TargetOS)' != 'haiku' and '$(TargetOS)' != 'illumos' and '$(TargetOS)' != 'netbsd' and '$(TargetOS)' != 'solaris'">true</_NativeAotSupportedOS>
|
||||
<_NativeAotSupportedArch Condition="'$(TargetArchitecture)' == 'x64' or '$(TargetArchitecture)' == 'arm64' or '$(TargetArchitecture)' == 'arm' or '$(TargetArchitecture)' == 'loongarch64' or '$(TargetArchitecture)' == 'riscv64' or ('$(TargetOS)' == 'windows' and '$(TargetArchitecture)' == 'x86')">true</_NativeAotSupportedArch>
|
||||
<NativeAotSupported Condition="'$(_NativeAotSupportedOS)' == 'true' and '$(_NativeAotSupportedArch)' == 'true'">true</NativeAotSupported>
|
||||
|
||||
|
@ -71,6 +71,7 @@
|
|||
<DefaultSubsets>clr+mono+libs+tools+host+packs</DefaultSubsets>
|
||||
<DefaultSubsets Condition="'$(TargetsMobile)' == 'true'">mono+libs+packs</DefaultSubsets>
|
||||
<DefaultSubsets Condition="'$(TargetsAndroid)' == 'true' and '$(CoreCLRSupported)' == 'true'">clr+mono+libs+host+packs</DefaultSubsets>
|
||||
<DefaultSubsets Condition="'$(TargetsAndroid)' == 'true' and '$(CoreCLRSupported)' != 'true' and '$(NativeAotSupported)' == 'true'">clr.nativeaotruntime+clr.nativeaotlibs+mono+libs+packs</DefaultSubsets>
|
||||
<DefaultSubsets Condition="'$(TargetsAppleMobile)' == 'true'">clr.nativeaotruntime+clr.nativeaotlibs+mono+libs+packs</DefaultSubsets>
|
||||
<DefaultSubsets Condition="'$(TargetsLinuxBionic)' == 'true' and '$(MonoSupported)' == 'true'">clr.nativeaotruntime+clr.nativeaotlibs+mono+libs+host+packs</DefaultSubsets>
|
||||
<DefaultSubsets Condition="'$(TargetsLinuxBionic)' == 'true' and '$(MonoSupported)' != 'true'">clr.nativeaotruntime+clr.nativeaotlibs+libs+packs</DefaultSubsets>
|
||||
|
@ -153,7 +154,7 @@
|
|||
<BootstrapSubsets Condition="'$(UseNativeAotForComponents)' == 'true'">$(BootstrapSubsets)+clr.nativeaotlibs+clr.nativeaotruntime+libs.native</BootstrapSubsets>
|
||||
|
||||
<SwapNativeForIL Condition="$(_subset.Contains('+bootstrap+')) and '$(RuntimeFlavor)' == 'CoreCLR'">true</SwapNativeForIL>
|
||||
|
||||
|
||||
<!-- Define AllSubsets to include all available subsets including OnDemand ones -->
|
||||
<AllSubsetsExpansion>clr.nativeprereqs+clr.iltools+clr.runtime+clr.native+clr.aot+clr.nativeaotlibs+clr.nativeaotruntime+clr.crossarchtools</AllSubsetsExpansion>
|
||||
<AllSubsetsExpansion>$(AllSubsetsExpansion)+clr.paltests+clr.paltestlist+clr.hosts+clr.jit+clr.alljits+clr.alljitscommunity+clr.spmi+clr.corelib+clr.nativecorelib+clr.tools+clr.toolstests+clr.packages</AllSubsetsExpansion>
|
||||
|
@ -656,6 +657,8 @@
|
|||
<_BuildMonoRuntimePack Condition="'$(RuntimeFlavor)' == 'Mono' and '$(MonoSupported)' == 'true'">true</_BuildMonoRuntimePack>
|
||||
<_BuildHostPack Condition="'$(RuntimeFlavor)' == '$(PrimaryRuntimeFlavor)' and '$(TargetsMobile)' != 'true'">true</_BuildHostPack>
|
||||
<_BuildCdacPack Condition="'$(_CDacToolsBuilt)' == 'true' and '$(RuntimeFlavor)' == 'CoreCLR' and '$(TargetsMobile)' != 'true' and ('$(TargetOS)' == 'windows' or '$(TargetOS)' == 'osx' or '$(TargetOS)' == 'linux')">true</_BuildCdacPack>
|
||||
<!-- Some source build configurations and musl need to work out packaging errors before they can be enabled -->
|
||||
<_BuildCdacPack Condition="'$(DotNetBuildSourceOnly)' == 'true' or '$(TargetsLinuxMusl)' == 'true'">false</_BuildCdacPack>
|
||||
<_BuildBundle Condition="'$(RuntimeFlavor)' == '$(PrimaryRuntimeFlavor)' and '$(TargetsMobile)' != 'true'">true</_BuildBundle>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<!-- will get filled in the next backflow -->
|
|
@ -1,5 +1,5 @@
|
|||
<Dependencies>
|
||||
<Source Uri="https://github.com/dotnet/dotnet" Mapping="runtime" Sha="f451e5d3036a4f140a989e0a7f3f1ae432420e71" BarId="274568" />
|
||||
<Source Uri="https://github.com/dotnet/dotnet" Mapping="runtime" Sha="699b0116eb3df66c4dd7698af4f1cd24ac4547a3" BarId="275638" />
|
||||
<ProductDependencies>
|
||||
<Dependency Name="Microsoft.NETCore.Runtime.ICU.Transport" Version="10.0.0-preview.6.25302.1">
|
||||
<Uri>https://github.com/dotnet/icu</Uri>
|
||||
|
@ -41,91 +41,91 @@
|
|||
<Uri>https://github.com/dotnet/llvm-project</Uri>
|
||||
<Sha>da5dd054a531e6fea65643b7e754285b73eab433</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.CommandLine" Version="2.0.0-beta6.25359.101">
|
||||
<Dependency Name="System.CommandLine" Version="2.0.0-beta7.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.Cecil" Version="0.11.5-alpha.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.Cecil" Version="0.11.5-alpha.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.NET.Workload.Emscripten.Current.Manifest-10.0.100.Transport" Version="10.0.100-preview.7.25359.101">
|
||||
<Dependency Name="Microsoft.NET.Workload.Emscripten.Current.Manifest-10.0.100.Transport" Version="10.0.100-preview.7.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
</ProductDependencies>
|
||||
<ToolsetDependencies>
|
||||
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.XliffTasks" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.XliffTasks" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.Helix.Sdk" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.GenAPI" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.GenAPI" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.GenFacades" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.GenFacades" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.XUnitAssert" Version="2.9.2-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.XUnitAssert" Version="2.9.3-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.XUnitExtensions" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.XUnitExtensions" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.XUnitConsoleRunner" Version="2.9.2-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.XUnitConsoleRunner" Version="2.9.3-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Archives" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Archives" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Packaging" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Packaging" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Installers" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Installers" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Templating" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Workloads" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Workloads" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.CodeAnalysis" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.CodeAnalysis" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.TargetFramework" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.TargetFramework" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.RemoteExecutor" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.RemoteExecutor" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Feed" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.Build.Tasks.Feed" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.SharedFramework.Sdk" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.SharedFramework.Sdk" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.ComponentModel.TypeConverter.TestData" Version="10.0.0-beta.25310.1">
|
||||
<Uri>https://github.com/dotnet/runtime-assets</Uri>
|
||||
|
@ -263,33 +263,33 @@
|
|||
<Uri>https://github.com/dotnet/llvm-project</Uri>
|
||||
<Sha>da5dd054a531e6fea65643b7e754285b73eab433</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.NETCore.App.Ref" Version="10.0.0-preview.7.25359.101">
|
||||
<Dependency Name="Microsoft.NETCore.App.Ref" Version="10.0.0-preview.7.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="runtime.native.System.IO.Ports" Version="10.0.0-preview.7.25359.101">
|
||||
<Dependency Name="runtime.native.System.IO.Ports" Version="10.0.0-preview.7.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.NETCore.ILAsm" Version="10.0.0-preview.7.25359.101">
|
||||
<Dependency Name="Microsoft.NETCore.ILAsm" Version="10.0.0-preview.7.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.NET.Sdk.IL" Version="10.0.0-preview.7.25359.101">
|
||||
<Dependency Name="Microsoft.NET.Sdk.IL" Version="10.0.0-preview.7.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Text.Json" Version="10.0.0-preview.7.25359.101">
|
||||
<Dependency Name="System.Text.Json" Version="10.0.0-preview.7.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Reflection.Metadata" Version="10.0.0-preview.7.25359.101">
|
||||
<Dependency Name="System.Reflection.Metadata" Version="10.0.0-preview.7.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="System.Reflection.MetadataLoadContext" Version="10.0.0-preview.7.25359.101">
|
||||
<Dependency Name="System.Reflection.MetadataLoadContext" Version="10.0.0-preview.7.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.XHarness.TestRunners.Common" Version="10.0.0-prerelease.25330.2">
|
||||
<Uri>https://github.com/dotnet/xharness</Uri>
|
||||
|
@ -303,25 +303,25 @@
|
|||
<Uri>https://github.com/dotnet/xharness</Uri>
|
||||
<Sha>feac80219b22c403d32df9b6bd61cbf78e1b9986</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.PackageTesting" Version="10.0.0-beta.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.PackageTesting" Version="10.0.0-beta.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="optimization.windows_nt-x64.MIBC.Runtime" Version="1.0.0-prerelease.25324.1">
|
||||
<Dependency Name="optimization.windows_nt-x64.MIBC.Runtime" Version="1.0.0-prerelease.25363.1">
|
||||
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
|
||||
<Sha>86968b14b5c2ba5104d205665c76c22544c067f6</Sha>
|
||||
<Sha>54bab2dbb7652269d9ae0758de122f933b254561</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="optimization.windows_nt-x86.MIBC.Runtime" Version="1.0.0-prerelease.25324.1">
|
||||
<Dependency Name="optimization.windows_nt-x86.MIBC.Runtime" Version="1.0.0-prerelease.25363.1">
|
||||
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
|
||||
<Sha>86968b14b5c2ba5104d205665c76c22544c067f6</Sha>
|
||||
<Sha>54bab2dbb7652269d9ae0758de122f933b254561</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="optimization.linux-x64.MIBC.Runtime" Version="1.0.0-prerelease.25324.1">
|
||||
<Dependency Name="optimization.linux-x64.MIBC.Runtime" Version="1.0.0-prerelease.25363.1">
|
||||
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
|
||||
<Sha>86968b14b5c2ba5104d205665c76c22544c067f6</Sha>
|
||||
<Sha>54bab2dbb7652269d9ae0758de122f933b254561</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="optimization.PGO.CoreCLR" Version="1.0.0-prerelease.25324.1">
|
||||
<Dependency Name="optimization.PGO.CoreCLR" Version="1.0.0-prerelease.25363.1">
|
||||
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
|
||||
<Sha>86968b14b5c2ba5104d205665c76c22544c067f6</Sha>
|
||||
<Sha>54bab2dbb7652269d9ae0758de122f933b254561</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.HotReload.Utils.Generator.BuildTool" Version="10.0.0-alpha.0.25302.2">
|
||||
<Uri>https://github.com/dotnet/hotreload-utils</Uri>
|
||||
|
@ -331,37 +331,37 @@
|
|||
<Uri>https://github.com/dotnet/runtime-assets</Uri>
|
||||
<Sha>385d085eb055cabeaed3dde958a900e7b31cf6ce</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="5.0.0-1.25359.101">
|
||||
<Dependency Name="Microsoft.Net.Compilers.Toolset" Version="5.0.0-2.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis" Version="5.0.0-1.25359.101">
|
||||
<Dependency Name="Microsoft.CodeAnalysis" Version="5.0.0-2.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.CSharp" Version="5.0.0-1.25359.101">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.CSharp" Version="5.0.0-2.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.Analyzers" Version="5.0.0-1.25359.101">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.Analyzers" Version="5.0.0-2.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.0-preview.25359.101">
|
||||
<Dependency Name="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.0-preview.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.DotNet.ApiCompat.Task" Version="10.0.100-preview.7.25359.101">
|
||||
<Dependency Name="Microsoft.DotNet.ApiCompat.Task" Version="10.0.100-preview.7.25367.101">
|
||||
<Uri>https://github.com/dotnet/dotnet</Uri>
|
||||
<Sha>f451e5d3036a4f140a989e0a7f3f1ae432420e71</Sha>
|
||||
<Sha>699b0116eb3df66c4dd7698af4f1cd24ac4547a3</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="optimization.windows_nt-arm64.MIBC.Runtime" Version="1.0.0-prerelease.25324.1">
|
||||
<Dependency Name="optimization.windows_nt-arm64.MIBC.Runtime" Version="1.0.0-prerelease.25363.1">
|
||||
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
|
||||
<Sha>86968b14b5c2ba5104d205665c76c22544c067f6</Sha>
|
||||
<Sha>54bab2dbb7652269d9ae0758de122f933b254561</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="optimization.linux-arm64.MIBC.Runtime" Version="1.0.0-prerelease.25324.1">
|
||||
<Dependency Name="optimization.linux-arm64.MIBC.Runtime" Version="1.0.0-prerelease.25363.1">
|
||||
<Uri>https://dev.azure.com/dnceng/internal/_git/dotnet-optimization</Uri>
|
||||
<Sha>86968b14b5c2ba5104d205665c76c22544c067f6</Sha>
|
||||
<Sha>54bab2dbb7652269d9ae0758de122f933b254561</Sha>
|
||||
</Dependency>
|
||||
<!-- Necessary for source-build. This allows the package to be retrieved from previously-source-built artifacts
|
||||
and flow in as dependencies of the packages produced by runtime. -->
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
<PackageVersionNet8>8.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet9)').Build),11))</PackageVersionNet8>
|
||||
<PackageVersionNet7>7.0.20</PackageVersionNet7>
|
||||
<PackageVersionNet6>6.0.36</PackageVersionNet6>
|
||||
<PreReleaseVersionLabel>preview</PreReleaseVersionLabel>
|
||||
<PreReleaseVersionIteration>7</PreReleaseVersionIteration>
|
||||
<PreReleaseVersionLabel>rc</PreReleaseVersionLabel>
|
||||
<PreReleaseVersionIteration>1</PreReleaseVersionIteration>
|
||||
<!-- Enable to remove prerelease label. -->
|
||||
<StabilizePackageVersion Condition="'$(StabilizePackageVersion)' == ''">false</StabilizePackageVersion>
|
||||
<DotNetFinalVersionKind Condition="'$(StabilizePackageVersion)' == 'true'">release</DotNetFinalVersionKind>
|
||||
|
@ -28,25 +28,24 @@
|
|||
<FlagNetStandard1XDependencies Condition="'$(FlagNetStandard1XDependencies)' == ''">true</FlagNetStandard1XDependencies>
|
||||
<!-- Runtime controls its dependency graph via Traversal projects and doesn't want or need Arcade's ExcludeFrom infrastructure. -->
|
||||
<DisableArcadeExcludeFromBuildSupport>true</DisableArcadeExcludeFromBuildSupport>
|
||||
<!-- Use SDK compilers in full VMR builds. -->
|
||||
<UsingToolMicrosoftNetCompilers Condition="'$(DotNetBuildOrchestrator)' != 'true'">true</UsingToolMicrosoftNetCompilers>
|
||||
<UsingToolMicrosoftNetCompilers>true</UsingToolMicrosoftNetCompilers>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<WorkloadSdkBandVersions Include="$(SdkBandVersion)" SupportsMachineArch="true" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<!-- dotnet/roslyn-analyzers dependencies -->
|
||||
<MicrosoftCodeAnalysisNetAnalyzersVersion>10.0.0-preview.25359.101</MicrosoftCodeAnalysisNetAnalyzersVersion>
|
||||
<MicrosoftCodeAnalysisNetAnalyzersVersion>10.0.0-preview.25367.101</MicrosoftCodeAnalysisNetAnalyzersVersion>
|
||||
<!-- dotnet/roslyn dependencies -->
|
||||
<MicrosoftCodeAnalysisAnalyzersVersion>5.0.0-1.25359.101</MicrosoftCodeAnalysisAnalyzersVersion>
|
||||
<MicrosoftCodeAnalysisAnalyzersVersion>5.0.0-2.25367.101</MicrosoftCodeAnalysisAnalyzersVersion>
|
||||
<!--
|
||||
These versions should not be used by any project that contributes to the design-time experience in VS, such as an analyzer, code-fix, or generator assembly.
|
||||
Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure
|
||||
they do not break the local dev experience.
|
||||
-->
|
||||
<MicrosoftCodeAnalysisCSharpVersion>5.0.0-1.25359.101</MicrosoftCodeAnalysisCSharpVersion>
|
||||
<MicrosoftCodeAnalysisVersion>5.0.0-1.25359.101</MicrosoftCodeAnalysisVersion>
|
||||
<MicrosoftNetCompilersToolsetVersion>5.0.0-1.25359.101</MicrosoftNetCompilersToolsetVersion>
|
||||
<MicrosoftCodeAnalysisCSharpVersion>5.0.0-2.25367.101</MicrosoftCodeAnalysisCSharpVersion>
|
||||
<MicrosoftCodeAnalysisVersion>5.0.0-2.25367.101</MicrosoftCodeAnalysisVersion>
|
||||
<MicrosoftNetCompilersToolsetVersion>5.0.0-2.25367.101</MicrosoftNetCompilersToolsetVersion>
|
||||
</PropertyGroup>
|
||||
<!--
|
||||
For source generator support we need to target multiple versions of Roslyn in order to be able to run on older versions of Roslyn.
|
||||
|
@ -83,34 +82,34 @@
|
|||
<PropertyGroup>
|
||||
<StaticCsVersion>0.2.0</StaticCsVersion>
|
||||
<!-- SDK dependencies (also used in wasm build tests -->
|
||||
<MicrosoftDotNetApiCompatTaskVersion>10.0.100-preview.7.25359.101</MicrosoftDotNetApiCompatTaskVersion>
|
||||
<MicrosoftDotNetApiCompatTaskVersion>10.0.100-preview.7.25367.101</MicrosoftDotNetApiCompatTaskVersion>
|
||||
<!-- Arcade dependencies -->
|
||||
<MicrosoftDotNetBuildTasksFeedVersion>10.0.0-beta.25359.101</MicrosoftDotNetBuildTasksFeedVersion>
|
||||
<MicrosoftDotNetCodeAnalysisVersion>10.0.0-beta.25359.101</MicrosoftDotNetCodeAnalysisVersion>
|
||||
<MicrosoftDotNetGenAPIVersion>10.0.0-beta.25359.101</MicrosoftDotNetGenAPIVersion>
|
||||
<MicrosoftDotNetGenFacadesVersion>10.0.0-beta.25359.101</MicrosoftDotNetGenFacadesVersion>
|
||||
<MicrosoftDotNetXUnitAssertVersion>2.9.2-beta.25359.101</MicrosoftDotNetXUnitAssertVersion>
|
||||
<MicrosoftDotNetXUnitExtensionsVersion>10.0.0-beta.25359.101</MicrosoftDotNetXUnitExtensionsVersion>
|
||||
<MicrosoftDotNetXUnitConsoleRunnerVersion>2.9.2-beta.25359.101</MicrosoftDotNetXUnitConsoleRunnerVersion>
|
||||
<MicrosoftDotNetBuildTasksArchivesVersion>10.0.0-beta.25359.101</MicrosoftDotNetBuildTasksArchivesVersion>
|
||||
<MicrosoftDotNetBuildTasksInstallersVersion>10.0.0-beta.25359.101</MicrosoftDotNetBuildTasksInstallersVersion>
|
||||
<MicrosoftDotNetBuildTasksPackagingVersion>10.0.0-beta.25359.101</MicrosoftDotNetBuildTasksPackagingVersion>
|
||||
<MicrosoftDotNetBuildTasksTargetFrameworkVersion>10.0.0-beta.25359.101</MicrosoftDotNetBuildTasksTargetFrameworkVersion>
|
||||
<MicrosoftDotNetBuildTasksTemplatingVersion>10.0.0-beta.25359.101</MicrosoftDotNetBuildTasksTemplatingVersion>
|
||||
<MicrosoftDotNetBuildTasksWorkloadsPackageVersion>10.0.0-beta.25359.101</MicrosoftDotNetBuildTasksWorkloadsPackageVersion>
|
||||
<MicrosoftDotNetRemoteExecutorVersion>10.0.0-beta.25359.101</MicrosoftDotNetRemoteExecutorVersion>
|
||||
<MicrosoftDotNetPackageTestingVersion>10.0.0-beta.25359.101</MicrosoftDotNetPackageTestingVersion>
|
||||
<MicrosoftDotNetXliffTasksVersion>10.0.0-beta.25359.101</MicrosoftDotNetXliffTasksVersion>
|
||||
<MicrosoftDotNetBuildTasksFeedVersion>10.0.0-beta.25367.101</MicrosoftDotNetBuildTasksFeedVersion>
|
||||
<MicrosoftDotNetCodeAnalysisVersion>10.0.0-beta.25367.101</MicrosoftDotNetCodeAnalysisVersion>
|
||||
<MicrosoftDotNetGenAPIVersion>10.0.0-beta.25367.101</MicrosoftDotNetGenAPIVersion>
|
||||
<MicrosoftDotNetGenFacadesVersion>10.0.0-beta.25367.101</MicrosoftDotNetGenFacadesVersion>
|
||||
<MicrosoftDotNetXUnitAssertVersion>2.9.3-beta.25367.101</MicrosoftDotNetXUnitAssertVersion>
|
||||
<MicrosoftDotNetXUnitExtensionsVersion>10.0.0-beta.25367.101</MicrosoftDotNetXUnitExtensionsVersion>
|
||||
<MicrosoftDotNetXUnitConsoleRunnerVersion>2.9.3-beta.25367.101</MicrosoftDotNetXUnitConsoleRunnerVersion>
|
||||
<MicrosoftDotNetBuildTasksArchivesVersion>10.0.0-beta.25367.101</MicrosoftDotNetBuildTasksArchivesVersion>
|
||||
<MicrosoftDotNetBuildTasksInstallersVersion>10.0.0-beta.25367.101</MicrosoftDotNetBuildTasksInstallersVersion>
|
||||
<MicrosoftDotNetBuildTasksPackagingVersion>10.0.0-beta.25367.101</MicrosoftDotNetBuildTasksPackagingVersion>
|
||||
<MicrosoftDotNetBuildTasksTargetFrameworkVersion>10.0.0-beta.25367.101</MicrosoftDotNetBuildTasksTargetFrameworkVersion>
|
||||
<MicrosoftDotNetBuildTasksTemplatingVersion>10.0.0-beta.25367.101</MicrosoftDotNetBuildTasksTemplatingVersion>
|
||||
<MicrosoftDotNetBuildTasksWorkloadsPackageVersion>10.0.0-beta.25367.101</MicrosoftDotNetBuildTasksWorkloadsPackageVersion>
|
||||
<MicrosoftDotNetRemoteExecutorVersion>10.0.0-beta.25367.101</MicrosoftDotNetRemoteExecutorVersion>
|
||||
<MicrosoftDotNetPackageTestingVersion>10.0.0-beta.25367.101</MicrosoftDotNetPackageTestingVersion>
|
||||
<MicrosoftDotNetXliffTasksVersion>10.0.0-beta.25367.101</MicrosoftDotNetXliffTasksVersion>
|
||||
<!-- TODO: Remove pinned xunit.analyzers version: https://github.com/dotnet/runtime/issues/97088 -->
|
||||
<XUnitAnalyzersVersion>1.4.0</XUnitAnalyzersVersion>
|
||||
<!-- NuGet dependencies -->
|
||||
<NuGetBuildTasksPackVersion>6.0.0-preview.1.102</NuGetBuildTasksPackVersion>
|
||||
<!-- Installer dependencies -->
|
||||
<MicrosoftNETCoreAppRefVersion>10.0.0-preview.7.25359.101</MicrosoftNETCoreAppRefVersion>
|
||||
<MicrosoftNETCoreAppRefVersion>10.0.0-preview.7.25367.101</MicrosoftNETCoreAppRefVersion>
|
||||
<MicrosoftExtensionsDependencyModelVersion>6.0.0</MicrosoftExtensionsDependencyModelVersion>
|
||||
<!-- ILAsm dependencies -->
|
||||
<MicrosoftNETCoreILAsmVersion>10.0.0-preview.7.25359.101</MicrosoftNETCoreILAsmVersion>
|
||||
<MicrosoftNETSdkILVersion>10.0.0-preview.7.25359.101</MicrosoftNETSdkILVersion>
|
||||
<MicrosoftNETCoreILAsmVersion>10.0.0-preview.7.25367.101</MicrosoftNETCoreILAsmVersion>
|
||||
<MicrosoftNETSdkILVersion>10.0.0-preview.7.25367.101</MicrosoftNETSdkILVersion>
|
||||
<!-- Maintenance-Packages dependencies -->
|
||||
<MicrosoftBclHashCodeVersion>6.0.0</MicrosoftBclHashCodeVersion>
|
||||
<SystemBuffersVersion>4.6.1</SystemBuffersVersion>
|
||||
|
@ -128,16 +127,16 @@
|
|||
<SystemDrawingCommonVersion>8.0.0</SystemDrawingCommonVersion>
|
||||
<SystemFormatsAsn1Version>8.0.1</SystemFormatsAsn1Version>
|
||||
<SystemIOFileSystemAccessControlVersion>5.0.0</SystemIOFileSystemAccessControlVersion>
|
||||
<SystemReflectionMetadataVersion>10.0.0-preview.7.25359.101</SystemReflectionMetadataVersion>
|
||||
<SystemReflectionMetadataLoadContextVersion>10.0.0-preview.7.25359.101</SystemReflectionMetadataLoadContextVersion>
|
||||
<SystemReflectionMetadataVersion>10.0.0-preview.7.25367.101</SystemReflectionMetadataVersion>
|
||||
<SystemReflectionMetadataLoadContextVersion>10.0.0-preview.7.25367.101</SystemReflectionMetadataLoadContextVersion>
|
||||
<SystemSecurityAccessControlVersion>6.0.0</SystemSecurityAccessControlVersion>
|
||||
<SystemSecurityCryptographyCngVersion>5.0.0</SystemSecurityCryptographyCngVersion>
|
||||
<SystemSecurityCryptographyOpenSslVersion>5.0.0</SystemSecurityCryptographyOpenSslVersion>
|
||||
<SystemSecurityPrincipalWindowsVersion>5.0.0</SystemSecurityPrincipalWindowsVersion>
|
||||
<SystemSecurityPermissionsVersion>7.0.0</SystemSecurityPermissionsVersion>
|
||||
<SystemTextJsonVersion>10.0.0-preview.7.25359.101</SystemTextJsonVersion>
|
||||
<SystemTextJsonVersion>10.0.0-preview.7.25367.101</SystemTextJsonVersion>
|
||||
<SystemThreadingAccessControlVersion>7.0.0</SystemThreadingAccessControlVersion>
|
||||
<runtimenativeSystemIOPortsVersion>10.0.0-preview.7.25359.101</runtimenativeSystemIOPortsVersion>
|
||||
<runtimenativeSystemIOPortsVersion>10.0.0-preview.7.25367.101</runtimenativeSystemIOPortsVersion>
|
||||
<!-- Keep toolset versions in sync with dotnet/msbuild and dotnet/sdk -->
|
||||
<MicrosoftBclAsyncInterfacesToolsetVersion>8.0.0</MicrosoftBclAsyncInterfacesToolsetVersion>
|
||||
<SystemBuffersToolsetVersion>4.5.1</SystemBuffersToolsetVersion>
|
||||
|
@ -171,16 +170,16 @@
|
|||
<!-- hotreload-utils dependencies -->
|
||||
<MicrosoftDotNetHotReloadUtilsGeneratorBuildToolVersion>10.0.0-alpha.0.25302.2</MicrosoftDotNetHotReloadUtilsGeneratorBuildToolVersion>
|
||||
<!-- dotnet-optimization dependencies -->
|
||||
<optimizationwindows_ntx64MIBCRuntimeVersion>1.0.0-prerelease.25324.1</optimizationwindows_ntx64MIBCRuntimeVersion>
|
||||
<optimizationwindows_ntx86MIBCRuntimeVersion>1.0.0-prerelease.25324.1</optimizationwindows_ntx86MIBCRuntimeVersion>
|
||||
<optimizationwindows_ntarm64MIBCRuntimeVersion>1.0.0-prerelease.25324.1</optimizationwindows_ntarm64MIBCRuntimeVersion>
|
||||
<optimizationlinuxx64MIBCRuntimeVersion>1.0.0-prerelease.25324.1</optimizationlinuxx64MIBCRuntimeVersion>
|
||||
<optimizationlinuxarm64MIBCRuntimeVersion>1.0.0-prerelease.25324.1</optimizationlinuxarm64MIBCRuntimeVersion>
|
||||
<optimizationPGOCoreCLRVersion>1.0.0-prerelease.25324.1</optimizationPGOCoreCLRVersion>
|
||||
<optimizationwindows_ntx64MIBCRuntimeVersion>1.0.0-prerelease.25363.1</optimizationwindows_ntx64MIBCRuntimeVersion>
|
||||
<optimizationwindows_ntx86MIBCRuntimeVersion>1.0.0-prerelease.25363.1</optimizationwindows_ntx86MIBCRuntimeVersion>
|
||||
<optimizationwindows_ntarm64MIBCRuntimeVersion>1.0.0-prerelease.25363.1</optimizationwindows_ntarm64MIBCRuntimeVersion>
|
||||
<optimizationlinuxx64MIBCRuntimeVersion>1.0.0-prerelease.25363.1</optimizationlinuxx64MIBCRuntimeVersion>
|
||||
<optimizationlinuxarm64MIBCRuntimeVersion>1.0.0-prerelease.25363.1</optimizationlinuxarm64MIBCRuntimeVersion>
|
||||
<optimizationPGOCoreCLRVersion>1.0.0-prerelease.25363.1</optimizationPGOCoreCLRVersion>
|
||||
<!-- Not auto-updated. -->
|
||||
<MicrosoftDiaSymReaderVersion>2.0.0</MicrosoftDiaSymReaderVersion>
|
||||
<MicrosoftDiaSymReaderNativeVersion>17.10.0-beta1.24272.1</MicrosoftDiaSymReaderNativeVersion>
|
||||
<SystemCommandLineVersion>2.0.0-beta6.25359.101</SystemCommandLineVersion>
|
||||
<SystemCommandLineVersion>2.0.0-beta7.25367.101</SystemCommandLineVersion>
|
||||
<TraceEventVersion>3.1.16</TraceEventVersion>
|
||||
<NETStandardLibraryRefVersion>2.1.0</NETStandardLibraryRefVersion>
|
||||
<NetStandardLibraryVersion>2.0.3</NetStandardLibraryVersion>
|
||||
|
@ -226,7 +225,7 @@
|
|||
<!-- Docs -->
|
||||
<MicrosoftPrivateIntellisenseVersion>9.0.0-preview-20241010.1</MicrosoftPrivateIntellisenseVersion>
|
||||
<!-- Mono Cecil -->
|
||||
<MicrosoftDotNetCecilVersion>0.11.5-alpha.25359.101</MicrosoftDotNetCecilVersion>
|
||||
<MicrosoftDotNetCecilVersion>0.11.5-alpha.25367.101</MicrosoftDotNetCecilVersion>
|
||||
<!-- ICU -->
|
||||
<MicrosoftNETCoreRuntimeICUTransportVersion>10.0.0-preview.6.25302.1</MicrosoftNETCoreRuntimeICUTransportVersion>
|
||||
<!-- MsQuic -->
|
||||
|
@ -258,7 +257,7 @@
|
|||
Note: when the name is updated, make sure to update dependency name in eng/pipelines/common/xplat-setup.yml
|
||||
like - DarcDependenciesChanged.Microsoft_NET_Workload_Emscripten_Current_Manifest-10_0_100_Transport
|
||||
-->
|
||||
<MicrosoftNETWorkloadEmscriptenCurrentManifest100100TransportVersion>10.0.100-preview.7.25359.101</MicrosoftNETWorkloadEmscriptenCurrentManifest100100TransportVersion>
|
||||
<MicrosoftNETWorkloadEmscriptenCurrentManifest100100TransportVersion>10.0.100-preview.7.25367.101</MicrosoftNETWorkloadEmscriptenCurrentManifest100100TransportVersion>
|
||||
<MicrosoftNETRuntimeEmscriptenVersion>$(MicrosoftNETWorkloadEmscriptenCurrentManifest100100TransportVersion)</MicrosoftNETRuntimeEmscriptenVersion>
|
||||
<!-- workloads -->
|
||||
<SwixPackageVersion>1.1.87-gba258badda</SwixPackageVersion>
|
||||
|
|
|
@ -150,7 +150,7 @@ initDistroRid()
|
|||
|
||||
showSubsetHelp()
|
||||
{
|
||||
"$scriptroot/common/build.sh" "-restore" "-build" "/p:Subset=help" "/clp:nosummary /tl:false"
|
||||
"$scriptroot/common/build.sh" "-restore" "-build" "/p:Subset=help" "/clp:nosummary" "/tl:false"
|
||||
}
|
||||
|
||||
arguments=()
|
||||
|
|
|
@ -70,7 +70,7 @@ build_native()
|
|||
# Let users provide additional compiler/linker flags via EXTRA_CFLAGS/EXTRA_CXXFLAGS/EXTRA_LDFLAGS.
|
||||
# If users directly override CFLAG/CXXFLAGS/LDFLAGS, that may lead to some configure tests working incorrectly.
|
||||
# See https://github.com/dotnet/runtime/issues/35727 for more information.
|
||||
#
|
||||
#
|
||||
# These flags MUST be exported before gen-buildsys.sh runs or cmake will ignore them
|
||||
#
|
||||
export CFLAGS="${CFLAGS} ${EXTRA_CFLAGS}"
|
||||
|
@ -547,6 +547,9 @@ elif [[ "$__TargetOS" == ios || "$__TargetOS" == iossimulator ]]; then
|
|||
elif [[ "$__TargetOS" == tvos || "$__TargetOS" == tvossimulator ]]; then
|
||||
# nothing to do here
|
||||
true
|
||||
elif [[ "$__TargetOS" == osx || "$__TargetOS" == maccatalyst ]]; then
|
||||
# nothing to do here
|
||||
true
|
||||
elif [[ "$__TargetOS" == android ]]; then
|
||||
# nothing to do here
|
||||
true
|
||||
|
|
|
@ -308,6 +308,8 @@ elseif(CLR_CMAKE_HOST_APPLE)
|
|||
add_definitions(-D_XOPEN_SOURCE)
|
||||
# enable support for Darwin extension APIs, like pthread_getthreadid_np
|
||||
add_definitions(-D_DARWIN_C_SOURCE)
|
||||
# enable the non-cancellable versions of APIs with $NOCANCEL variants, like close(2)
|
||||
add_definitions(-D__DARWIN_NON_CANCELABLE=1)
|
||||
|
||||
if(CLR_CMAKE_HOST_OSX)
|
||||
# the new linker in Xcode 15 (ld_new/ld_prime) deprecated the -bind_at_load flag for macOS which causes a warning
|
||||
|
|
|
@ -548,11 +548,11 @@ function(install_static_library targetName destination component)
|
|||
endif()
|
||||
endfunction()
|
||||
|
||||
# install_clr(TARGETS targetName [targetName2 ...] [DESTINATIONS destination [destination2 ...]] [COMPONENT componentName])
|
||||
# install_clr(TARGETS targetName [targetName2 ...] [DESTINATIONS destination [destination2 ...]] [COMPONENT componentName] [OPTIONAL])
|
||||
function(install_clr)
|
||||
set(multiValueArgs TARGETS DESTINATIONS)
|
||||
set(singleValueArgs COMPONENT)
|
||||
set(options "")
|
||||
set(options OPTIONAL)
|
||||
cmake_parse_arguments(INSTALL_CLR "${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGV})
|
||||
|
||||
if ("${INSTALL_CLR_TARGETS}" STREQUAL "")
|
||||
|
@ -587,12 +587,18 @@ function(install_clr)
|
|||
get_symbol_file_name(${targetName} symbolFile)
|
||||
endif()
|
||||
|
||||
if (${INSTALL_CLR_OPTIONAL})
|
||||
set(INSTALL_CLR_OPTIONAL "OPTIONAL")
|
||||
else()
|
||||
set(INSTALL_CLR_OPTIONAL "")
|
||||
endif()
|
||||
|
||||
foreach(destination ${destinations})
|
||||
# We don't need to install the export libraries for our DLLs
|
||||
# since they won't be directly linked against.
|
||||
install(PROGRAMS $<TARGET_FILE:${targetName}> DESTINATION ${destination} COMPONENT ${INSTALL_CLR_COMPONENT})
|
||||
install(PROGRAMS $<TARGET_FILE:${targetName}> DESTINATION ${destination} COMPONENT ${INSTALL_CLR_COMPONENT} ${INSTALL_CLR_OPTIONAL})
|
||||
if (NOT "${symbolFile}" STREQUAL "")
|
||||
install_symbol_file(${symbolFile} ${destination} COMPONENT ${INSTALL_CLR_COMPONENT})
|
||||
install_symbol_file(${symbolFile} ${destination} COMPONENT ${INSTALL_CLR_COMPONENT} ${INSTALL_CLR_OPTIONAL})
|
||||
endif()
|
||||
|
||||
if(CLR_CMAKE_PGO_INSTRUMENT)
|
||||
|
|
|
@ -76,7 +76,7 @@ jobs:
|
|||
nameSuffix: AllSubsets_Mono
|
||||
isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }}
|
||||
buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:EnableAdditionalTimezoneChecks=true
|
||||
timeoutInMinutes: 480
|
||||
timeoutInMinutes: 240
|
||||
# extra steps, run tests
|
||||
postBuildSteps:
|
||||
- template: /eng/pipelines/libraries/helix.yml
|
||||
|
@ -107,7 +107,7 @@ jobs:
|
|||
nameSuffix: AllSubsets_CoreCLR
|
||||
isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }}
|
||||
buildArgs: -s clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg)
|
||||
timeoutInMinutes: 480
|
||||
timeoutInMinutes: 240
|
||||
# extra steps, run tests
|
||||
postBuildSteps:
|
||||
- template: /eng/pipelines/libraries/helix.yml
|
||||
|
|
|
@ -111,7 +111,7 @@ jobs:
|
|||
nameSuffix: AllSubsets_Mono
|
||||
isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }}
|
||||
buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg)
|
||||
timeoutInMinutes: 180
|
||||
timeoutInMinutes: 240
|
||||
# extra steps, run tests
|
||||
postBuildSteps:
|
||||
- template: /eng/pipelines/libraries/helix.yml
|
||||
|
|
|
@ -42,7 +42,7 @@ jobs:
|
|||
buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg) /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=false /p:IsManualOrRollingBuild=true /p:EnableAggressiveTrimming=false
|
||||
${{ else }}:
|
||||
buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg) /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=false /p:IsManualOrRollingBuild=true /p:EnableAggressiveTrimming=true
|
||||
timeoutInMinutes: 480
|
||||
timeoutInMinutes: 240
|
||||
# extra steps, run tests
|
||||
postBuildSteps:
|
||||
- template: /eng/pipelines/libraries/helix.yml
|
||||
|
@ -81,7 +81,7 @@ jobs:
|
|||
testGroup: innerloop
|
||||
nameSuffix: AllSubsets_Mono_RuntimeTests
|
||||
buildArgs: -s mono+libs -c $(_BuildConfig)
|
||||
timeoutInMinutes: 480
|
||||
timeoutInMinutes: 240
|
||||
# extra steps, run tests
|
||||
extraVariablesTemplates:
|
||||
- template: /eng/pipelines/common/templates/runtimes/test-variables.yml
|
||||
|
@ -152,7 +152,7 @@ jobs:
|
|||
jobParameters:
|
||||
testGroup: innerloop
|
||||
nameSuffix: AllSubsets_NativeAOT_RuntimeTests
|
||||
timeoutInMinutes: 480
|
||||
timeoutInMinutes: 240
|
||||
buildArgs: --cross -s clr.alljits+clr.tools+clr.nativeaotruntime+clr.nativeaotlibs+libs -c $(_BuildConfig)
|
||||
# extra steps, run tests
|
||||
extraVariablesTemplates:
|
||||
|
|
|
@ -36,7 +36,7 @@ jobs:
|
|||
testGroup: innerloop
|
||||
nameSuffix: AllSubsets_Mono
|
||||
buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:RunAOTCompilation=true /p:MonoForceInterpreter=true
|
||||
timeoutInMinutes: 180
|
||||
timeoutInMinutes: 240
|
||||
# extra steps, run tests
|
||||
postBuildSteps:
|
||||
- template: /eng/pipelines/libraries/helix.yml
|
||||
|
@ -119,7 +119,7 @@ jobs:
|
|||
jobParameters:
|
||||
testGroup: innerloop
|
||||
nameSuffix: AllSubsets_NativeAOT_RuntimeTests
|
||||
timeoutInMinutes: 240
|
||||
timeoutInMinutes: 180
|
||||
buildArgs: --cross -s clr.alljits+clr.tools+clr.nativeaotruntime+clr.nativeaotlibs+libs -c $(_BuildConfig)
|
||||
# extra steps, run tests
|
||||
extraVariablesTemplates:
|
||||
|
@ -133,3 +133,37 @@ jobs:
|
|||
testBuildArgs: tree nativeaot/SmokeTests /p:BuildNativeAOTRuntimePack=true
|
||||
testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig)
|
||||
buildAllTestsAsStandalone: true
|
||||
|
||||
#
|
||||
# iOS simulator
|
||||
# Build the whole product using CoreCLR and run functional tests
|
||||
#
|
||||
- template: /eng/pipelines/common/platform-matrix.yml
|
||||
parameters:
|
||||
jobTemplate: /eng/pipelines/common/global-build-job.yml
|
||||
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
|
||||
buildConfig: checked
|
||||
runtimeFlavor: coreclr
|
||||
isExtraPlatformsBuild: ${{ parameters.isExtraPlatformsBuild }}
|
||||
isiOSLikeSimulatorOnlyBuild: ${{ parameters.isiOSLikeSimulatorOnlyBuild }}
|
||||
platforms:
|
||||
- iossimulator_arm64
|
||||
variables:
|
||||
# map dependencies variables to local variables
|
||||
- name: librariesContainsChange
|
||||
value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'] ]
|
||||
- name: coreclrContainsChange
|
||||
value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'] ]
|
||||
- name: illinkContainsChange
|
||||
value: $[ stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_tools_illink.containsChange'] ]
|
||||
jobParameters:
|
||||
testGroup: innerloop
|
||||
nameSuffix: AllSubsets_CoreCLR
|
||||
buildArgs: -s clr+clr.runtime+libs+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=false /p:UseMonoRuntime=false /p:MonoForceInterpreter=false /p:RunSmokeTestsOnly=true
|
||||
timeoutInMinutes: 120
|
||||
# extra steps, run tests
|
||||
postBuildSteps:
|
||||
- template: /eng/pipelines/libraries/helix.yml
|
||||
parameters:
|
||||
creator: dotnet-bot
|
||||
testRunNamePrefixSuffix: CoreCLR_$(_BuildConfig)
|
||||
|
|
|
@ -42,7 +42,6 @@ jobs:
|
|||
# Linux x64
|
||||
- ${{ if eq(parameters.platform, 'linux_x64') }}:
|
||||
- AzureLinux.3.Amd64.Open
|
||||
- Ubuntu.2204.Amd64.Open
|
||||
|
||||
# OSX arm64
|
||||
- ${{ if eq(parameters.platform, 'osx_arm64') }}:
|
||||
|
|
|
@ -14,10 +14,6 @@ parameters:
|
|||
displayName: Build Coreclr Arm64 Windows
|
||||
type: boolean
|
||||
default: true
|
||||
- name: coreclr_muslx64_linux
|
||||
displayName: Build Coreclr Musl x64 Linux
|
||||
type: boolean
|
||||
default: true
|
||||
- name: coreclr_x64_linux
|
||||
displayName: Build Coreclr x64 Linux
|
||||
type: boolean
|
||||
|
@ -110,8 +106,6 @@ extends:
|
|||
- coreclr_arm64_linux
|
||||
- ${{ if eq(parameters.coreclr_arm64_windows, true) }}:
|
||||
- coreclr_arm64_windows
|
||||
- ${{ if eq(parameters.coreclr_muslx64_linux, true) }}:
|
||||
- coreclr_muslx64_linux
|
||||
- ${{ if eq(parameters.coreclr_x64_linux, true) }}:
|
||||
- coreclr_x64_linux
|
||||
- ${{ if eq(parameters.coreclr_x64_windows, true) }}:
|
||||
|
@ -152,8 +146,6 @@ extends:
|
|||
- coreclr_arm64_linux
|
||||
- ${{ if eq(parameters.coreclr_arm64_windows, true) }}:
|
||||
- coreclr_arm64_windows
|
||||
- ${{ if eq(parameters.coreclr_muslx64_linux, true) }}:
|
||||
- coreclr_muslx64_linux
|
||||
- ${{ if eq(parameters.coreclr_x64_linux, true) }}:
|
||||
- coreclr_x64_linux
|
||||
- ${{ if eq(parameters.coreclr_x64_windows, true) }}:
|
||||
|
@ -182,7 +174,7 @@ extends:
|
|||
- nativeAot_arm64_ios
|
||||
${{ if parameters.mauiFramework }}:
|
||||
mauiFramework: ${{ parameters.mauiFramework }}
|
||||
|
||||
|
||||
- ${{ if and(ne(variables['System.TeamProject'], 'public'), or(eq(variables['Build.Reason'], 'IndividualCI'), parameters.runPrivateJobs)) }}:
|
||||
- stage: UploadArtifacts
|
||||
displayName: 'Upload Artifacts'
|
||||
|
@ -200,8 +192,6 @@ extends:
|
|||
- coreclr_arm64_linux
|
||||
- ${{ if eq(parameters.coreclr_arm64_windows, true) }}:
|
||||
- coreclr_arm64_windows
|
||||
- ${{ if eq(parameters.coreclr_muslx64_linux, true) }}:
|
||||
- coreclr_muslx64_linux
|
||||
- ${{ if eq(parameters.coreclr_x64_linux, true) }}:
|
||||
- coreclr_x64_linux
|
||||
- ${{ if eq(parameters.coreclr_x64_windows, true) }}:
|
||||
|
|
|
@ -8,6 +8,7 @@ trigger:
|
|||
branches:
|
||||
include:
|
||||
- main
|
||||
- release/10.0
|
||||
- release/9.0
|
||||
- release/8.0
|
||||
paths:
|
||||
|
|
|
@ -8,7 +8,6 @@ jobs:
|
|||
linux_x64: true
|
||||
windows_x64: true
|
||||
windows_x86: true
|
||||
linux_musl_x64: true
|
||||
android_arm64: true
|
||||
|
||||
# build mono for AOT
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
parameters:
|
||||
linux_x64: false
|
||||
linux_musl_x64: false
|
||||
linux_arm64: false
|
||||
windows_x64: false
|
||||
windows_x86: false
|
||||
|
@ -8,7 +7,7 @@ parameters:
|
|||
android_arm64: false
|
||||
|
||||
jobs:
|
||||
- ${{ if or(eq(parameters.linux_x64, true), eq(parameters.windows_x64, true), eq(parameters.windows_x86, true), eq(parameters.linux_musl_x64, true), eq(parameters.linux_arm64, true), eq(parameters.windows_arm64, true)) }}:
|
||||
- ${{ if or(eq(parameters.linux_x64, true), eq(parameters.windows_x64, true), eq(parameters.windows_x86, true), eq(parameters.linux_arm64, true), eq(parameters.windows_arm64, true)) }}:
|
||||
# build coreclr and libraries
|
||||
- template: /eng/pipelines/common/platform-matrix.yml
|
||||
parameters:
|
||||
|
@ -21,8 +20,6 @@ jobs:
|
|||
- windows_x64
|
||||
- ${{ if eq(parameters.windows_x86, true) }}:
|
||||
- windows_x86
|
||||
- ${{ if eq(parameters.linux_musl_x64, true) }}:
|
||||
- linux_musl_x64
|
||||
- ${{ if eq(parameters.linux_arm64, true) }}:
|
||||
- linux_arm64
|
||||
- ${{ if eq(parameters.windows_arm64, true) }}:
|
||||
|
|
|
@ -900,13 +900,13 @@ extends:
|
|||
|
||||
# WASI/WASM
|
||||
|
||||
- template: /eng/pipelines/common/templates/simple-wasm-build-tests.yml
|
||||
parameters:
|
||||
platforms:
|
||||
- wasi_wasm
|
||||
- wasi_wasm_win
|
||||
extraBuildArgs: /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS)
|
||||
alwaysRun: ${{ variables.isRollingBuild }}
|
||||
# - template: /eng/pipelines/common/templates/simple-wasm-build-tests.yml
|
||||
# parameters:
|
||||
# platforms:
|
||||
# - wasi_wasm
|
||||
# - wasi_wasm_win
|
||||
# extraBuildArgs: /p:AotHostArchitecture=x64 /p:AotHostOS=$(_hostedOS)
|
||||
# alwaysRun: ${{ variables.isRollingBuild }}
|
||||
|
||||
#
|
||||
# Android devices
|
||||
|
@ -931,7 +931,7 @@ extends:
|
|||
testGroup: innerloop
|
||||
nameSuffix: AllSubsets_Mono
|
||||
buildArgs: -s mono+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:EnableAdditionalTimezoneChecks=true
|
||||
timeoutInMinutes: 480
|
||||
timeoutInMinutes: 120
|
||||
condition: >-
|
||||
or(
|
||||
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
|
||||
|
@ -961,7 +961,8 @@ extends:
|
|||
buildConfig: Release
|
||||
runtimeFlavor: coreclr
|
||||
platforms:
|
||||
- android_x64
|
||||
# Tracking issue: https://github.com/dotnet/dnceng/issues/5909
|
||||
# - android_x64
|
||||
- android_arm64
|
||||
variables:
|
||||
# map dependencies variables to local variables
|
||||
|
@ -973,7 +974,7 @@ extends:
|
|||
testGroup: innerloop
|
||||
nameSuffix: AllSubsets_CoreCLR
|
||||
buildArgs: -s clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true
|
||||
timeoutInMinutes: 480
|
||||
timeoutInMinutes: 120
|
||||
condition: >-
|
||||
or(
|
||||
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
|
||||
|
@ -1017,7 +1018,7 @@ extends:
|
|||
testGroup: innerloop
|
||||
nameSuffix: AllSubsets_Mono
|
||||
buildArgs: -s mono+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true /p:RunSmokeTestsOnly=true /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=false /p:EnableAggressiveTrimming=true
|
||||
timeoutInMinutes: 480
|
||||
timeoutInMinutes: 120
|
||||
condition: >-
|
||||
or(
|
||||
eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true),
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<SlnGenSolutionFolder Condition="'$(IsGeneratorProject)' == 'true'">$(SlnGenSolutionFolder)gen$(SlnGenSolutionInnerFolder)</SlnGenSolutionFolder>
|
||||
<SlnGenSolutionFolder Condition="'$(IsReferenceAssemblyProject)' == 'true'">$(SlnGenSolutionFolder)ref$(SlnGenSolutionInnerFolder)</SlnGenSolutionFolder>
|
||||
<SlnGenSolutionFolder Condition="'$(IsTestProject)' == 'true' or '$(IsTrimmingTestProject)' == 'true' or '$(IsTestSupportProject)' == 'true'">$(SlnGenSolutionFolder)tests$(SlnGenSolutionInnerFolder)</SlnGenSolutionFolder>
|
||||
<SlnGenSolutionFolder Condition="'$(IsSourceProject)' == 'true' or '$(SlnGenSolutionFolder)' == ''">$(SlnGenSolutionFolder)src$(SlnGenSolutionInnerFolder)</SlnGenSolutionFolder>
|
||||
<SlnGenSolutionFolder Condition="'$(IsSourceProject)' == 'true' or ('$(SlnGenSolutionFolder)' == '' and '$(NoDefaultSlnGenSolutionFolder)' != 'true')">$(SlnGenSolutionFolder)src$(SlnGenSolutionInnerFolder)</SlnGenSolutionFolder>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,7 +1 @@
|
|||
Wasi.Build.Tests.InvariantTests
|
||||
Wasi.Build.Tests.ILStripTests
|
||||
Wasi.Build.Tests.SdkMissingTests
|
||||
Wasi.Build.Tests.RuntimeConfigTests
|
||||
Wasi.Build.Tests.WasiTemplateTests
|
||||
Wasi.Build.Tests.PInvokeTableGeneratorTests
|
||||
Wasi.Build.Tests.WasiLibraryModeTests
|
||||
|
||||
|
|
|
@ -8,11 +8,11 @@
|
|||
"dotnet": "10.0.100-preview.7.25322.101"
|
||||
},
|
||||
"msbuild-sdks": {
|
||||
"Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25359.101",
|
||||
"Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25359.101",
|
||||
"Microsoft.DotNet.SharedFramework.Sdk": "10.0.0-beta.25359.101",
|
||||
"Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25367.101",
|
||||
"Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25367.101",
|
||||
"Microsoft.DotNet.SharedFramework.Sdk": "10.0.0-beta.25367.101",
|
||||
"Microsoft.Build.NoTargets": "3.7.0",
|
||||
"Microsoft.Build.Traversal": "3.4.0",
|
||||
"Microsoft.NET.Sdk.IL": "10.0.0-preview.7.25359.101"
|
||||
"Microsoft.NET.Sdk.IL": "10.0.0-preview.7.25367.101"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,10 @@ if (DEFINED CLR_CMAKE_ICU_DIR)
|
|||
include_directories(${CLR_CMAKE_ICU_DIR}/include)
|
||||
endif(DEFINED CLR_CMAKE_ICU_DIR)
|
||||
|
||||
if (CLR_CMAKE_TARGET_ARCH_WASM)
|
||||
add_compile_options(-fwasm-exceptions)
|
||||
endif()
|
||||
|
||||
#----------------------------------------------------
|
||||
# Cross target Component build specific configuration
|
||||
#----------------------------------------------------
|
||||
|
|
|
@ -223,6 +223,7 @@
|
|||
<Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\Marshal.CoreCLR.cs" />
|
||||
<Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\MemoryMarshal.CoreCLR.cs" />
|
||||
<Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\NativeLibrary.CoreCLR.cs" />
|
||||
<Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\Java\JavaMarshal.CoreCLR.cs" Condition="'$(FeatureJavaMarshal)' == 'true'" />
|
||||
<Compile Include="$(BclSourcesRoot)\System\Runtime\Intrinsics\X86\X86Base.CoreCLR.cs" />
|
||||
<Compile Include="$(BclSourcesRoot)\System\Runtime\Loader\AssemblyLoadContext.CoreCLR.cs" />
|
||||
<Compile Include="$(BclSourcesRoot)\System\RuntimeArgumentHandle.cs" />
|
||||
|
|
|
@ -9,6 +9,7 @@ using System.Reflection.Emit;
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
|
||||
namespace System
|
||||
{
|
||||
|
@ -144,7 +145,7 @@ namespace System
|
|||
|
||||
private static bool TrySetSlot(object?[] a, int index, object o)
|
||||
{
|
||||
if (a[index] == null && Threading.Interlocked.CompareExchange<object?>(ref a[index], o, null) == null)
|
||||
if (a[index] == null && Interlocked.CompareExchange(ref a[index], o, null) == null)
|
||||
return true;
|
||||
|
||||
// The slot may be already set because we have added and removed the same method before.
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace System.Reflection
|
|||
|
||||
#endregion
|
||||
|
||||
internal IntPtr GetUnderlyingNativeHandle() { return m_assembly; }
|
||||
internal IntPtr GetUnderlyingNativeHandle() => m_assembly;
|
||||
|
||||
private sealed class ManifestResourceStream : UnmanagedMemoryStream
|
||||
{
|
||||
|
@ -52,17 +52,8 @@ namespace System.Reflection
|
|||
// NOTE: no reason to override Write(Span<byte>), since a ManifestResourceStream is read-only.
|
||||
}
|
||||
|
||||
internal object SyncRoot
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_syncRoot == null)
|
||||
{
|
||||
Interlocked.CompareExchange<object?>(ref m_syncRoot, new object(), null);
|
||||
}
|
||||
return m_syncRoot;
|
||||
}
|
||||
}
|
||||
internal object SyncRoot =>
|
||||
m_syncRoot ?? Interlocked.CompareExchange(ref m_syncRoot, new object(), null) ?? m_syncRoot;
|
||||
|
||||
public override event ModuleResolveEventHandler? ModuleResolve
|
||||
{
|
||||
|
|
|
@ -1270,12 +1270,12 @@ namespace System.Reflection
|
|||
for (int i = 0; i < pcas.Count; i++)
|
||||
result.Add(pcas[i]);
|
||||
|
||||
while (type != (RuntimeType)typeof(object) && type != null)
|
||||
do
|
||||
{
|
||||
AddCustomAttributes(ref result, type.GetRuntimeModule(), type.MetadataToken, caType, mustBeInheritable, result);
|
||||
mustBeInheritable = true;
|
||||
type = (type.BaseType as RuntimeType)!;
|
||||
}
|
||||
} while (type != (RuntimeType)typeof(object) && type != null);
|
||||
|
||||
object[] typedResult = CreateAttributeArrayHelper(caType, result.Count);
|
||||
for (int i = 0; i < result.Count; i++)
|
||||
|
|
|
@ -61,6 +61,15 @@ namespace System.Runtime.CompilerServices
|
|||
// OSR method saved in the beginning of 'Data', or -1 if the continuation
|
||||
// belongs to a tier 0 method.
|
||||
CORINFO_CONTINUATION_OSR_IL_OFFSET_IN_DATA = 4,
|
||||
// If this bit is set the continuation should continue on the thread
|
||||
// pool.
|
||||
CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL = 8,
|
||||
// If this bit is set the continuation has a SynchronizationContext
|
||||
// that we should continue on.
|
||||
CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT = 16,
|
||||
// If this bit is set the continuation has a TaskScheduler
|
||||
// that we should continue on.
|
||||
CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_TASK_SCHEDULER = 32,
|
||||
}
|
||||
|
||||
internal sealed unsafe class Continuation
|
||||
|
@ -93,6 +102,29 @@ namespace System.Runtime.CompilerServices
|
|||
//
|
||||
public byte[]? Data;
|
||||
public object?[]? GCData;
|
||||
|
||||
public object GetContinuationContext()
|
||||
{
|
||||
int index = 0;
|
||||
if ((Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA) != 0)
|
||||
index++;
|
||||
if ((Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION) != 0)
|
||||
index++;
|
||||
Debug.Assert(GCData != null && GCData.Length > index);
|
||||
object? continuationContext = GCData[index];
|
||||
Debug.Assert(continuationContext != null);
|
||||
return continuationContext;
|
||||
}
|
||||
|
||||
public void SetException(Exception ex)
|
||||
{
|
||||
int index = 0;
|
||||
if ((Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA) != 0)
|
||||
index++;
|
||||
|
||||
Debug.Assert(GCData != null && GCData.Length > index);
|
||||
GCData[index] = ex;
|
||||
}
|
||||
}
|
||||
|
||||
public static partial class AsyncHelpers
|
||||
|
@ -171,240 +203,385 @@ namespace System.Runtime.CompilerServices
|
|||
return RuntimeTypeHandle.InternalAllocNoChecks((MethodTable*)pMT);
|
||||
}
|
||||
|
||||
// wrapper to await a notifier
|
||||
private struct AwaitableProxy : ICriticalNotifyCompletion
|
||||
private interface IThunkTaskOps<T>
|
||||
{
|
||||
private readonly INotifyCompletion _notifier;
|
||||
|
||||
public AwaitableProxy(INotifyCompletion notifier)
|
||||
{
|
||||
_notifier = notifier;
|
||||
}
|
||||
|
||||
public bool IsCompleted => false;
|
||||
|
||||
public void OnCompleted(Action action)
|
||||
{
|
||||
_notifier!.OnCompleted(action);
|
||||
}
|
||||
|
||||
public AwaitableProxy GetAwaiter() { return this; }
|
||||
|
||||
public void UnsafeOnCompleted(Action action)
|
||||
{
|
||||
if (_notifier is ICriticalNotifyCompletion criticalNotification)
|
||||
{
|
||||
criticalNotification.UnsafeOnCompleted(action);
|
||||
}
|
||||
else
|
||||
{
|
||||
_notifier!.OnCompleted(action);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetResult() { }
|
||||
static abstract Action GetContinuationAction(T task);
|
||||
static abstract Continuation GetContinuationState(T task);
|
||||
static abstract void SetContinuationState(T task, Continuation value);
|
||||
static abstract bool SetCompleted(T task, Continuation continuation);
|
||||
static abstract void PostToSyncContext(T task, SynchronizationContext syncCtx);
|
||||
}
|
||||
|
||||
private static Continuation UnlinkHeadContinuation(out AwaitableProxy awaitableProxy)
|
||||
private sealed class ThunkTask<T> : Task<T>
|
||||
{
|
||||
ref RuntimeAsyncAwaitState state = ref t_runtimeAsyncAwaitState;
|
||||
awaitableProxy = new AwaitableProxy(state.Notifier!);
|
||||
state.Notifier = null;
|
||||
|
||||
Continuation sentinelContinuation = state.SentinelContinuation!;
|
||||
Continuation head = sentinelContinuation.Next!;
|
||||
sentinelContinuation.Next = null;
|
||||
return head;
|
||||
}
|
||||
|
||||
// When a Task-returning thunk gets a continuation result
|
||||
// it calls here to make a Task that awaits on the current async state.
|
||||
// NOTE: This cannot be Runtime Async. Must use C# state machine or make one by hand.
|
||||
private static async Task<T?> FinalizeTaskReturningThunk<T>(Continuation continuation)
|
||||
{
|
||||
Continuation finalContinuation = new Continuation();
|
||||
|
||||
// Note that the exact location the return value is placed is tied
|
||||
// into getAsyncResumptionStub in the VM, so do not change this
|
||||
// without also changing that code (and the JIT).
|
||||
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
|
||||
public ThunkTask()
|
||||
{
|
||||
finalContinuation.Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA | CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION;
|
||||
finalContinuation.GCData = new object[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
finalContinuation.Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION;
|
||||
finalContinuation.Data = new byte[Unsafe.SizeOf<T>()];
|
||||
// We use the base Task's state object field to store the Continuation while posting the task around.
|
||||
// Ensure that state object isn't published out for others to see.
|
||||
Debug.Assert((m_stateFlags & (int)InternalTaskOptions.PromiseTask) != 0, "Expected state flags to already be configured.");
|
||||
Debug.Assert(m_stateObject is null, "Expected to be able to use the state object field for Continuation.");
|
||||
m_action = MoveNext;
|
||||
m_stateFlags |= (int)InternalTaskOptions.HiddenState;
|
||||
}
|
||||
|
||||
continuation.Next = finalContinuation;
|
||||
|
||||
while (true)
|
||||
internal override void ExecuteFromThreadPool(Thread threadPoolThread)
|
||||
{
|
||||
Continuation headContinuation = UnlinkHeadContinuation(out var awaitableProxy);
|
||||
await awaitableProxy;
|
||||
Continuation? finalResult = DispatchContinuations(headContinuation);
|
||||
if (finalResult != null)
|
||||
MoveNext();
|
||||
}
|
||||
|
||||
private void MoveNext()
|
||||
{
|
||||
ThunkTaskCore.MoveNext<ThunkTask<T>, Ops>(this);
|
||||
}
|
||||
|
||||
public void HandleSuspended()
|
||||
{
|
||||
ThunkTaskCore.HandleSuspended<ThunkTask<T>, Ops>(this);
|
||||
}
|
||||
|
||||
private static readonly SendOrPostCallback s_postCallback = static state =>
|
||||
{
|
||||
Debug.Assert(state is ThunkTask<T>);
|
||||
((ThunkTask<T>)state).MoveNext();
|
||||
};
|
||||
|
||||
private struct Ops : IThunkTaskOps<ThunkTask<T>>
|
||||
{
|
||||
public static Action GetContinuationAction(ThunkTask<T> task) => (Action)task.m_action!;
|
||||
public static void MoveNext(ThunkTask<T> task) => task.MoveNext();
|
||||
public static Continuation GetContinuationState(ThunkTask<T> task) => (Continuation)task.m_stateObject!;
|
||||
public static void SetContinuationState(ThunkTask<T> task, Continuation value)
|
||||
{
|
||||
Debug.Assert(finalResult == finalContinuation);
|
||||
task.m_stateObject = value;
|
||||
}
|
||||
|
||||
public static bool SetCompleted(ThunkTask<T> task, Continuation continuation)
|
||||
{
|
||||
T result;
|
||||
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
if (typeof(T).IsValueType)
|
||||
{
|
||||
return Unsafe.As<byte, T>(ref finalResult.GCData![0]!.GetRawData());
|
||||
result = Unsafe.As<byte, T>(ref continuation.GCData![0]!.GetRawData());
|
||||
}
|
||||
|
||||
return Unsafe.As<object, T>(ref finalResult.GCData![0]!);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Unsafe.As<byte, T>(ref finalResult.Data![0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task FinalizeTaskReturningThunk(Continuation continuation)
|
||||
{
|
||||
Continuation finalContinuation = new Continuation
|
||||
{
|
||||
Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION,
|
||||
};
|
||||
continuation.Next = finalContinuation;
|
||||
|
||||
while (true)
|
||||
{
|
||||
Continuation headContinuation = UnlinkHeadContinuation(out var awaitableProxy);
|
||||
await awaitableProxy;
|
||||
Continuation? finalResult = DispatchContinuations(headContinuation);
|
||||
if (finalResult != null)
|
||||
{
|
||||
Debug.Assert(finalResult == finalContinuation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async ValueTask<T?> FinalizeValueTaskReturningThunk<T>(Continuation continuation)
|
||||
{
|
||||
Continuation finalContinuation = new Continuation();
|
||||
|
||||
// Note that the exact location the return value is placed is tied
|
||||
// into getAsyncResumptionStub in the VM, so do not change this
|
||||
// without also changing that code (and the JIT).
|
||||
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
finalContinuation.Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA | CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION;
|
||||
finalContinuation.GCData = new object[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
finalContinuation.Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION;
|
||||
finalContinuation.Data = new byte[Unsafe.SizeOf<T>()];
|
||||
}
|
||||
|
||||
continuation.Next = finalContinuation;
|
||||
|
||||
while (true)
|
||||
{
|
||||
Continuation headContinuation = UnlinkHeadContinuation(out var awaitableProxy);
|
||||
await awaitableProxy;
|
||||
Continuation? finalResult = DispatchContinuations(headContinuation);
|
||||
if (finalResult != null)
|
||||
{
|
||||
Debug.Assert(finalResult == finalContinuation);
|
||||
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
if (typeof(T).IsValueType)
|
||||
else
|
||||
{
|
||||
return Unsafe.As<byte, T>(ref finalResult.GCData![0]!.GetRawData());
|
||||
result = Unsafe.As<object, T>(ref continuation.GCData![0]!);
|
||||
}
|
||||
|
||||
return Unsafe.As<object, T>(ref finalResult.GCData![0]!);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Unsafe.As<byte, T>(ref finalResult.Data![0]);
|
||||
result = Unsafe.As<byte, T>(ref continuation.Data![0]);
|
||||
}
|
||||
|
||||
return task.TrySetResult(result);
|
||||
}
|
||||
|
||||
public static void PostToSyncContext(ThunkTask<T> task, SynchronizationContext syncContext)
|
||||
{
|
||||
syncContext.Post(s_postCallback, task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class ThunkTask : Task
|
||||
{
|
||||
public ThunkTask()
|
||||
{
|
||||
// We use the base Task's state object field to store the Continuation while posting the task around.
|
||||
// Ensure that state object isn't published out for others to see.
|
||||
Debug.Assert((m_stateFlags & (int)InternalTaskOptions.PromiseTask) != 0, "Expected state flags to already be configured.");
|
||||
Debug.Assert(m_stateObject is null, "Expected to be able to use the state object field for Continuation.");
|
||||
m_action = MoveNext;
|
||||
m_stateFlags |= (int)InternalTaskOptions.HiddenState;
|
||||
}
|
||||
|
||||
internal override void ExecuteFromThreadPool(Thread threadPoolThread)
|
||||
{
|
||||
MoveNext();
|
||||
}
|
||||
|
||||
private void MoveNext()
|
||||
{
|
||||
ThunkTaskCore.MoveNext<ThunkTask, Ops>(this);
|
||||
}
|
||||
|
||||
public void HandleSuspended()
|
||||
{
|
||||
ThunkTaskCore.HandleSuspended<ThunkTask, Ops>(this);
|
||||
}
|
||||
|
||||
private static readonly SendOrPostCallback s_postCallback = static state =>
|
||||
{
|
||||
Debug.Assert(state is ThunkTask);
|
||||
((ThunkTask)state).MoveNext();
|
||||
};
|
||||
|
||||
private struct Ops : IThunkTaskOps<ThunkTask>
|
||||
{
|
||||
public static Action GetContinuationAction(ThunkTask task) => (Action)task.m_action!;
|
||||
public static void MoveNext(ThunkTask task) => task.MoveNext();
|
||||
public static Continuation GetContinuationState(ThunkTask task) => (Continuation)task.m_stateObject!;
|
||||
public static void SetContinuationState(ThunkTask task, Continuation value)
|
||||
{
|
||||
task.m_stateObject = value;
|
||||
}
|
||||
|
||||
public static bool SetCompleted(ThunkTask task, Continuation continuation)
|
||||
{
|
||||
return task.TrySetResult();
|
||||
}
|
||||
|
||||
public static void PostToSyncContext(ThunkTask task, SynchronizationContext syncContext)
|
||||
{
|
||||
syncContext.Post(s_postCallback, task);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ThunkTaskCore
|
||||
{
|
||||
public static unsafe void MoveNext<T, TOps>(T task) where T : Task where TOps : IThunkTaskOps<T>
|
||||
{
|
||||
ExecutionAndSyncBlockStore contexts = default;
|
||||
contexts.Push();
|
||||
Continuation continuation = TOps.GetContinuationState(task);
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
Continuation? newContinuation = continuation.Resume(continuation);
|
||||
|
||||
if (newContinuation != null)
|
||||
{
|
||||
newContinuation.Next = continuation.Next;
|
||||
HandleSuspended<T, TOps>(task);
|
||||
contexts.Pop();
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Assert(continuation.Next != null);
|
||||
continuation = continuation.Next;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Continuation nextContinuation = UnwindToPossibleHandler(continuation);
|
||||
if (nextContinuation.Resume == null)
|
||||
{
|
||||
// Tail of AsyncTaskMethodBuilderT.SetException
|
||||
bool successfullySet = ex is OperationCanceledException oce ?
|
||||
task.TrySetCanceled(oce.CancellationToken, oce) :
|
||||
task.TrySetException(ex);
|
||||
|
||||
contexts.Pop();
|
||||
|
||||
if (!successfullySet)
|
||||
{
|
||||
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
nextContinuation.SetException(ex);
|
||||
|
||||
continuation = nextContinuation;
|
||||
}
|
||||
|
||||
if (continuation.Resume == null)
|
||||
{
|
||||
bool successfullySet = TOps.SetCompleted(task, continuation);
|
||||
|
||||
contexts.Pop();
|
||||
|
||||
if (!successfullySet)
|
||||
{
|
||||
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (QueueContinuationFollowUpActionIfNecessary<T, TOps>(task, continuation))
|
||||
{
|
||||
contexts.Pop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async ValueTask FinalizeValueTaskReturningThunk(Continuation continuation)
|
||||
{
|
||||
Continuation finalContinuation = new Continuation
|
||||
private static Continuation UnwindToPossibleHandler(Continuation continuation)
|
||||
{
|
||||
Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION,
|
||||
};
|
||||
continuation.Next = finalContinuation;
|
||||
|
||||
while (true)
|
||||
{
|
||||
Continuation headContinuation = UnlinkHeadContinuation(out var awaitableProxy);
|
||||
await awaitableProxy;
|
||||
Continuation? finalResult = DispatchContinuations(headContinuation);
|
||||
if (finalResult != null)
|
||||
while (true)
|
||||
{
|
||||
Debug.Assert(finalResult == finalContinuation);
|
||||
return;
|
||||
Debug.Assert(continuation.Next != null);
|
||||
continuation = continuation.Next;
|
||||
if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION) != 0)
|
||||
return continuation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return a continuation object if that is the one which has the final
|
||||
// result of the Task, if the real output of the series of continuations was
|
||||
// an exception, it is allowed to propagate out.
|
||||
// OR
|
||||
// return NULL to indicate that this isn't yet done.
|
||||
private static unsafe Continuation? DispatchContinuations(Continuation? continuation)
|
||||
{
|
||||
Debug.Assert(continuation != null);
|
||||
|
||||
while (true)
|
||||
public static void HandleSuspended<T, TOps>(T task) where T : Task where TOps : IThunkTaskOps<T>
|
||||
{
|
||||
Continuation? newContinuation;
|
||||
Continuation headContinuation = UnlinkHeadContinuation(out INotifyCompletion? notifier);
|
||||
|
||||
// Head continuation should be the result of async call to AwaitAwaiter or UnsafeAwaitAwaiter.
|
||||
// These never have special continuation handling.
|
||||
const CorInfoContinuationFlags continueFlags =
|
||||
CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT |
|
||||
CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL |
|
||||
CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_TASK_SCHEDULER;
|
||||
Debug.Assert((headContinuation.Flags & continueFlags) == 0);
|
||||
|
||||
TOps.SetContinuationState(task, headContinuation);
|
||||
|
||||
try
|
||||
{
|
||||
newContinuation = continuation.Resume(continuation);
|
||||
if (notifier is ICriticalNotifyCompletion crit)
|
||||
{
|
||||
crit.UnsafeOnCompleted(TOps.GetContinuationAction(task));
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert(notifier != null);
|
||||
notifier.OnCompleted(TOps.GetContinuationAction(task));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
continuation = UnwindToPossibleHandler(continuation);
|
||||
if (continuation.Resume == null)
|
||||
Task.ThrowAsync(ex, targetContext: null);
|
||||
}
|
||||
}
|
||||
|
||||
private static Continuation UnlinkHeadContinuation(out INotifyCompletion? notifier)
|
||||
{
|
||||
ref RuntimeAsyncAwaitState state = ref t_runtimeAsyncAwaitState;
|
||||
notifier = state.Notifier;
|
||||
state.Notifier = null;
|
||||
|
||||
Continuation sentinelContinuation = state.SentinelContinuation!;
|
||||
Continuation head = sentinelContinuation.Next!;
|
||||
sentinelContinuation.Next = null;
|
||||
return head;
|
||||
}
|
||||
|
||||
private static bool QueueContinuationFollowUpActionIfNecessary<T, TOps>(T task, Continuation continuation) where T : Task where TOps : IThunkTaskOps<T>
|
||||
{
|
||||
if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL) != 0)
|
||||
{
|
||||
SynchronizationContext? ctx = Thread.CurrentThreadAssumedInitialized._synchronizationContext;
|
||||
if (ctx == null || ctx.GetType() == typeof(SynchronizationContext))
|
||||
{
|
||||
throw;
|
||||
TaskScheduler? sched = TaskScheduler.InternalCurrent;
|
||||
if (sched == null || sched == TaskScheduler.Default)
|
||||
{
|
||||
// Can inline
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
continuation.GCData![(continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA) != 0 ? 1 : 0] = ex;
|
||||
continue;
|
||||
TOps.SetContinuationState(task, continuation);
|
||||
ThreadPool.UnsafeQueueUserWorkItemInternal(task, preferLocal: true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (newContinuation != null)
|
||||
if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT) != 0)
|
||||
{
|
||||
newContinuation.Next = continuation.Next;
|
||||
return null;
|
||||
object continuationContext = continuation.GetContinuationContext();
|
||||
Debug.Assert(continuationContext is SynchronizationContext { });
|
||||
SynchronizationContext continuationSyncCtx = (SynchronizationContext)continuationContext;
|
||||
|
||||
if (continuationSyncCtx == Thread.CurrentThreadAssumedInitialized._synchronizationContext)
|
||||
{
|
||||
// Inline
|
||||
return false;
|
||||
}
|
||||
|
||||
TOps.SetContinuationState(task, continuation);
|
||||
|
||||
try
|
||||
{
|
||||
TOps.PostToSyncContext(task, continuationSyncCtx);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Task.ThrowAsync(ex, targetContext: null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
continuation = continuation.Next;
|
||||
Debug.Assert(continuation != null);
|
||||
|
||||
if (continuation.Resume == null)
|
||||
if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_TASK_SCHEDULER) != 0)
|
||||
{
|
||||
return continuation; // Return the result containing Continuation
|
||||
object continuationContext = continuation.GetContinuationContext();
|
||||
Debug.Assert(continuationContext is TaskScheduler { });
|
||||
TaskScheduler sched = (TaskScheduler)continuationContext;
|
||||
|
||||
TOps.SetContinuationState(task, continuation);
|
||||
// TODO: We do not need TaskSchedulerAwaitTaskContinuation here, just need to refactor its Run method...
|
||||
var taskSchedCont = new TaskSchedulerAwaitTaskContinuation(sched, TOps.GetContinuationAction(task), flowExecutionContext: false);
|
||||
taskSchedCont.Run(Task.CompletedTask, canInlineContinuationTask: true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static Continuation UnwindToPossibleHandler(Continuation continuation)
|
||||
// Change return type to ThunkTask<T?> -- no benefit since this is used for Task returning thunks only
|
||||
#pragma warning disable CA1859
|
||||
// When a Task-returning thunk gets a continuation result
|
||||
// it calls here to make a Task that awaits on the current async state.
|
||||
private static Task<T?> FinalizeTaskReturningThunk<T>(Continuation continuation)
|
||||
{
|
||||
while (true)
|
||||
Continuation finalContinuation = new Continuation();
|
||||
|
||||
// Note that the exact location the return value is placed is tied
|
||||
// into getAsyncResumptionStub in the VM, so do not change this
|
||||
// without also changing that code (and the JIT).
|
||||
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
|
||||
{
|
||||
Debug.Assert(continuation.Next != null);
|
||||
continuation = continuation.Next;
|
||||
if ((continuation.Flags & CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION) != 0)
|
||||
return continuation;
|
||||
finalContinuation.Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_RESULT_IN_GCDATA | CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION;
|
||||
finalContinuation.GCData = new object[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
finalContinuation.Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION;
|
||||
finalContinuation.Data = new byte[Unsafe.SizeOf<T>()];
|
||||
}
|
||||
|
||||
continuation.Next = finalContinuation;
|
||||
|
||||
ThunkTask<T?> result = new();
|
||||
result.HandleSuspended();
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Task FinalizeTaskReturningThunk(Continuation continuation)
|
||||
{
|
||||
Continuation finalContinuation = new Continuation
|
||||
{
|
||||
Flags = CorInfoContinuationFlags.CORINFO_CONTINUATION_NEEDS_EXCEPTION,
|
||||
};
|
||||
continuation.Next = finalContinuation;
|
||||
|
||||
ThunkTask result = new();
|
||||
result.HandleSuspended();
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ValueTask<T?> FinalizeValueTaskReturningThunk<T>(Continuation continuation)
|
||||
{
|
||||
// We only come to these methods in the expensive case (already
|
||||
// suspended), so ValueTask optimization here is not relevant.
|
||||
return new ValueTask<T?>(FinalizeTaskReturningThunk<T>(continuation));
|
||||
}
|
||||
|
||||
private static ValueTask FinalizeValueTaskReturningThunk(Continuation continuation)
|
||||
{
|
||||
return new ValueTask(FinalizeTaskReturningThunk(continuation));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
|
@ -414,14 +591,58 @@ namespace System.Runtime.CompilerServices
|
|||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void RestoreExecutionContext(ExecutionContext? previousExecutionCtx)
|
||||
private static void RestoreExecutionContext(ExecutionContext? previousExecCtx)
|
||||
{
|
||||
Thread thread = Thread.CurrentThreadAssumedInitialized;
|
||||
ExecutionContext? currentExecutionCtx = thread._executionContext;
|
||||
if (previousExecutionCtx != currentExecutionCtx)
|
||||
ExecutionContext? currentExecCtx = thread._executionContext;
|
||||
if (previousExecCtx != currentExecCtx)
|
||||
{
|
||||
ExecutionContext.RestoreChangedContextToThread(thread, previousExecutionCtx, currentExecutionCtx);
|
||||
ExecutionContext.RestoreChangedContextToThread(thread, previousExecCtx, currentExecCtx);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void CaptureContexts(out ExecutionContext? execCtx, out SynchronizationContext? syncCtx)
|
||||
{
|
||||
Thread thread = Thread.CurrentThreadAssumedInitialized;
|
||||
execCtx = thread._executionContext;
|
||||
syncCtx = thread._synchronizationContext;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void RestoreContexts(bool suspended, ExecutionContext? previousExecCtx, SynchronizationContext? previousSyncCtx)
|
||||
{
|
||||
Thread thread = Thread.CurrentThreadAssumedInitialized;
|
||||
if (!suspended && previousSyncCtx != thread._synchronizationContext)
|
||||
{
|
||||
thread._synchronizationContext = previousSyncCtx;
|
||||
}
|
||||
|
||||
ExecutionContext? currentExecCtx = thread._executionContext;
|
||||
if (previousExecCtx != currentExecCtx)
|
||||
{
|
||||
ExecutionContext.RestoreChangedContextToThread(thread, previousExecCtx, currentExecCtx);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CaptureContinuationContext(SynchronizationContext syncCtx, ref object context, ref CorInfoContinuationFlags flags)
|
||||
{
|
||||
if (syncCtx != null && syncCtx.GetType() != typeof(SynchronizationContext))
|
||||
{
|
||||
flags |= CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_SYNCHRONIZATION_CONTEXT;
|
||||
context = syncCtx;
|
||||
return;
|
||||
}
|
||||
|
||||
TaskScheduler? sched = TaskScheduler.InternalCurrent;
|
||||
if (sched != null && sched != TaskScheduler.Default)
|
||||
{
|
||||
flags |= CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_CAPTURED_TASK_SCHEDULER;
|
||||
context = sched;
|
||||
return;
|
||||
}
|
||||
|
||||
flags |= CorInfoContinuationFlags.CORINFO_CONTINUATION_CONTINUE_ON_THREAD_POOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,9 +51,9 @@ class AsmOffsets
|
|||
public const int OFFSETOF__REGDISPLAY__SP = 0xba8;
|
||||
public const int OFFSETOF__REGDISPLAY__ControlPC = 0xbb0;
|
||||
#elif TARGET_WASM
|
||||
public const int SIZEOF__REGDISPLAY = 0x3c;
|
||||
public const int OFFSETOF__REGDISPLAY__SP = 0x34;
|
||||
public const int OFFSETOF__REGDISPLAY__ControlPC = 0x38;
|
||||
public const int SIZEOF__REGDISPLAY = 0x38;
|
||||
public const int OFFSETOF__REGDISPLAY__SP = 0x30;
|
||||
public const int OFFSETOF__REGDISPLAY__ControlPC = 0x34;
|
||||
#endif
|
||||
|
||||
#if TARGET_64BIT
|
||||
|
@ -73,9 +73,14 @@ class AsmOffsets
|
|||
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x3d0;
|
||||
#else // TARGET_64BIT
|
||||
public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4;
|
||||
#if FEATURE_INTERPRETER
|
||||
public const int SIZEOF__StackFrameIterator = 0xdc;
|
||||
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xd8;
|
||||
#else
|
||||
public const int SIZEOF__StackFrameIterator = 0xcc;
|
||||
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xba;
|
||||
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xc8;
|
||||
#endif
|
||||
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xba;
|
||||
#endif // TARGET_64BIT
|
||||
|
||||
#else // DEBUG
|
||||
|
@ -117,9 +122,9 @@ class AsmOffsets
|
|||
public const int OFFSETOF__REGDISPLAY__SP = 0xba0;
|
||||
public const int OFFSETOF__REGDISPLAY__ControlPC = 0xba8;
|
||||
#elif TARGET_WASM
|
||||
public const int SIZEOF__REGDISPLAY = 0x3c;
|
||||
public const int OFFSETOF__REGDISPLAY__SP = 0x34;
|
||||
public const int OFFSETOF__REGDISPLAY__ControlPC = 0x38;
|
||||
public const int SIZEOF__REGDISPLAY = 0x34;
|
||||
public const int OFFSETOF__REGDISPLAY__SP = 0x2c;
|
||||
public const int OFFSETOF__REGDISPLAY__ControlPC = 0x30;
|
||||
#endif
|
||||
|
||||
#if TARGET_64BIT
|
||||
|
@ -139,9 +144,14 @@ class AsmOffsets
|
|||
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0x3c8;
|
||||
#else // TARGET_64BIT
|
||||
public const int OFFSETOF__REGDISPLAY__m_pCurrentContext = 0x4;
|
||||
#if FEATURE_INTERPRETER
|
||||
public const int SIZEOF__StackFrameIterator = 0xd4;
|
||||
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xd0;
|
||||
#else
|
||||
public const int SIZEOF__StackFrameIterator = 0xc4;
|
||||
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xb2;
|
||||
public const int OFFSETOF__StackFrameIterator__m_AdjustedControlPC = 0xc0;
|
||||
#endif
|
||||
public const int OFFSETOF__StackFrameIterator__m_isRuntimeWrappedExceptions = 0xb2;
|
||||
#endif // TARGET_64BIT
|
||||
|
||||
#endif // DEBUG
|
||||
|
@ -167,7 +177,7 @@ class AsmOffsets
|
|||
#elif TARGET_LOONGARCH64
|
||||
public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x520;
|
||||
#elif TARGET_WASM
|
||||
public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x08;
|
||||
public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x04;
|
||||
#endif
|
||||
|
||||
#if TARGET_AMD64
|
||||
|
|
|
@ -12,39 +12,24 @@ namespace System.Runtime.InteropServices.Java
|
|||
{
|
||||
public static unsafe void Initialize(delegate* unmanaged<MarkCrossReferencesArgs*, void> markCrossReferences)
|
||||
{
|
||||
#if NATIVEAOT
|
||||
throw new NotImplementedException();
|
||||
#elif FEATURE_JAVAMARSHAL
|
||||
ArgumentNullException.ThrowIfNull(markCrossReferences);
|
||||
|
||||
if (!InitializeInternal((IntPtr)markCrossReferences))
|
||||
{
|
||||
throw new InvalidOperationException(SR.InvalidOperation_ReinitializeJavaMarshal);
|
||||
}
|
||||
#else
|
||||
throw new PlatformNotSupportedException();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static unsafe GCHandle CreateReferenceTrackingHandle(object obj, void* context)
|
||||
{
|
||||
#if NATIVEAOT
|
||||
throw new NotImplementedException();
|
||||
#elif FEATURE_JAVAMARSHAL
|
||||
ArgumentNullException.ThrowIfNull(obj);
|
||||
|
||||
IntPtr handle = CreateReferenceTrackingHandleInternal(ObjectHandleOnStack.Create(ref obj), context);
|
||||
return GCHandle.FromIntPtr(handle);
|
||||
#else
|
||||
throw new PlatformNotSupportedException();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static unsafe void* GetContext(GCHandle obj)
|
||||
{
|
||||
#if NATIVEAOT
|
||||
throw new NotImplementedException();
|
||||
#elif FEATURE_JAVAMARSHAL
|
||||
IntPtr handle = GCHandle.ToIntPtr(obj);
|
||||
if (handle == IntPtr.Zero
|
||||
|| !GetContextInternal(handle, out void* context))
|
||||
|
@ -53,18 +38,12 @@ namespace System.Runtime.InteropServices.Java
|
|||
}
|
||||
|
||||
return context;
|
||||
#else
|
||||
throw new PlatformNotSupportedException();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static unsafe void FinishCrossReferenceProcessing(
|
||||
MarkCrossReferencesArgs* crossReferences,
|
||||
ReadOnlySpan<GCHandle> unreachableObjectHandles)
|
||||
{
|
||||
#if NATIVEAOT
|
||||
throw new NotImplementedException();
|
||||
#elif FEATURE_JAVAMARSHAL
|
||||
fixed (GCHandle* pHandles = unreachableObjectHandles)
|
||||
{
|
||||
FinishCrossReferenceProcessing(
|
||||
|
@ -72,12 +51,8 @@ namespace System.Runtime.InteropServices.Java
|
|||
(nuint)unreachableObjectHandles.Length,
|
||||
pHandles);
|
||||
}
|
||||
#else
|
||||
throw new PlatformNotSupportedException();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if FEATURE_JAVAMARSHAL && !NATIVEAOT
|
||||
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "JavaMarshal_Initialize")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static partial bool InitializeInternal(IntPtr callback);
|
||||
|
@ -92,6 +67,5 @@ namespace System.Runtime.InteropServices.Java
|
|||
[SuppressGCTransition]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static unsafe partial bool GetContextInternal(IntPtr handle, out void* context);
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -3974,6 +3974,11 @@ namespace System
|
|||
throw new MissingMethodException(SR.Format(SR.Arg_NoDefCTor, this));
|
||||
}
|
||||
|
||||
if (IsByRefLike)
|
||||
{
|
||||
throw new NotSupportedException(SR.NotSupported_ByRefLike);
|
||||
}
|
||||
|
||||
// Compat: allocation always takes place outside the try block so that OOMs
|
||||
// bubble up to the caller; the ctor invocation is within the try block so
|
||||
// that it can be wrapped in TIE if needed.
|
||||
|
@ -3996,6 +4001,8 @@ namespace System
|
|||
[DebuggerHidden]
|
||||
internal object? CreateInstanceOfT()
|
||||
{
|
||||
Debug.Assert(!IsValueType);
|
||||
|
||||
ActivatorCache cache = GetOrCreateCacheEntry<ActivatorCache>();
|
||||
|
||||
if (!cache.CtorIsPublic)
|
||||
|
|
|
@ -1351,26 +1351,20 @@ namespace System.StubHelpers
|
|||
|
||||
internal static Exception GetHRExceptionObject(int hr)
|
||||
{
|
||||
Exception? ex = null;
|
||||
GetHRExceptionObject(hr, ObjectHandleOnStack.Create(ref ex));
|
||||
ex!.InternalPreserveStackTrace();
|
||||
return ex!;
|
||||
Exception ex = Marshal.GetExceptionForHR(hr)!;
|
||||
ex.InternalPreserveStackTrace();
|
||||
return ex;
|
||||
}
|
||||
|
||||
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_GetHRExceptionObject")]
|
||||
private static partial void GetHRExceptionObject(int hr, ObjectHandleOnStack throwable);
|
||||
|
||||
#if FEATURE_COMINTEROP
|
||||
internal static Exception GetCOMHRExceptionObject(int hr, IntPtr pCPCMD, object pThis)
|
||||
internal static Exception GetCOMHRExceptionObject(int hr, IntPtr pCPCMD, IntPtr pUnk)
|
||||
{
|
||||
Exception? ex = null;
|
||||
GetCOMHRExceptionObject(hr, pCPCMD, ObjectHandleOnStack.Create(ref pThis), ObjectHandleOnStack.Create(ref ex));
|
||||
ex!.InternalPreserveStackTrace();
|
||||
return ex!;
|
||||
RuntimeMethodHandle handle = RuntimeMethodHandle.FromIntPtr(pCPCMD);
|
||||
RuntimeType declaringType = RuntimeMethodHandle.GetDeclaringType(handle.GetMethodInfo());
|
||||
Exception ex = Marshal.GetExceptionForHR(hr, declaringType.GUID, pUnk)!;
|
||||
ex.InternalPreserveStackTrace();
|
||||
return ex;
|
||||
}
|
||||
|
||||
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "StubHelpers_GetCOMHRExceptionObject")]
|
||||
private static partial void GetCOMHRExceptionObject(int hr, IntPtr pCPCMD, ObjectHandleOnStack pThis, ObjectHandleOnStack throwable);
|
||||
#endif // FEATURE_COMINTEROP
|
||||
|
||||
[ThreadStatic]
|
||||
|
@ -1583,8 +1577,7 @@ namespace System.StubHelpers
|
|||
internal static partial void ValidateByref(IntPtr byref, IntPtr pMD); // the byref is pinned so we can safely "cast" it to IntPtr
|
||||
|
||||
[Intrinsic]
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern IntPtr GetStubContext();
|
||||
internal static IntPtr GetStubContext() => throw new UnreachableException(); // Unconditionally expanded intrinsic
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void MulticastDebuggerTraceHelper(object o, int count)
|
||||
|
@ -1596,11 +1589,10 @@ namespace System.StubHelpers
|
|||
private static partial void MulticastDebuggerTraceHelperQCall(ObjectHandleOnStack obj, int count);
|
||||
|
||||
[Intrinsic]
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern IntPtr NextCallReturnAddress();
|
||||
internal static IntPtr NextCallReturnAddress() => throw new UnreachableException(); // Unconditionally expanded intrinsic
|
||||
|
||||
[Intrinsic]
|
||||
internal static Continuation? AsyncCallContinuation() => null;
|
||||
internal static Continuation? AsyncCallContinuation() => throw new UnreachableException(); // Unconditionally expanded intrinsic
|
||||
} // class StubHelpers
|
||||
|
||||
#if FEATURE_COMINTEROP
|
||||
|
|
|
@ -152,8 +152,6 @@ if(FEATURE_OBJCMARSHAL)
|
|||
add_compile_definitions(FEATURE_OBJCMARSHAL)
|
||||
endif()
|
||||
|
||||
# add_compile_definitions(FEATURE_RUNTIME_ASYNC)
|
||||
|
||||
add_compile_definitions($<${FEATURE_JAVAMARSHAL}:FEATURE_JAVAMARSHAL>)
|
||||
|
||||
add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:DAC_COMPONENT>>>:FEATURE_PROFAPI_ATTACH_DETACH>)
|
||||
|
|
|
@ -2,6 +2,10 @@ if (NOT CLR_CMAKE_TARGET_ARCH_WASM)
|
|||
set(FEATURE_JIT 1)
|
||||
endif()
|
||||
|
||||
if (CLR_CMAKE_TARGET_ARCH_WASM OR CLR_CMAKE_TARGET_MACCATALYST OR CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS)
|
||||
set(FEATURE_STATICALLY_LINKED 1)
|
||||
endif()
|
||||
|
||||
if(CLR_CMAKE_TARGET_TIZEN_LINUX)
|
||||
set(FEATURE_GDBJIT_LANGID_CS 1)
|
||||
endif()
|
||||
|
@ -32,13 +36,15 @@ endif(NOT DEFINED FEATURE_DBGIPC)
|
|||
|
||||
if(NOT DEFINED FEATURE_INTERPRETER)
|
||||
if(CLR_CMAKE_TARGET_ANDROID)
|
||||
set(FEATURE_INTERPRETER 0)
|
||||
set(FEATURE_INTERPRETER 0)
|
||||
elseif(CLR_CMAKE_TARGET_ARCH_WASM)
|
||||
set(FEATURE_INTERPRETER 1)
|
||||
else()
|
||||
if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
|
||||
set(FEATURE_INTERPRETER $<IF:$<CONFIG:Debug,Checked>,1,0>)
|
||||
else(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
|
||||
set(FEATURE_INTERPRETER 0)
|
||||
endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
|
||||
if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
|
||||
set(FEATURE_INTERPRETER $<IF:$<CONFIG:Debug,Checked>,1,0>)
|
||||
else(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
|
||||
set(FEATURE_INTERPRETER 0)
|
||||
endif(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
|
||||
endif()
|
||||
endif(NOT DEFINED FEATURE_INTERPRETER)
|
||||
|
||||
|
@ -54,7 +60,7 @@ if(NOT DEFINED FEATURE_SINGLE_FILE_DIAGNOSTICS)
|
|||
set(FEATURE_SINGLE_FILE_DIAGNOSTICS 1)
|
||||
endif(NOT DEFINED FEATURE_SINGLE_FILE_DIAGNOSTICS)
|
||||
|
||||
if (CLR_CMAKE_TARGET_WIN32 OR CLR_CMAKE_TARGET_UNIX)
|
||||
if ((CLR_CMAKE_TARGET_WIN32 OR CLR_CMAKE_TARGET_UNIX) AND NOT CLR_CMAKE_TARGET_ARCH_WASM)
|
||||
set(FEATURE_COMWRAPPERS 1)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -3423,9 +3423,9 @@ void DacDbiInterfaceImpl::EnumerateMemRangesForJitCodeHeaps(CQuickArrayList<COR_
|
|||
{
|
||||
// We should always have a valid EEJitManager with at least one code heap.
|
||||
EEJitManager *pEM = ExecutionManager::GetEEJitManager();
|
||||
_ASSERTE(pEM != NULL && pEM->m_pCodeHeap.IsValid());
|
||||
_ASSERTE(pEM != NULL && pEM->m_pAllCodeHeaps.IsValid());
|
||||
|
||||
PTR_HeapList pHeapList = pEM->m_pCodeHeap;
|
||||
PTR_HeapList pHeapList = pEM->m_pAllCodeHeaps;
|
||||
while (pHeapList != NULL)
|
||||
{
|
||||
CodeHeap *pHeap = pHeapList->pHeap;
|
||||
|
@ -4963,9 +4963,21 @@ void DacDbiInterfaceImpl::Hijack(
|
|||
// Setup context for hijack
|
||||
//
|
||||
T_CONTEXT ctx;
|
||||
#if !defined(CROSS_COMPILE) && !defined(TARGET_WINDOWS) && (defined(DTCONTEXT_IS_AMD64) || defined(DTCONTEXT_IS_ARM64))
|
||||
// If the host or target is not Windows, then we can assume that the DT_CONTEXT
|
||||
// is the same as the T_CONTEXT, except for the XSTATE registers.
|
||||
static_assert(sizeof(DT_CONTEXT) == offsetof(T_CONTEXT, XStateFeaturesMask), "DT_CONTEXT does not include the XSTATE registers");
|
||||
#else
|
||||
// Since Dac + DBI are tightly coupled, context sizes should be the same.
|
||||
static_assert(sizeof(DT_CONTEXT) == sizeof(T_CONTEXT), "DT_CONTEXT size must equal the T_CONTEXT size");
|
||||
#endif
|
||||
HRESULT hr = m_pTarget->GetThreadContext(
|
||||
dwThreadId,
|
||||
CONTEXT_FULL,
|
||||
CONTEXT_FULL | CONTEXT_FLOATING_POINT
|
||||
#ifdef CONTEXT_EXTENDED_REGISTERS
|
||||
| CONTEXT_EXTENDED_REGISTERS
|
||||
#endif
|
||||
,
|
||||
sizeof(DT_CONTEXT),
|
||||
(BYTE*) &ctx);
|
||||
IfFailThrow(hr);
|
||||
|
|
|
@ -169,7 +169,7 @@ extern "C" NTSTATUS OutOfProcessFunctionTableCallbackEx(IN ReadMemoryFunction
|
|||
*ppFunctions = 0;
|
||||
*pnEntries = 0;
|
||||
|
||||
DWORD_PTR pHp = JitMan + (DWORD_PTR)offsetof(FakeEEJitManager, m_pCodeHeap);
|
||||
DWORD_PTR pHp = JitMan + (DWORD_PTR)offsetof(FakeEEJitManager, m_pAllCodeHeaps);
|
||||
|
||||
move(pHp, pHp);
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@ struct FakeEEJitManager
|
|||
{
|
||||
LPVOID __VFN_table;
|
||||
LPVOID m_runtimeSupport;
|
||||
LPVOID m_pCodeHeap;
|
||||
// Nothing after this point matters: we only need the correct offset of m_pCodeHeap.
|
||||
LPVOID m_pAllCodeHeaps;
|
||||
// Nothing after this point matters: we only need the correct offset of m_pAllCodeHeaps.
|
||||
};
|
||||
|
||||
struct FakeHeapList
|
||||
|
@ -76,7 +76,7 @@ class CheckDuplicatedStructLayouts
|
|||
{
|
||||
#define CHECK_OFFSET(cls, fld) CPP_ASSERT(cls##fld, offsetof(Fake##cls, fld) == offsetof(cls, fld))
|
||||
|
||||
CHECK_OFFSET(EEJitManager, m_pCodeHeap);
|
||||
CHECK_OFFSET(EEJitManager, m_pAllCodeHeaps);
|
||||
|
||||
CHECK_OFFSET(HeapList, hpNext);
|
||||
CHECK_OFFSET(HeapList, startAddress);
|
||||
|
|
|
@ -38,9 +38,9 @@ DacGetThread(ULONG32 osThread)
|
|||
UNREACHABLE();
|
||||
}
|
||||
|
||||
// Note that if we had access to TLS, we could get this at index gThreadTLSIndex for the specified
|
||||
// thread. However, this is the only place we might want to use TLS, and it's not performance critical,
|
||||
// so we haven't added TLS support to ICorDebugDataTarget (the legacy ICLRDataTarget interface has it though)
|
||||
// Note that if we had access to TLS, we could get this at TLS for the specified thread. However, this is
|
||||
// the only place we might want to use TLS, and it's not performance critical, so we haven't added TLS support
|
||||
// to ICorDebugDataTarget (the legacy ICLRDataTarget interface has it though)
|
||||
|
||||
// Scan the whole thread store to see if there's a matching thread.
|
||||
|
||||
|
|
|
@ -362,7 +362,7 @@ ClrDataAccess::GetJitManagerList(unsigned int count, struct DacpJitManagerInfo m
|
|||
currentPtr->codeType = managerPtr->GetCodeType();
|
||||
|
||||
EEJitManager *eeJitManager = PTR_EEJitManager(PTR_HOST_TO_TADDR(managerPtr));
|
||||
currentPtr->ptrHeapList = HOST_CDADDR(eeJitManager->m_pCodeHeap);
|
||||
currentPtr->ptrHeapList = HOST_CDADDR(eeJitManager->m_pAllCodeHeaps);
|
||||
}
|
||||
}
|
||||
else if (pNeeded)
|
||||
|
@ -528,7 +528,7 @@ ClrDataAccess::GetCodeHeapList(CLRDATA_ADDRESS jitManager, unsigned int count, s
|
|||
SOSDacEnter();
|
||||
|
||||
EEJitManager *pJitManager = PTR_EEJitManager(TO_TADDR(jitManager));
|
||||
HeapList *heapList = pJitManager->m_pCodeHeap;
|
||||
HeapList *heapList = pJitManager->m_pAllCodeHeaps;
|
||||
|
||||
if (codeHeaps)
|
||||
{
|
||||
|
@ -2434,31 +2434,25 @@ ClrDataAccess::GetAppDomainData(CLRDATA_ADDRESS addr, struct DacpAppDomainData *
|
|||
if (addr != HOST_CDADDR(SystemDomain::System()))
|
||||
{
|
||||
PTR_AppDomain pAppDomain = PTR_AppDomain(TO_TADDR(addr));
|
||||
appdomainData->DomainLocalBlock = 0;
|
||||
appdomainData->pDomainLocalModules = 0;
|
||||
|
||||
appdomainData->dwId = DefaultADID;
|
||||
appdomainData->appDomainStage = (DacpAppDomainDataStage)pAppDomain->m_Stage.Load();
|
||||
if (pAppDomain->IsActive())
|
||||
|
||||
AppDomain::AssemblyIterator i = pAppDomain->IterateAssembliesEx((AssemblyIterationFlags)(
|
||||
kIncludeLoading | kIncludeLoaded | kIncludeExecution));
|
||||
CollectibleAssemblyHolder<Assembly *> pAssembly;
|
||||
|
||||
while (i.Next(pAssembly.This()))
|
||||
{
|
||||
// The assembly list is not valid in a closed appdomain.
|
||||
AppDomain::AssemblyIterator i = pAppDomain->IterateAssembliesEx((AssemblyIterationFlags)(
|
||||
kIncludeLoading | kIncludeLoaded | kIncludeExecution));
|
||||
CollectibleAssemblyHolder<Assembly *> pAssembly;
|
||||
|
||||
while (i.Next(pAssembly.This()))
|
||||
if (pAssembly->IsLoaded())
|
||||
{
|
||||
if (pAssembly->IsLoaded())
|
||||
{
|
||||
appdomainData->AssemblyCount++;
|
||||
}
|
||||
appdomainData->AssemblyCount++;
|
||||
}
|
||||
}
|
||||
|
||||
AppDomain::FailedAssemblyIterator j = pAppDomain->IterateFailedAssembliesEx();
|
||||
while (j.Next())
|
||||
{
|
||||
appdomainData->FailedAssemblyCount++;
|
||||
}
|
||||
AppDomain::FailedAssemblyIterator j = pAppDomain->IterateFailedAssembliesEx();
|
||||
while (j.Next())
|
||||
{
|
||||
appdomainData->FailedAssemblyCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <common.h>
|
||||
#include <codeman.h>
|
||||
#include <debugger.h>
|
||||
#include <walker.h>
|
||||
#include <controller.h>
|
||||
#include <eedbginterfaceimpl.h>
|
||||
#include <methoditer.h>
|
||||
|
|
|
@ -32,10 +32,9 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// In v1.0, we declared that mscordbi was a "shared" component, which means
|
||||
// that we promised to provide it from now until the end of time. So every CLR implementation
|
||||
// needs an Mscordbi that implements the everett guids for CorDebug + CorPublish.
|
||||
// needs an Mscordbi that implements the everett guids for CorDebug
|
||||
//
|
||||
// This works fine for CorPublish, which is truly shared.
|
||||
// CorDebug however is "versioned" not "shared" - each version of the CLR has its own disjoint copy.
|
||||
// CorDebug is "versioned" not "shared" - each version of the CLR has its own disjoint copy.
|
||||
//
|
||||
// Thus creating a CorDebug object requires a version parameter.
|
||||
// CoCreateInstance doesn't have a the version param, so we use the new (v2.0+)
|
||||
|
@ -307,14 +306,6 @@ STDAPI DLLEXPORT DllGetClassObjectInternal( // Return code.
|
|||
CClassFactory *pClassFactory; // To create class factory object.
|
||||
PFN_CREATE_OBJ pfnCreateObject = NULL;
|
||||
|
||||
|
||||
#if defined(FEATURE_DBG_PUBLISH)
|
||||
if (rclsid == CLSID_CorpubPublish)
|
||||
{
|
||||
pfnCreateObject = CorpubPublish::CreateObject;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#if defined(FEATURE_DBGIPC_TRANSPORT_DI)
|
||||
if (rclsid == CLSID_CorDebug_Telesto)
|
||||
{
|
||||
|
|
|
@ -5061,6 +5061,23 @@ void CordbProcess::RawDispatchEvent(
|
|||
|
||||
case DB_IPCE_LOAD_MODULE:
|
||||
{
|
||||
LOG((LF_CORDB, LL_INFO100,
|
||||
"RCET::HRCE: load module (includes assembly loading) on thread %#x Asm:0x%08x AD:0x%08x \n",
|
||||
dwVolatileThreadId,
|
||||
VmPtrToCookie(pEvent->LoadModuleData.vmDomainAssembly),
|
||||
VmPtrToCookie(pEvent->vmAppDomain)));
|
||||
|
||||
_ASSERTE (pAppDomain != NULL);
|
||||
|
||||
// Determine if this Assembly is cached.
|
||||
CordbAssembly * pAssembly = pAppDomain->LookupOrCreateAssembly(pEvent->LoadModuleData.vmDomainAssembly);
|
||||
_ASSERTE(pAssembly != NULL); // throws on error
|
||||
|
||||
// If created, or have, an Assembly, notify callback.
|
||||
{
|
||||
PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
|
||||
hr = pCallback1->LoadAssembly(pAppDomain, pAssembly);
|
||||
}
|
||||
_ASSERTE (pAppDomain != NULL);
|
||||
CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->LoadModuleData.vmDomainAssembly);
|
||||
|
||||
|
@ -5375,29 +5392,6 @@ void CordbProcess::RawDispatchEvent(
|
|||
|
||||
break;
|
||||
|
||||
case DB_IPCE_LOAD_ASSEMBLY:
|
||||
{
|
||||
LOG((LF_CORDB, LL_INFO100,
|
||||
"RCET::HRCE: load assembly on thread %#x Asm:0x%08x AD:0x%08x \n",
|
||||
dwVolatileThreadId,
|
||||
VmPtrToCookie(pEvent->AssemblyData.vmDomainAssembly),
|
||||
VmPtrToCookie(pEvent->vmAppDomain)));
|
||||
|
||||
_ASSERTE (pAppDomain != NULL);
|
||||
|
||||
// Determine if this Assembly is cached.
|
||||
CordbAssembly * pAssembly = pAppDomain->LookupOrCreateAssembly(pEvent->AssemblyData.vmDomainAssembly);
|
||||
_ASSERTE(pAssembly != NULL); // throws on error
|
||||
|
||||
// If created, or have, an Assembly, notify callback.
|
||||
{
|
||||
PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
|
||||
hr = pCallback1->LoadAssembly(pAppDomain, pAssembly);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DB_IPCE_UNLOAD_ASSEMBLY:
|
||||
{
|
||||
LOG((LF_CORDB, LL_INFO100, "RCET::DRCE: unload assembly on thread %#x Asm:0x%x AD:0x%x\n",
|
||||
|
@ -13281,9 +13275,9 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven
|
|||
LOG((LF_CORDB, LL_INFO100000, "W32ET::W32EL: hijack complete will restore context...\n"));
|
||||
DT_CONTEXT tempContext = { 0 };
|
||||
#if defined(DT_CONTEXT_EXTENDED_REGISTERS)
|
||||
tempContext.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_EXTENDED_REGISTERS;
|
||||
tempContext.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_EXTENDED_REGISTERS;
|
||||
#else
|
||||
tempContext.ContextFlags = DT_CONTEXT_FULL;
|
||||
tempContext.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT;
|
||||
#endif
|
||||
HRESULT hr = pUnmanagedThread->GetThreadContext(&tempContext);
|
||||
_ASSERTE(SUCCEEDED(hr));
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -452,7 +452,7 @@ void LeftSideResourceCleanupList::SweepNeuterLeftSideResources(CordbProcess * pP
|
|||
* ------------------------------------------------------------------------- */
|
||||
extern void* GetClrModuleBase();
|
||||
|
||||
// Do any initialization necessary for both CorPublish and CorDebug
|
||||
// Do any initialization necessary for CorDebug
|
||||
// This includes enabling logging and adding the SEDebug priv.
|
||||
void CordbCommonBase::InitializeCommon()
|
||||
{
|
||||
|
|
|
@ -114,13 +114,6 @@ class CordbEval;
|
|||
|
||||
class CordbMDA;
|
||||
|
||||
class CorpubPublish;
|
||||
class CorpubProcess;
|
||||
class CorpubAppDomain;
|
||||
class CorpubProcessEnum;
|
||||
class CorpubAppDomainEnum;
|
||||
|
||||
|
||||
class RSLock;
|
||||
class NeuterList;
|
||||
|
||||
|
@ -1094,11 +1087,11 @@ typedef enum {
|
|||
enumCordbEnCSnapshot, // 21
|
||||
enumCordbEval, // 22
|
||||
enumCordbUnmanagedThread,// 23
|
||||
enumCorpubPublish, // 24
|
||||
enumCorpubProcess, // 25
|
||||
enumCorpubAppDomain, // 26
|
||||
enumCorpubProcessEnum, // 27
|
||||
enumCorpubAppDomainEnum,// 28
|
||||
// unused, // 24
|
||||
// unused, // 25
|
||||
// unused, // 26
|
||||
// unused, // 27
|
||||
// unused, // 28
|
||||
enumCordbEnumFilter, // 29
|
||||
enumCordbEnCErrorInfo, // 30
|
||||
enumCordbEnCErrorInfoEnum,//31
|
||||
|
@ -1157,7 +1150,7 @@ class CordbHashTable;
|
|||
#define CORDB_COMMON_BASE_SIGNATURE 0x0d00d96a
|
||||
#define CORDB_COMMON_BASE_SIGNATURE_DEAD 0x0dead0b1
|
||||
|
||||
// Common base for both CorPublish + CorDebug objects.
|
||||
// Common base for CorDebug objects.
|
||||
class CordbCommonBase : public IUnknown
|
||||
{
|
||||
public:
|
||||
|
@ -10691,12 +10684,6 @@ public:
|
|||
};
|
||||
#endif // FEATURE_INTEROP_DEBUGGING
|
||||
|
||||
|
||||
//********************************************************************************
|
||||
//**************** App Domain Publishing Service API *****************************
|
||||
//********************************************************************************
|
||||
|
||||
|
||||
class EnumElement
|
||||
{
|
||||
public:
|
||||
|
@ -10716,293 +10703,6 @@ private:
|
|||
EnumElement *m_pNext;
|
||||
};
|
||||
|
||||
#if defined(FEATURE_DBG_PUBLISH)
|
||||
|
||||
// Prototype of psapi!GetModuleFileNameEx.
|
||||
typedef DWORD FPGetModuleFileNameEx(HANDLE, HMODULE, LPTSTR, DWORD);
|
||||
|
||||
|
||||
class CorpubPublish : public CordbCommonBase, public ICorPublish
|
||||
{
|
||||
public:
|
||||
CorpubPublish();
|
||||
virtual ~CorpubPublish();
|
||||
|
||||
#ifdef _DEBUG
|
||||
virtual const char * DbgGetName() { return "CordbPublish"; }
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// IUnknown
|
||||
//-----------------------------------------------------------
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
return (BaseAddRef());
|
||||
}
|
||||
ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
return (BaseRelease());
|
||||
}
|
||||
COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// ICorPublish
|
||||
//-----------------------------------------------------------
|
||||
|
||||
COM_METHOD EnumProcesses(
|
||||
COR_PUB_ENUMPROCESS Type,
|
||||
ICorPublishProcessEnum **ppIEnum);
|
||||
|
||||
COM_METHOD GetProcess(
|
||||
unsigned pid,
|
||||
ICorPublishProcess **ppProcess);
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// CreateObject
|
||||
//-----------------------------------------------------------
|
||||
static COM_METHOD CreateObject(REFIID id, void **object)
|
||||
{
|
||||
*object = NULL;
|
||||
|
||||
if (id != IID_IUnknown && id != IID_ICorPublish)
|
||||
return (E_NOINTERFACE);
|
||||
|
||||
CorpubPublish *pCorPub = new (nothrow) CorpubPublish();
|
||||
|
||||
if (pCorPub == NULL)
|
||||
return (E_OUTOFMEMORY);
|
||||
|
||||
*object = (ICorPublish*)pCorPub;
|
||||
pCorPub->AddRef();
|
||||
|
||||
return (S_OK);
|
||||
}
|
||||
|
||||
private:
|
||||
HRESULT GetProcessInternal( unsigned pid, CorpubProcess **ppProcess );
|
||||
|
||||
// Cached information to get the process name. Not available on all platforms, so may be null.
|
||||
HModuleHolder m_hPSAPIdll;
|
||||
FPGetModuleFileNameEx * m_fpGetModuleFileNameEx;
|
||||
};
|
||||
|
||||
class CorpubProcess : public CordbCommonBase, public ICorPublishProcess
|
||||
{
|
||||
public:
|
||||
CorpubProcess(const ProcessDescriptor * pProcessDescriptor,
|
||||
bool fManaged,
|
||||
HANDLE hProcess,
|
||||
HANDLE hMutex,
|
||||
AppDomainEnumerationIPCBlock *pAD,
|
||||
#if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
|
||||
IPCReaderInterface *pIPCReader,
|
||||
#endif // !FEATURE_DBGIPC_TRANSPORT_DI
|
||||
FPGetModuleFileNameEx * fpGetModuleFileNameEx);
|
||||
virtual ~CorpubProcess();
|
||||
|
||||
#ifdef _DEBUG
|
||||
virtual const char * DbgGetName() { return "CorpubProcess"; }
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// IUnknown
|
||||
//-----------------------------------------------------------
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
return (BaseAddRef());
|
||||
}
|
||||
ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
return (BaseRelease());
|
||||
}
|
||||
COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// ICorPublishProcess
|
||||
//-----------------------------------------------------------
|
||||
COM_METHOD IsManaged(BOOL *pbManaged);
|
||||
|
||||
/*
|
||||
* Enumerate the list of known application domains in the target process.
|
||||
*/
|
||||
COM_METHOD EnumAppDomains(ICorPublishAppDomainEnum **ppEnum);
|
||||
|
||||
/*
|
||||
* Returns the OS ID for the process in question.
|
||||
*/
|
||||
COM_METHOD GetProcessID(unsigned *pid);
|
||||
|
||||
/*
|
||||
* Get the display name for a process.
|
||||
*/
|
||||
COM_METHOD GetDisplayName(ULONG32 cchName,
|
||||
ULONG32 *pcchName,
|
||||
_Out_writes_to_opt_(cchName, *pcchName) WCHAR szName[]);
|
||||
|
||||
CorpubProcess *GetNextProcess () { return m_pNext;}
|
||||
void SetNext (CorpubProcess *pNext) { m_pNext = pNext;}
|
||||
|
||||
// Helper to tell if this process has exited
|
||||
bool IsExited();
|
||||
|
||||
public:
|
||||
ProcessDescriptor m_processDescriptor;
|
||||
|
||||
private:
|
||||
bool m_fIsManaged;
|
||||
HANDLE m_hProcess;
|
||||
HANDLE m_hMutex;
|
||||
AppDomainEnumerationIPCBlock *m_AppDomainCB;
|
||||
#if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
|
||||
IPCReaderInterface *m_pIPCReader; // controls the lifetime of the AppDomainEnumerationIPCBlock
|
||||
#endif // !FEATURE_DBGIPC_TRANSPORT_DI
|
||||
CorpubProcess *m_pNext; // pointer to the next process in the process list
|
||||
WCHAR *m_szProcessName;
|
||||
|
||||
};
|
||||
|
||||
class CorpubAppDomain : public CordbCommonBase, public ICorPublishAppDomain
|
||||
{
|
||||
public:
|
||||
CorpubAppDomain (_In_ LPWSTR szAppDomainName, ULONG Id);
|
||||
virtual ~CorpubAppDomain();
|
||||
|
||||
#ifdef _DEBUG
|
||||
virtual const char * DbgGetName() { return "CorpubAppDomain"; }
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// IUnknown
|
||||
//-----------------------------------------------------------
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
return (BaseAddRef());
|
||||
}
|
||||
ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
return (BaseRelease());
|
||||
}
|
||||
COM_METHOD QueryInterface (REFIID riid, void **ppInterface);
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// ICorPublishAppDomain
|
||||
//-----------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Get the name and ID for an application domain.
|
||||
*/
|
||||
COM_METHOD GetID (ULONG32 *pId);
|
||||
|
||||
/*
|
||||
* Get the name for an application domain.
|
||||
*/
|
||||
COM_METHOD GetName (ULONG32 cchName,
|
||||
ULONG32 *pcchName,
|
||||
_Out_writes_to_opt_(cchName, *pcchName) WCHAR szName[]);
|
||||
|
||||
CorpubAppDomain *GetNextAppDomain () { return m_pNext;}
|
||||
void SetNext (CorpubAppDomain *pNext) { m_pNext = pNext;}
|
||||
|
||||
private:
|
||||
CorpubAppDomain *m_pNext;
|
||||
WCHAR *m_szAppDomainName;
|
||||
ULONG m_id;
|
||||
|
||||
};
|
||||
|
||||
class CorpubProcessEnum : public CordbCommonBase, public ICorPublishProcessEnum
|
||||
{
|
||||
public:
|
||||
CorpubProcessEnum(CorpubProcess *pFirst);
|
||||
virtual ~CorpubProcessEnum();
|
||||
|
||||
#ifdef _DEBUG
|
||||
virtual const char * DbgGetName() { return "CorpubProcessEnum"; }
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// IUnknown
|
||||
//-----------------------------------------------------------
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
return (BaseAddRef());
|
||||
}
|
||||
ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
return (BaseRelease());
|
||||
}
|
||||
COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// ICorPublishProcessEnum
|
||||
//-----------------------------------------------------------
|
||||
|
||||
COM_METHOD Skip(ULONG celt);
|
||||
COM_METHOD Reset();
|
||||
COM_METHOD Clone(ICorPublishEnum **ppEnum);
|
||||
COM_METHOD GetCount(ULONG *pcelt);
|
||||
COM_METHOD Next(ULONG celt,
|
||||
ICorPublishProcess *objects[],
|
||||
ULONG *pceltFetched);
|
||||
|
||||
private:
|
||||
CorpubProcess *m_pFirst;
|
||||
CorpubProcess *m_pCurrent;
|
||||
|
||||
};
|
||||
|
||||
class CorpubAppDomainEnum : public CordbCommonBase, public ICorPublishAppDomainEnum
|
||||
{
|
||||
public:
|
||||
CorpubAppDomainEnum(CorpubAppDomain *pFirst);
|
||||
virtual ~CorpubAppDomainEnum();
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
virtual const char * DbgGetName() { return "CordbAppDomainEnum"; }
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// IUnknown
|
||||
//-----------------------------------------------------------
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
return (BaseAddRef());
|
||||
}
|
||||
ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
return (BaseRelease());
|
||||
}
|
||||
COM_METHOD QueryInterface(REFIID riid, void **ppInterface);
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// ICorPublishAppDomainEnum
|
||||
//-----------------------------------------------------------
|
||||
COM_METHOD Skip(ULONG celt);
|
||||
COM_METHOD Reset();
|
||||
COM_METHOD Clone(ICorPublishEnum **ppEnum);
|
||||
COM_METHOD GetCount(ULONG *pcelt);
|
||||
|
||||
COM_METHOD Next(ULONG celt,
|
||||
ICorPublishAppDomain *objects[],
|
||||
ULONG *pceltFetched);
|
||||
|
||||
private:
|
||||
CorpubAppDomain *m_pFirst;
|
||||
CorpubAppDomain *m_pCurrent;
|
||||
|
||||
};
|
||||
|
||||
#endif // defined(FEATURE_DBG_PUBLISH)
|
||||
|
||||
class CordbHeapEnum : public CordbBase, public ICorDebugHeapEnum
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -3706,9 +3706,9 @@ HRESULT CordbUnmanagedThread::SetupFirstChanceHijackForSync()
|
|||
// to avoid getting incomplete information and corrupt the thread context
|
||||
DT_CONTEXT context;
|
||||
#if defined(DT_CONTEXT_EXTENDED_REGISTERS)
|
||||
context.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_EXTENDED_REGISTERS;
|
||||
context.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_EXTENDED_REGISTERS;
|
||||
#else
|
||||
context.ContextFlags = DT_CONTEXT_FULL;
|
||||
context.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT;
|
||||
#endif
|
||||
BOOL succ = DbiGetThreadContext(m_handle, &context);
|
||||
_ASSERTE(succ);
|
||||
|
@ -3719,9 +3719,9 @@ HRESULT CordbUnmanagedThread::SetupFirstChanceHijackForSync()
|
|||
LOG((LF_CORDB, LL_ERROR, "CUT::SFCHFS: DbiGetThreadContext error=0x%x\n", error));
|
||||
}
|
||||
#if defined(DT_CONTEXT_EXTENDED_REGISTERS)
|
||||
GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_EXTENDED_REGISTERS;
|
||||
GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_EXTENDED_REGISTERS;
|
||||
#else
|
||||
GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL;
|
||||
GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT;
|
||||
#endif
|
||||
CORDbgCopyThreadContext(GetHijackCtx(), &context);
|
||||
LOG((LF_CORDB, LL_INFO10000, "CUT::SFCHFS: thread=0x%x Hijacking for sync. Original context is:\n", this));
|
||||
|
|
|
@ -29,7 +29,6 @@ using std::max;
|
|||
#include "ex.h"
|
||||
|
||||
#include "sigparser.h"
|
||||
#include "corpub.h"
|
||||
#include "rspriv.h"
|
||||
|
||||
// This is included to deal with GCC limitations around templates.
|
||||
|
|
|
@ -67,9 +67,79 @@ bool DebuggerControllerPatch::IsSafeForStackTrace()
|
|||
|
||||
}
|
||||
|
||||
#ifndef DACCESS_COMPILE
|
||||
#ifndef FEATURE_EMULATE_SINGLESTEP
|
||||
// returns a pointer to the shared buffer. each call will AddRef() the object
|
||||
// before returning it so callers only need to Release() when they're finished with it.
|
||||
|
||||
//
|
||||
// We have to have a whole separate function for this because you
|
||||
// can't use __try in a function that requires object unwinding...
|
||||
//
|
||||
|
||||
LONG FilterAccessViolation2(LPEXCEPTION_POINTERS ep, PVOID pv)
|
||||
{
|
||||
LIMITED_METHOD_CONTRACT;
|
||||
|
||||
return (ep->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||
? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
// This helper is required because the AVInRuntimeImplOkayHolder can not
|
||||
// be directly placed inside the scope of a PAL_TRY
|
||||
void _CopyInstructionBlockHelper(BYTE* to, const BYTE* from)
|
||||
{
|
||||
AVInRuntimeImplOkayHolder AVOkay;
|
||||
|
||||
// This function only copies the portion of the instruction that follows the
|
||||
// breakpoint opcode, not the breakpoint itself
|
||||
to += CORDbg_BREAK_INSTRUCTION_SIZE;
|
||||
from += CORDbg_BREAK_INSTRUCTION_SIZE;
|
||||
|
||||
// If an AV occurs because we walked off a valid page then we need
|
||||
// to be certain that all bytes on the previous page were copied.
|
||||
// We are certain that we copied enough bytes to contain the instruction
|
||||
// because it must have fit within the valid page.
|
||||
for (int i = 0; i < MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE; i++)
|
||||
{
|
||||
*to++ = *from++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// WARNING: this function skips copying the first CORDbg_BREAK_INSTRUCTION_SIZE bytes by design
|
||||
// See the comment at the callsite in DebuggerPatchSkip::DebuggerPatchSkip for more details on
|
||||
// this
|
||||
void DebuggerControllerPatch::CopyInstructionBlock(BYTE *to, const BYTE* from)
|
||||
{
|
||||
// We wrap the memcpy in an exception handler to handle the
|
||||
// extremely rare case where we're copying an instruction off the
|
||||
// end of a method that is also at the end of a page, and the next
|
||||
// page is unmapped.
|
||||
struct Param
|
||||
{
|
||||
BYTE *to;
|
||||
const BYTE* from;
|
||||
} param;
|
||||
param.to = to;
|
||||
param.from = from;
|
||||
PAL_TRY(Param *, pParam, ¶m)
|
||||
{
|
||||
_CopyInstructionBlockHelper(pParam->to, pParam->from);
|
||||
}
|
||||
PAL_EXCEPT_FILTER(FilterAccessViolation2)
|
||||
{
|
||||
// The whole point is that if we copy up the AV, then
|
||||
// that's enough to execute, otherwise we would not have been
|
||||
// able to execute the code anyway. So we just ignore the
|
||||
// exception.
|
||||
LOG((LF_CORDB, LL_INFO10000,
|
||||
"DCP::CIP: AV copying instruction block ignored.\n"));
|
||||
}
|
||||
PAL_ENDTRY
|
||||
}
|
||||
|
||||
|
||||
// Creates a new shared patch bypass buffer
|
||||
// AddRef() before returning it so callers need to Release() when they're finished with it.
|
||||
SharedPatchBypassBuffer* DebuggerControllerPatch::GetOrCreateSharedPatchBypassBuffer()
|
||||
{
|
||||
CONTRACTL
|
||||
|
@ -79,27 +149,110 @@ SharedPatchBypassBuffer* DebuggerControllerPatch::GetOrCreateSharedPatchBypassBu
|
|||
}
|
||||
CONTRACTL_END;
|
||||
|
||||
if (m_pSharedPatchBypassBuffer == NULL)
|
||||
if (m_pSharedPatchBypassBuffer != NULL)
|
||||
{
|
||||
void *pSharedPatchBypassBufferRX = g_pDebugger->GetInteropSafeExecutableHeap()->Alloc(sizeof(SharedPatchBypassBuffer));
|
||||
#if defined(HOST_OSX) && defined(HOST_ARM64)
|
||||
ExecutableWriterHolder<SharedPatchBypassBuffer> sharedPatchBypassBufferWriterHolder((SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX, sizeof(SharedPatchBypassBuffer));
|
||||
void *pSharedPatchBypassBufferRW = sharedPatchBypassBufferWriterHolder.GetRW();
|
||||
#else // HOST_OSX && HOST_ARM64
|
||||
void *pSharedPatchBypassBufferRW = pSharedPatchBypassBufferRX;
|
||||
#endif // HOST_OSX && HOST_ARM64
|
||||
new (pSharedPatchBypassBufferRW) SharedPatchBypassBuffer();
|
||||
m_pSharedPatchBypassBuffer = (SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX;
|
||||
|
||||
_ASSERTE(m_pSharedPatchBypassBuffer);
|
||||
TRACE_ALLOC(m_pSharedPatchBypassBuffer);
|
||||
m_pSharedPatchBypassBuffer->AddRef();
|
||||
return m_pSharedPatchBypassBuffer;
|
||||
}
|
||||
|
||||
// NOTE: in order to correctly single-step RIP-relative writes on multiple threads we need to set up
|
||||
// a shared buffer with the instruction and a buffer for the RIP-relative value so that all threads
|
||||
// are working on the same copy. as the single-steps complete the modified data in the buffer is
|
||||
// copied back to the real address to ensure proper execution of the program.
|
||||
|
||||
SharedPatchBypassBuffer *pSharedPatchBypassBufferRX = (SharedPatchBypassBuffer*)g_pDebugger->GetInteropSafeExecutableHeap()->Alloc(sizeof(SharedPatchBypassBuffer));
|
||||
#if defined(HOST_OSX) && defined(HOST_ARM64)
|
||||
ExecutableWriterHolder<SharedPatchBypassBuffer> sharedPatchBypassBufferWriterHolder((SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX, sizeof(SharedPatchBypassBuffer));
|
||||
SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = sharedPatchBypassBufferWriterHolder.GetRW();
|
||||
#else // HOST_OSX && HOST_ARM64
|
||||
SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = pSharedPatchBypassBufferRX;
|
||||
#endif // HOST_OSX && HOST_ARM64
|
||||
new (pSharedPatchBypassBufferRW) SharedPatchBypassBuffer();
|
||||
m_pSharedPatchBypassBuffer = (SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX;
|
||||
_ASSERTE(m_pSharedPatchBypassBuffer);
|
||||
TRACE_ALLOC(m_pSharedPatchBypassBuffer);
|
||||
|
||||
m_pSharedPatchBypassBuffer->AddRef();
|
||||
|
||||
BYTE* patchBypassRW = pSharedPatchBypassBufferRW->PatchBypass;
|
||||
BYTE* patchBypassRX = m_pSharedPatchBypassBuffer->PatchBypass;
|
||||
|
||||
LOG((LF_CORDB, LL_INFO10000, "DCP::CSPBB: Patch skip for opcode 0x%.4x at address %p buffer allocated at 0x%.8x\n", this->opcode, this->address, m_pSharedPatchBypassBuffer));
|
||||
|
||||
// CopyInstructionBlock copies all the code bytes except the breakpoint byte(s).
|
||||
_ASSERTE( this->IsBound() );
|
||||
CopyInstructionBlock(patchBypassRW, (const BYTE *)this->address);
|
||||
|
||||
// Technically, we could create a patch skipper for an inactive patch, but we rely on the opcode being
|
||||
// set here.
|
||||
_ASSERTE( this->IsActivated() );
|
||||
CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patchBypassRW, this->opcode);
|
||||
|
||||
LOG((LF_CORDB, LL_EVERYTHING, "DCP::CSPBB: SetInstruction was called\n"));
|
||||
|
||||
//
|
||||
// Look at instruction to get some attributes
|
||||
//
|
||||
InstructionAttribute instrAttrib = { 0 };
|
||||
NativeWalker::DecodeInstructionForPatchSkip(patchBypassRX, &instrAttrib);
|
||||
|
||||
#if defined(TARGET_AMD64)
|
||||
// The code below handles RIP-relative addressing on AMD64. The original implementation made the assumption that
|
||||
// we are only using RIP-relative addressing to access read-only data (see VSW 246145 for more information). This
|
||||
// has since been expanded to handle RIP-relative writes as well.
|
||||
if (instrAttrib.m_dwOffsetToDisp != 0)
|
||||
{
|
||||
_ASSERTE(pSharedPatchBypassBufferRW != NULL);
|
||||
_ASSERTE(instrAttrib.m_cbInstr != 0);
|
||||
|
||||
//
|
||||
// Populate the RIP-relative buffer with the current value if needed
|
||||
//
|
||||
|
||||
BYTE* bufferBypassRW = pSharedPatchBypassBufferRW->BypassBuffer;
|
||||
|
||||
// Overwrite the *signed* displacement.
|
||||
int dwOldDisp = *(int*)(&patchBypassRX[instrAttrib.m_dwOffsetToDisp]);
|
||||
int dwNewDisp = offsetof(SharedPatchBypassBuffer, BypassBuffer) -
|
||||
(offsetof(SharedPatchBypassBuffer, PatchBypass) + instrAttrib.m_cbInstr);
|
||||
*(int*)(&patchBypassRW[instrAttrib.m_dwOffsetToDisp]) = dwNewDisp;
|
||||
|
||||
// This could be an LEA, which we'll just have to change into a MOV and copy the original address.
|
||||
if (((patchBypassRX[0] == 0x4C) || (patchBypassRX[0] == 0x48)) && (patchBypassRX[1] == 0x8d))
|
||||
{
|
||||
patchBypassRW[1] = 0x8b; // MOV reg, mem
|
||||
_ASSERTE((int)sizeof(void*) <= SharedPatchBypassBuffer::cbBufferBypass);
|
||||
*(void**)bufferBypassRW = (void*)(this->address + instrAttrib.m_cbInstr + dwOldDisp);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ASSERTE(instrAttrib.m_cOperandSize <= SharedPatchBypassBuffer::cbBufferBypass);
|
||||
// Copy the data into our buffer.
|
||||
memcpy(bufferBypassRW, this->address + instrAttrib.m_cbInstr + dwOldDisp, instrAttrib.m_cOperandSize);
|
||||
|
||||
if (instrAttrib.m_fIsWrite)
|
||||
{
|
||||
// save the actual destination address and size so when we TriggerSingleStep() we can update the value
|
||||
pSharedPatchBypassBufferRW->RipTargetFixup = (UINT_PTR)(this->address + instrAttrib.m_cbInstr + dwOldDisp);
|
||||
pSharedPatchBypassBufferRW->RipTargetFixupSize = instrAttrib.m_cOperandSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TARGET_AMD64
|
||||
|
||||
m_pSharedPatchBypassBuffer->SetInstructionAttrib(instrAttrib);
|
||||
|
||||
// Since we just created a new buffer of code, but the CPU caches code and may
|
||||
// not be aware of our changes. This should force the CPU to dump any cached
|
||||
// instructions it has in this region and load the new ones from memory
|
||||
FlushInstructionCache(GetCurrentProcess(), patchBypassRW + CORDbg_BREAK_INSTRUCTION_SIZE,
|
||||
MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE);
|
||||
|
||||
return m_pSharedPatchBypassBuffer;
|
||||
}
|
||||
#endif // !FEATURE_EMULATE_SINGLESTEP
|
||||
#endif // !DACCESS_COMPILE
|
||||
|
||||
// @todo - remove all this splicing trash
|
||||
// This Sort/Splice stuff just reorders the patches within a particular chain such
|
||||
|
@ -4509,53 +4662,9 @@ DebuggerPatchSkip::DebuggerPatchSkip(Thread *thread,
|
|||
// the single-step emulation itself.
|
||||
#ifndef FEATURE_EMULATE_SINGLESTEP
|
||||
|
||||
// NOTE: in order to correctly single-step RIP-relative writes on multiple threads we need to set up
|
||||
// a shared buffer with the instruction and a buffer for the RIP-relative value so that all threads
|
||||
// are working on the same copy. as the single-steps complete the modified data in the buffer is
|
||||
// copied back to the real address to ensure proper execution of the program.
|
||||
|
||||
//
|
||||
// Create the shared instruction block. this will also create the shared RIP-relative buffer
|
||||
//
|
||||
|
||||
_ASSERTE(DebuggerController::HasLock());
|
||||
m_pSharedPatchBypassBuffer = patch->GetOrCreateSharedPatchBypassBuffer();
|
||||
#if defined(HOST_OSX) && defined(HOST_ARM64)
|
||||
ExecutableWriterHolder<SharedPatchBypassBuffer> sharedPatchBypassBufferWriterHolder((SharedPatchBypassBuffer*)m_pSharedPatchBypassBuffer, sizeof(SharedPatchBypassBuffer));
|
||||
SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = sharedPatchBypassBufferWriterHolder.GetRW();
|
||||
#else // HOST_OSX && HOST_ARM64
|
||||
SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = m_pSharedPatchBypassBuffer;
|
||||
#endif // HOST_OSX && HOST_ARM64
|
||||
|
||||
BYTE* patchBypassRX = m_pSharedPatchBypassBuffer->PatchBypass;
|
||||
BYTE* patchBypassRW = pSharedPatchBypassBufferRW->PatchBypass;
|
||||
LOG((LF_CORDB, LL_INFO10000, "DPS::DPS: Patch skip for opcode 0x%.4x at address %p buffer allocated at 0x%.8x\n", patch->opcode, patch->address, m_pSharedPatchBypassBuffer));
|
||||
|
||||
// Copy the instruction block over to the patch skip
|
||||
// WARNING: there used to be an issue here because CopyInstructionBlock copied the breakpoint from the
|
||||
// jitted code stream into the patch buffer. Further below CORDbgSetInstruction would correct the
|
||||
// first instruction. This buffer is shared by all threads so if another thread executed the buffer
|
||||
// between this thread's execution of CopyInstructionBlock and CORDbgSetInstruction the wrong
|
||||
// code would be executed. The bug has been fixed by changing CopyInstructionBlock to only copy
|
||||
// the code bytes after the breakpoint.
|
||||
// You might be tempted to stop copying the code at all, however that wouldn't work well with rejit.
|
||||
// If we skip a breakpoint that is sitting at the beginning of a method, then the profiler rejits that
|
||||
// method causing a jump-stamp to be placed, then we skip the breakpoint again, we need to make sure
|
||||
// the 2nd skip executes the new jump-stamp code and not the original method prologue code. Copying
|
||||
// the code every time ensures that we have the most up-to-date version of the code in the buffer.
|
||||
_ASSERTE( patch->IsBound() );
|
||||
CopyInstructionBlock(patchBypassRW, (const BYTE *)patch->address);
|
||||
|
||||
// Technically, we could create a patch skipper for an inactive patch, but we rely on the opcode being
|
||||
// set here.
|
||||
_ASSERTE( patch->IsActivated() );
|
||||
CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patchBypassRW, patch->opcode);
|
||||
|
||||
LOG((LF_CORDB, LL_EVERYTHING, "SetInstruction was called\n"));
|
||||
//
|
||||
// Look at instruction to get some attributes
|
||||
//
|
||||
|
||||
NativeWalker::DecodeInstructionForPatchSkip(patchBypassRX, &(m_instrAttrib));
|
||||
m_instrAttrib = m_pSharedPatchBypassBuffer->GetInstructionAttrib();
|
||||
|
||||
#ifdef OUT_OF_PROCESS_SETTHREADCONTEXT
|
||||
if (g_pDebugInterface->IsOutOfProcessSetContextEnabled() && m_instrAttrib.m_fIsCall)
|
||||
|
@ -4564,51 +4673,6 @@ DebuggerPatchSkip::DebuggerPatchSkip(Thread *thread,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_AMD64)
|
||||
|
||||
// The code below handles RIP-relative addressing on AMD64. The original implementation made the assumption that
|
||||
// we are only using RIP-relative addressing to access read-only data (see VSW 246145 for more information). This
|
||||
// has since been expanded to handle RIP-relative writes as well.
|
||||
if (m_instrAttrib.m_dwOffsetToDisp != 0 && !IsInPlaceSingleStep())
|
||||
{
|
||||
_ASSERTE(m_instrAttrib.m_cbInstr != 0);
|
||||
|
||||
//
|
||||
// Populate the RIP-relative buffer with the current value if needed
|
||||
//
|
||||
|
||||
BYTE* bufferBypassRW = pSharedPatchBypassBufferRW->BypassBuffer;
|
||||
|
||||
// Overwrite the *signed* displacement.
|
||||
int dwOldDisp = *(int*)(&patchBypassRX[m_instrAttrib.m_dwOffsetToDisp]);
|
||||
int dwNewDisp = offsetof(SharedPatchBypassBuffer, BypassBuffer) -
|
||||
(offsetof(SharedPatchBypassBuffer, PatchBypass) + m_instrAttrib.m_cbInstr);
|
||||
*(int*)(&patchBypassRW[m_instrAttrib.m_dwOffsetToDisp]) = dwNewDisp;
|
||||
|
||||
// This could be an LEA, which we'll just have to change into a MOV and copy the original address.
|
||||
if (((patchBypassRX[0] == 0x4C) || (patchBypassRX[0] == 0x48)) && (patchBypassRX[1] == 0x8d))
|
||||
{
|
||||
patchBypassRW[1] = 0x8b; // MOV reg, mem
|
||||
_ASSERTE((int)sizeof(void*) <= SharedPatchBypassBuffer::cbBufferBypass);
|
||||
*(void**)bufferBypassRW = (void*)(patch->address + m_instrAttrib.m_cbInstr + dwOldDisp);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ASSERTE(m_instrAttrib.m_cOperandSize <= SharedPatchBypassBuffer::cbBufferBypass);
|
||||
// Copy the data into our buffer.
|
||||
memcpy(bufferBypassRW, patch->address + m_instrAttrib.m_cbInstr + dwOldDisp, m_instrAttrib.m_cOperandSize);
|
||||
|
||||
if (m_instrAttrib.m_fIsWrite)
|
||||
{
|
||||
// save the actual destination address and size so when we TriggerSingleStep() we can update the value
|
||||
pSharedPatchBypassBufferRW->RipTargetFixup = (UINT_PTR)(patch->address + m_instrAttrib.m_cbInstr + dwOldDisp);
|
||||
pSharedPatchBypassBufferRW->RipTargetFixupSize = m_instrAttrib.m_cOperandSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TARGET_AMD64
|
||||
|
||||
#endif // !FEATURE_EMULATE_SINGLESTEP
|
||||
|
||||
// Signals our thread that the debugger will be manipulating the context
|
||||
|
@ -4672,7 +4736,9 @@ DebuggerPatchSkip::DebuggerPatchSkip(Thread *thread,
|
|||
#else // FEATURE_EMULATE_SINGLESTEP
|
||||
|
||||
#ifdef TARGET_ARM64
|
||||
patchBypassRX = NativeWalker::SetupOrSimulateInstructionForPatchSkip(context, m_pSharedPatchBypassBuffer, (const BYTE *)patch->address, patch->opcode);
|
||||
BYTE* patchBypassRX = NativeWalker::SetupOrSimulateInstructionForPatchSkip(context, m_pSharedPatchBypassBuffer, (const BYTE *)patch->address, patch->opcode);
|
||||
#else
|
||||
BYTE* patchBypassRX = m_pSharedPatchBypassBuffer->PatchBypass;
|
||||
#endif //TARGET_ARM64
|
||||
|
||||
if (!IsInPlaceSingleStep())
|
||||
|
@ -4742,80 +4808,6 @@ void DebuggerPatchSkip::DebuggerDetachClean()
|
|||
#endif // !FEATURE_EMULATE_SINGLESTEP
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// We have to have a whole separate function for this because you
|
||||
// can't use __try in a function that requires object unwinding...
|
||||
//
|
||||
|
||||
LONG FilterAccessViolation2(LPEXCEPTION_POINTERS ep, PVOID pv)
|
||||
{
|
||||
LIMITED_METHOD_CONTRACT;
|
||||
|
||||
return (ep->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||
? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
// This helper is required because the AVInRuntimeImplOkayHolder can not
|
||||
// be directly placed inside the scope of a PAL_TRY
|
||||
void _CopyInstructionBlockHelper(BYTE* to, const BYTE* from)
|
||||
{
|
||||
AVInRuntimeImplOkayHolder AVOkay;
|
||||
|
||||
// This function only copies the portion of the instruction that follows the
|
||||
// breakpoint opcode, not the breakpoint itself
|
||||
to += CORDbg_BREAK_INSTRUCTION_SIZE;
|
||||
from += CORDbg_BREAK_INSTRUCTION_SIZE;
|
||||
|
||||
// If an AV occurs because we walked off a valid page then we need
|
||||
// to be certain that all bytes on the previous page were copied.
|
||||
// We are certain that we copied enough bytes to contain the instruction
|
||||
// because it must have fit within the valid page.
|
||||
for (int i = 0; i < MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE; i++)
|
||||
{
|
||||
*to++ = *from++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// WARNING: this function skips copying the first CORDbg_BREAK_INSTRUCTION_SIZE bytes by design
|
||||
// See the comment at the callsite in DebuggerPatchSkip::DebuggerPatchSkip for more details on
|
||||
// this
|
||||
void DebuggerPatchSkip::CopyInstructionBlock(BYTE *to, const BYTE* from)
|
||||
{
|
||||
// We wrap the memcpy in an exception handler to handle the
|
||||
// extremely rare case where we're copying an instruction off the
|
||||
// end of a method that is also at the end of a page, and the next
|
||||
// page is unmapped.
|
||||
struct Param
|
||||
{
|
||||
BYTE *to;
|
||||
const BYTE* from;
|
||||
} param;
|
||||
param.to = to;
|
||||
param.from = from;
|
||||
PAL_TRY(Param *, pParam, ¶m)
|
||||
{
|
||||
_CopyInstructionBlockHelper(pParam->to, pParam->from);
|
||||
}
|
||||
PAL_EXCEPT_FILTER(FilterAccessViolation2)
|
||||
{
|
||||
// The whole point is that if we copy up the AV, then
|
||||
// that's enough to execute, otherwise we would not have been
|
||||
// able to execute the code anyway. So we just ignore the
|
||||
// exception.
|
||||
LOG((LF_CORDB, LL_INFO10000,
|
||||
"DPS::DPS: AV copying instruction block ignored.\n"));
|
||||
}
|
||||
PAL_ENDTRY
|
||||
|
||||
// We just created a new buffer of code, but the CPU caches code and may
|
||||
// not be aware of our changes. This should force the CPU to dump any cached
|
||||
// instructions it has in this region and load the new ones from memory
|
||||
FlushInstructionCache(GetCurrentProcess(), to + CORDbg_BREAK_INSTRUCTION_SIZE,
|
||||
MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE);
|
||||
}
|
||||
|
||||
TP_RESULT DebuggerPatchSkip::TriggerPatch(DebuggerControllerPatch *patch,
|
||||
Thread *thread,
|
||||
TRIGGER_WHY tyWhy)
|
||||
|
|
|
@ -312,7 +312,11 @@ public:
|
|||
UINT_PTR RipTargetFixup;
|
||||
#endif
|
||||
|
||||
const InstructionAttribute& GetInstructionAttrib() { return m_instrAttrib; }
|
||||
void SetInstructionAttrib(const InstructionAttribute& instrAttrib) { m_instrAttrib = instrAttrib; }
|
||||
|
||||
private:
|
||||
InstructionAttribute m_instrAttrib; // info about the instruction being skipped over
|
||||
const static DWORD SentinelValue = 0xffffffff;
|
||||
LONG m_refCount;
|
||||
};
|
||||
|
@ -550,10 +554,13 @@ public:
|
|||
// Is this patch at a position at which it's safe to take a stack?
|
||||
bool IsSafeForStackTrace();
|
||||
|
||||
#ifndef DACCESS_COMPILE
|
||||
#ifndef FEATURE_EMULATE_SINGLESTEP
|
||||
// gets a pointer to the shared buffer
|
||||
SharedPatchBypassBuffer* GetOrCreateSharedPatchBypassBuffer();
|
||||
|
||||
void CopyInstructionBlock(BYTE *to, const BYTE* from);
|
||||
|
||||
// entry point for general initialization when the controller is being created
|
||||
void Initialize()
|
||||
{
|
||||
|
@ -567,6 +574,7 @@ public:
|
|||
m_pSharedPatchBypassBuffer->Release();
|
||||
}
|
||||
#endif // !FEATURE_EMULATE_SINGLESTEP
|
||||
#endif // !DACCESS_COMPILE
|
||||
|
||||
void LogInstance()
|
||||
{
|
||||
|
@ -1515,8 +1523,6 @@ class DebuggerPatchSkip : public DebuggerController
|
|||
virtual DEBUGGER_CONTROLLER_TYPE GetDCType(void)
|
||||
{ return DEBUGGER_CONTROLLER_PATCH_SKIP; }
|
||||
|
||||
void CopyInstructionBlock(BYTE *to, const BYTE* from);
|
||||
|
||||
void DecodeInstruction(CORDB_ADDRESS_TYPE *code);
|
||||
|
||||
void DebuggerDetachClean();
|
||||
|
|
|
@ -22,12 +22,7 @@
|
|||
|
||||
#ifdef DEBUGGING_SUPPORTED
|
||||
|
||||
extern PTR_ECHash gFCallMethods[FCALL_HASH_SIZE];
|
||||
extern TADDR gLowestFCall;
|
||||
extern TADDR gHighestFCall;
|
||||
extern PCODE g_FCDynamicallyAssignedImplementations[ECall::NUM_DYNAMICALLY_ASSIGNED_FCALL_IMPLEMENTATIONS];
|
||||
extern DWORD gThreadTLSIndex;
|
||||
extern DWORD gAppDomainTLSIndex;
|
||||
extern "C" void STDCALL ThePreStubPatchLabel(void);
|
||||
|
||||
#ifdef FEATURE_COMWRAPPERS
|
||||
|
|
|
@ -926,7 +926,6 @@ Debugger::Debugger()
|
|||
m_jitAttachInProgress(FALSE),
|
||||
m_launchingDebugger(FALSE),
|
||||
m_LoggingEnabled(TRUE),
|
||||
m_pAppDomainCB(NULL),
|
||||
m_dClassLoadCallbackCount(0),
|
||||
m_pModules(NULL),
|
||||
m_RSRequestedSync(FALSE),
|
||||
|
@ -1896,22 +1895,6 @@ HRESULT Debugger::Startup(void)
|
|||
|
||||
InitializeHijackFunctionAddress();
|
||||
|
||||
// Also initialize the AppDomainEnumerationIPCBlock
|
||||
#if !defined(FEATURE_IPCMAN) || defined(FEATURE_DBGIPC_TRANSPORT_VM)
|
||||
m_pAppDomainCB = new (nothrow) AppDomainEnumerationIPCBlock();
|
||||
#else
|
||||
m_pAppDomainCB = g_pIPCManagerInterface->GetAppDomainBlock();
|
||||
#endif
|
||||
|
||||
if (m_pAppDomainCB == NULL)
|
||||
{
|
||||
LOG((LF_CORDB, LL_INFO100, "D::S: Failed to get AppDomain IPC block from IPCManager.\n"));
|
||||
ThrowHR(E_FAIL);
|
||||
}
|
||||
|
||||
hr = InitAppDomainIPC();
|
||||
_ASSERTE(SUCCEEDED(hr)); // throws on error.
|
||||
|
||||
// Allows the debugger (and profiler) diagnostics to be disabled so resources like
|
||||
// the named pipes and semaphores are not created.
|
||||
if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_EnableDiagnostics) == 0)
|
||||
|
@ -1939,7 +1922,7 @@ HRESULT Debugger::Startup(void)
|
|||
#if defined(FEATURE_DBGIPC_TRANSPORT_VM)
|
||||
// Create transport session and initialize it.
|
||||
g_pDbgTransport = new DbgTransportSession();
|
||||
hr = g_pDbgTransport->Init(m_pRCThread->GetDCB(), m_pAppDomainCB);
|
||||
hr = g_pDbgTransport->Init(m_pRCThread->GetDCB());
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ShutdownTransport();
|
||||
|
@ -2286,10 +2269,10 @@ void DebuggerLazyInit::Init()
|
|||
DebuggerLazyInit::~DebuggerLazyInit()
|
||||
{
|
||||
{
|
||||
USHORT cBlobs = m_pMemBlobs.Count();
|
||||
INT32 cBlobs = m_pMemBlobs.Count();
|
||||
void **rgpBlobs = m_pMemBlobs.Table();
|
||||
|
||||
for (int i = 0; i < cBlobs; i++)
|
||||
for (INT32 i = 0; i < cBlobs; i++)
|
||||
{
|
||||
g_pDebugger->ReleaseRemoteBuffer(rgpBlobs[i], false);
|
||||
}
|
||||
|
@ -2406,9 +2389,6 @@ void Debugger::StopDebugger(void)
|
|||
m_pRCThread->AsyncStop();
|
||||
}
|
||||
|
||||
// Also clean up the AppDomain stuff since this is cross-process.
|
||||
TerminateAppDomainIPC ();
|
||||
|
||||
//
|
||||
// Tell the VM to clear out all references to the debugger before we start cleaning up,
|
||||
// so that nothing will reference (accidentally) through the partially cleaned up debugger.
|
||||
|
@ -9180,7 +9160,7 @@ BOOL Debugger::SuspendComplete(bool isEESuspendedForGC)
|
|||
|
||||
//---------------------------------------------------------------------------------------
|
||||
//
|
||||
// Debugger::SendCreateAppDomainEvent - notify the RS of an AppDomain
|
||||
// Debugger::AppDomainCreated - notify the RS of an AppDomain
|
||||
//
|
||||
// Arguments:
|
||||
// pRuntimeAppdomain - pointer to the AppDomain
|
||||
|
@ -9190,18 +9170,13 @@ BOOL Debugger::SuspendComplete(bool isEESuspendedForGC)
|
|||
//
|
||||
// Notes:
|
||||
// This is used to notify the debugger of either a newly created
|
||||
// AppDomain (when fAttaching is FALSE) or of existing AppDomains
|
||||
// at attach time (fAttaching is TRUE). In both cases, this should
|
||||
// AppDomain. This should
|
||||
// be called before any LoadModule/LoadAssembly events are sent for
|
||||
// this domain. Otherwise the RS will get an event for an AppDomain
|
||||
// it doesn't recognize and ASSERT.
|
||||
//
|
||||
// For the non-attach case this means there is no need to enumerate
|
||||
// the assemblies/modules in an AppDomain after sending this event
|
||||
// because we know there won't be any.
|
||||
//
|
||||
|
||||
void Debugger::SendCreateAppDomainEvent(AppDomain * pRuntimeAppDomain)
|
||||
void Debugger::AppDomainCreated(AppDomain * pRuntimeAppDomain)
|
||||
{
|
||||
CONTRACTL
|
||||
{
|
||||
|
@ -9225,8 +9200,6 @@ void Debugger::SendCreateAppDomainEvent(AppDomain * pRuntimeAppDomain)
|
|||
Thread *pThread = g_pEEInterface->GetThread();
|
||||
SENDIPCEVENT_BEGIN(this, pThread);
|
||||
|
||||
|
||||
|
||||
// We may have detached while waiting in LockForEventSending,
|
||||
// in which case we can't send the event.
|
||||
if (CORDebuggerAttached())
|
||||
|
@ -9250,62 +9223,6 @@ void Debugger::SendCreateAppDomainEvent(AppDomain * pRuntimeAppDomain)
|
|||
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// LoadAssembly is called when a new Assembly gets loaded.
|
||||
//
|
||||
void Debugger::LoadAssembly(DomainAssembly * pDomainAssembly)
|
||||
{
|
||||
CONTRACTL
|
||||
{
|
||||
MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
|
||||
MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
|
||||
}
|
||||
CONTRACTL_END;
|
||||
|
||||
if (CORDBUnrecoverableError(this))
|
||||
return;
|
||||
|
||||
LOG((LF_CORDB, LL_INFO100, "D::LA: Load Assembly Asy:0x%p AD:0x%p which:%s\n",
|
||||
pDomainAssembly, AppDomain::GetCurrentDomain(), pDomainAssembly->GetAssembly()->GetDebugName() ));
|
||||
|
||||
if (!CORDebuggerAttached())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Thread *pThread = g_pEEInterface->GetThread();
|
||||
SENDIPCEVENT_BEGIN(this, pThread)
|
||||
|
||||
|
||||
if (CORDebuggerAttached())
|
||||
{
|
||||
// Send a load assembly event to the Right Side.
|
||||
DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer();
|
||||
InitIPCEvent(ipce,
|
||||
DB_IPCE_LOAD_ASSEMBLY,
|
||||
pThread);
|
||||
|
||||
ipce->AssemblyData.vmDomainAssembly.SetRawPtr(pDomainAssembly);
|
||||
|
||||
m_pRCThread->SendIPCEvent();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG((LF_CORDB,LL_INFO1000, "D::LA: Skipping SendIPCEvent because RS detached."));
|
||||
}
|
||||
|
||||
// Stop all Runtime threads
|
||||
if (CORDebuggerAttached())
|
||||
{
|
||||
TrapAllRuntimeThreads();
|
||||
}
|
||||
|
||||
SENDIPCEVENT_END;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// UnloadAssembly is called when a Runtime thread unloads an assembly.
|
||||
//
|
||||
|
@ -9790,43 +9707,31 @@ BOOL Debugger::SendSystemClassLoadUnloadEvent(mdTypeDef classMetadataToken,
|
|||
|
||||
Assembly *pAssembly = classModule->GetAssembly();
|
||||
|
||||
if (!m_pAppDomainCB->Lock())
|
||||
return (FALSE);
|
||||
AppDomain *pAppDomain = GetAppDomain();
|
||||
_ASSERTE(pAppDomain != NULL);
|
||||
|
||||
AppDomainInfo *pADInfo = m_pAppDomainCB->FindFirst();
|
||||
|
||||
while (pADInfo != NULL)
|
||||
// Only notify for app domains where the module has been fully loaded already
|
||||
// We used to make a different check here domain->ContainsAssembly() but that
|
||||
// triggers too early in the loading process. FindDomainAssembly will not become
|
||||
// non-NULL until the module is fully loaded into the domain which is what we
|
||||
// want.
|
||||
if (classModule->GetDomainAssembly() != NULL )
|
||||
{
|
||||
AppDomain *pAppDomain = pADInfo->m_pAppDomain;
|
||||
_ASSERTE(pAppDomain != NULL);
|
||||
// Find the Left Side module that this class belongs in.
|
||||
DebuggerModule* pModule = LookupOrCreateModule(classModule);
|
||||
_ASSERTE(pModule != NULL);
|
||||
|
||||
// Only notify for app domains where the module has been fully loaded already
|
||||
// We used to make a different check here domain->ContainsAssembly() but that
|
||||
// triggers too early in the loading process. FindDomainAssembly will not become
|
||||
// non-NULL until the module is fully loaded into the domain which is what we
|
||||
// want.
|
||||
if (classModule->GetDomainAssembly() != NULL )
|
||||
// Only send a class load event if they're enabled for this module.
|
||||
if (pModule && pModule->ClassLoadCallbacksEnabled())
|
||||
{
|
||||
// Find the Left Side module that this class belongs in.
|
||||
DebuggerModule* pModule = LookupOrCreateModule(classModule);
|
||||
_ASSERTE(pModule != NULL);
|
||||
|
||||
// Only send a class load event if they're enabled for this module.
|
||||
if (pModule && pModule->ClassLoadCallbacksEnabled())
|
||||
{
|
||||
SendClassLoadUnloadEvent(classMetadataToken,
|
||||
pModule,
|
||||
pAssembly,
|
||||
fIsLoadEvent);
|
||||
fRetVal = TRUE;
|
||||
}
|
||||
SendClassLoadUnloadEvent(classMetadataToken,
|
||||
pModule,
|
||||
pAssembly,
|
||||
fIsLoadEvent);
|
||||
fRetVal = TRUE;
|
||||
}
|
||||
|
||||
pADInfo = m_pAppDomainCB->FindNext(pADInfo);
|
||||
}
|
||||
|
||||
m_pAppDomainCB->Unlock();
|
||||
|
||||
return fRetVal;
|
||||
}
|
||||
|
||||
|
@ -12154,10 +12059,10 @@ HRESULT Debugger::ReleaseRemoteBuffer(void *pBuffer, bool removeFromBlobList)
|
|||
// Remove the buffer from the blob list if necessary.
|
||||
if (removeFromBlobList)
|
||||
{
|
||||
USHORT cBlobs = GetMemBlobs()->Count();
|
||||
INT32 cBlobs = GetMemBlobs()->Count();
|
||||
void **rgpBlobs = GetMemBlobs()->Table();
|
||||
|
||||
USHORT i;
|
||||
INT32 i;
|
||||
for (i = 0; i < cBlobs; i++)
|
||||
{
|
||||
if (rgpBlobs[i] == pBuffer)
|
||||
|
@ -14543,399 +14448,6 @@ void Debugger::SendCustomDebuggerNotification(Thread * pThread,
|
|||
SENDIPCEVENT_END;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Add the AppDomain to the list stored in the IPC block. It adds the id and
|
||||
// the name.
|
||||
//
|
||||
// Arguments:
|
||||
// pAppDomain - The runtime app domain object to add.
|
||||
//
|
||||
// Return Value:
|
||||
// S_OK on success, else detailed error code.
|
||||
//
|
||||
HRESULT Debugger::AddAppDomainToIPC(AppDomain *pAppDomain)
|
||||
{
|
||||
CONTRACTL
|
||||
{
|
||||
MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
|
||||
GC_TRIGGERS;
|
||||
MODE_ANY;
|
||||
}
|
||||
CONTRACTL_END;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
LPCWSTR szName = NULL;
|
||||
|
||||
LOG((LF_CORDB, LL_INFO100, "D::AADTIPC: Executing AADTIPC for AppDomain 0x%08x.\n",
|
||||
pAppDomain));
|
||||
|
||||
STRESS_LOG1(LF_CORDB, LL_INFO10000, "D::AADTIPC: AddAppDomainToIPC:%#08x\n",
|
||||
pAppDomain);
|
||||
|
||||
|
||||
|
||||
_ASSERTE(m_pAppDomainCB->m_iTotalSlots > 0);
|
||||
_ASSERTE(m_pAppDomainCB->m_rgListOfAppDomains != NULL);
|
||||
|
||||
{
|
||||
//
|
||||
// We need to synchronize this routine with the attach logic. The "normal"
|
||||
// attach case uses the HelperThread and TrapAllRuntimeThreads to synchronize
|
||||
// the runtime before sending any of the events (including AppDomainCreates)
|
||||
// to the right-side. Thus, we can synchronize with this case by forcing us
|
||||
// to go co-operative. If we were already co-op, then the helper thread will
|
||||
// wait to start the attach until all co-op threads are paused. If we were
|
||||
// pre-emptive, then going co-op will suspend us until the HelperThread finishes.
|
||||
//
|
||||
// The second case is under the IPC event for ATTACHING, which is where there are
|
||||
// zero app domains, so it is considered an 'early attach' case. To synchronize
|
||||
// with this we have to grab and hold the AppDomainDB lock.
|
||||
//
|
||||
|
||||
GCX_COOP();
|
||||
|
||||
// Lock the list
|
||||
if (!m_pAppDomainCB->Lock())
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Get a free entry from the list
|
||||
AppDomainInfo *pAppDomainInfo = m_pAppDomainCB->GetFreeEntry();
|
||||
|
||||
// Function returns NULL if the list is full and a realloc failed.
|
||||
if (!pAppDomainInfo)
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
goto LErrExit;
|
||||
}
|
||||
|
||||
// Now set the AppDomainName.
|
||||
|
||||
/*
|
||||
* TODO :
|
||||
*
|
||||
* Make sure that returning NULL here does not result in a catastrophic
|
||||
* failure.
|
||||
*
|
||||
* GetFriendlyNameNoThrow may call SetFriendlyName, which may call
|
||||
* UpdateAppDomainEntryInIPC. There is no recursive death, however, because
|
||||
* the AppDomainInfo object does not contain a pointer to the app domain
|
||||
* yet.
|
||||
*/
|
||||
szName = pAppDomain->GetFriendlyNameForDebugger();
|
||||
pAppDomainInfo->SetName(szName);
|
||||
|
||||
// Save on to the appdomain pointer
|
||||
pAppDomainInfo->m_pAppDomain = pAppDomain;
|
||||
|
||||
// bump the used slot count
|
||||
m_pAppDomainCB->m_iNumOfUsedSlots++;
|
||||
|
||||
LErrExit:
|
||||
// UnLock the list
|
||||
m_pAppDomainCB->Unlock();
|
||||
|
||||
// Send event to debugger if one is attached.
|
||||
if (CORDebuggerAttached())
|
||||
{
|
||||
SendCreateAppDomainEvent(pAppDomain);
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Remove the AppDomain from the list stored in the IPC block and send an ExitAppDomain
|
||||
* event to the debugger if attached.
|
||||
******************************************************************************/
|
||||
HRESULT Debugger::RemoveAppDomainFromIPC (AppDomain *pAppDomain)
|
||||
{
|
||||
CONTRACTL
|
||||
{
|
||||
MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT;
|
||||
MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT;
|
||||
}
|
||||
CONTRACTL_END;
|
||||
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
LOG((LF_CORDB, LL_INFO100, "D::RADFIPC: Executing RADFIPC for AppDomain 0x%08x.\n",
|
||||
pAppDomain));
|
||||
|
||||
// if none of the slots are occupied, then simply return.
|
||||
if (m_pAppDomainCB->m_iNumOfUsedSlots == 0)
|
||||
return hr;
|
||||
|
||||
// Lock the list
|
||||
if (!m_pAppDomainCB->Lock())
|
||||
return (E_FAIL);
|
||||
|
||||
|
||||
// Look for the entry
|
||||
AppDomainInfo *pADInfo = m_pAppDomainCB->FindEntry(pAppDomain);
|
||||
|
||||
// Shouldn't be trying to remove an appdomain that was never added
|
||||
if (!pADInfo)
|
||||
{
|
||||
// We'd like to assert this, but there is a small window where we may have
|
||||
// called AppDomain::Init (and so it's fair game to call Stop, and hence come here),
|
||||
// but not yet published the app domain.
|
||||
// _ASSERTE(!"D::RADFIPC: trying to remove an AppDomain that was never added");
|
||||
hr = (E_FAIL);
|
||||
goto ErrExit;
|
||||
}
|
||||
|
||||
// Release the entry
|
||||
m_pAppDomainCB->FreeEntry(pADInfo);
|
||||
|
||||
ErrExit:
|
||||
// UnLock the list
|
||||
m_pAppDomainCB->Unlock();
|
||||
|
||||
//
|
||||
// The Debugger expects to never get an unload event for the default AppDomain.
|
||||
//
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Update the AppDomain in the list stored in the IPC block.
|
||||
******************************************************************************/
|
||||
HRESULT Debugger::UpdateAppDomainEntryInIPC(AppDomain *pAppDomain)
|
||||
{
|
||||
CONTRACTL
|
||||
{
|
||||
NOTHROW;
|
||||
if (GetThreadNULLOk()) { GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
|
||||
}
|
||||
CONTRACTL_END;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
LPCWSTR szName = NULL;
|
||||
|
||||
LOG((LF_CORDB, LL_INFO100,
|
||||
"D::UADEIIPC: Executing UpdateAppDomainEntryInIPC ad:0x%x.\n",
|
||||
pAppDomain));
|
||||
|
||||
// if none of the slots are occupied, then simply return.
|
||||
if (m_pAppDomainCB->m_iNumOfUsedSlots == 0)
|
||||
return (E_FAIL);
|
||||
|
||||
// Lock the list
|
||||
if (!m_pAppDomainCB->Lock())
|
||||
return (E_FAIL);
|
||||
|
||||
// Look up the info entry
|
||||
AppDomainInfo *pADInfo = m_pAppDomainCB->FindEntry(pAppDomain);
|
||||
|
||||
if (!pADInfo)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
goto ErrExit;
|
||||
}
|
||||
|
||||
// Update the name only if new name is non-null
|
||||
szName = pADInfo->m_pAppDomain->GetFriendlyNameForDebugger();
|
||||
pADInfo->SetName(szName);
|
||||
|
||||
ErrExit:
|
||||
// UnLock the list
|
||||
m_pAppDomainCB->Unlock();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
******************************************************************************/
|
||||
HRESULT Debugger::InitAppDomainIPC(void)
|
||||
{
|
||||
CONTRACTL
|
||||
{
|
||||
THROWS;
|
||||
GC_NOTRIGGER;
|
||||
|
||||
PRECONDITION(CheckPointer(m_pAppDomainCB));
|
||||
}
|
||||
CONTRACTL_END;
|
||||
|
||||
// Ensure that if we throw here, the Terminate will get called and cleanup all resources.
|
||||
// This will make Init an atomic operation - it either fully inits or fully fails.
|
||||
class EnsureCleanup
|
||||
{
|
||||
Debugger * m_pThis;
|
||||
|
||||
public:
|
||||
EnsureCleanup(Debugger * pThis)
|
||||
{
|
||||
m_pThis = pThis;
|
||||
}
|
||||
|
||||
void SuppressCleanup()
|
||||
{
|
||||
m_pThis = NULL;
|
||||
}
|
||||
|
||||
~EnsureCleanup()
|
||||
{
|
||||
if (m_pThis != NULL)
|
||||
{
|
||||
m_pThis->TerminateAppDomainIPC();
|
||||
}
|
||||
}
|
||||
} hEnsureCleanup(this);
|
||||
|
||||
DWORD dwStrLen = 0;
|
||||
SString szExeName;
|
||||
int i;
|
||||
|
||||
// all fields in the object can be zero initialized.
|
||||
// If we throw, before fully initializing this, then cleanup won't try to free
|
||||
// uninited values.
|
||||
ZeroMemory(m_pAppDomainCB, sizeof(*m_pAppDomainCB));
|
||||
|
||||
// Create a mutex to allow the Left and Right Sides to properly
|
||||
// synchronize. The Right Side will spin until m_hMutex is valid,
|
||||
// then it will acquire it before accessing the data.
|
||||
HandleHolder hMutex(CreateMutex(NULL, TRUE/*hold*/, NULL));
|
||||
if (hMutex == NULL)
|
||||
{
|
||||
ThrowLastError();
|
||||
}
|
||||
if (!m_pAppDomainCB->m_hMutex.SetLocal(hMutex))
|
||||
{
|
||||
ThrowLastError();
|
||||
}
|
||||
hMutex.SuppressRelease();
|
||||
|
||||
m_pAppDomainCB->m_iSizeInBytes = INITIAL_APP_DOMAIN_INFO_LIST_SIZE *
|
||||
sizeof (AppDomainInfo);
|
||||
|
||||
// Number of slots in AppDomainListElement array
|
||||
m_pAppDomainCB->m_rgListOfAppDomains = new AppDomainInfo[INITIAL_APP_DOMAIN_INFO_LIST_SIZE];
|
||||
_ASSERTE(m_pAppDomainCB->m_rgListOfAppDomains != NULL); // throws on oom
|
||||
|
||||
|
||||
m_pAppDomainCB->m_iTotalSlots = INITIAL_APP_DOMAIN_INFO_LIST_SIZE;
|
||||
|
||||
// Initialize each AppDomainListElement
|
||||
for (i = 0; i < INITIAL_APP_DOMAIN_INFO_LIST_SIZE; i++)
|
||||
{
|
||||
m_pAppDomainCB->m_rgListOfAppDomains[i].FreeEntry();
|
||||
}
|
||||
|
||||
// also initialize the process name
|
||||
dwStrLen = WszGetModuleFileName(NULL,
|
||||
szExeName);
|
||||
|
||||
|
||||
// If we couldn't get the name, then use a nice default.
|
||||
if (dwStrLen == 0)
|
||||
{
|
||||
szExeName.Set(W("<NoProcessName>"));
|
||||
dwStrLen = szExeName.GetCount();
|
||||
}
|
||||
|
||||
// If we got the name, copy it into a buffer. dwStrLen is the
|
||||
// count of characters in the name, not including the null
|
||||
// terminator.
|
||||
m_pAppDomainCB->m_szProcessName = new WCHAR[dwStrLen + 1];
|
||||
_ASSERTE(m_pAppDomainCB->m_szProcessName != NULL); // throws on oom
|
||||
|
||||
wcscpy_s(m_pAppDomainCB->m_szProcessName, dwStrLen + 1, szExeName);
|
||||
|
||||
// Add 1 to the string length so the Right Side will copy out the
|
||||
// null terminator, too.
|
||||
m_pAppDomainCB->m_iProcessNameLengthInBytes = (dwStrLen + 1) * sizeof(WCHAR);
|
||||
|
||||
if (m_pAppDomainCB->m_hMutex != NULL)
|
||||
{
|
||||
m_pAppDomainCB->Unlock();
|
||||
}
|
||||
|
||||
hEnsureCleanup.SuppressCleanup();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Uninitialize the AppDomain IPC block
|
||||
* Returns:
|
||||
* S_OK -if fully uninitialized
|
||||
* E_FAIL - if we can't get ownership of the block, and thus no uninitialization
|
||||
* work is done.
|
||||
******************************************************************************/
|
||||
HRESULT Debugger::TerminateAppDomainIPC(void)
|
||||
{
|
||||
CONTRACTL
|
||||
{
|
||||
NOTHROW;
|
||||
GC_NOTRIGGER;
|
||||
}
|
||||
CONTRACTL_END;
|
||||
|
||||
// If we have no AppDomain block, then we can consider it's already terminated.
|
||||
if (m_pAppDomainCB == NULL)
|
||||
return S_OK;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// Lock the list
|
||||
// If there's no mutex, then we're in a partially created state.
|
||||
// This means InitAppDomainIPC failed halfway through. But we're still thread safe
|
||||
// since other threads can't access us if we don't have the mutex.
|
||||
if ((m_pAppDomainCB->m_hMutex != NULL) && !m_pAppDomainCB->Lock())
|
||||
{
|
||||
// The callers don't check our return value, we may want to know when we can't gracefully clean up
|
||||
LOG((LF_CORDB, LL_INFO10, "Debugger::TerminateAppDomainIPC: Failed to get AppDomain IPC lock, not cleaning up.\n"));
|
||||
|
||||
// If the lock is valid, but we can't get it, then we can't really
|
||||
// uninitialize since someone else is using the block.
|
||||
return (E_FAIL);
|
||||
}
|
||||
|
||||
// The shared IPC segment could still be around after the debugger
|
||||
// object has been destroyed during process shutdown. So, reset
|
||||
// the UsedSlots count to 0 so that any out of process clients
|
||||
// enumeratingthe app domains in this process see 0 AppDomains.
|
||||
m_pAppDomainCB->m_iNumOfUsedSlots = 0;
|
||||
m_pAppDomainCB->m_iTotalSlots = 0;
|
||||
|
||||
// Now delete the memory allocated for AppDomainInfo array
|
||||
delete [] m_pAppDomainCB->m_rgListOfAppDomains;
|
||||
m_pAppDomainCB->m_rgListOfAppDomains = NULL;
|
||||
|
||||
delete [] m_pAppDomainCB->m_szProcessName;
|
||||
m_pAppDomainCB->m_szProcessName = NULL;
|
||||
m_pAppDomainCB->m_iProcessNameLengthInBytes = 0;
|
||||
|
||||
// Set the mutex handle to NULL.
|
||||
// If the Right Side acquires the mutex, it will verify
|
||||
// that the handle is still not NULL. If it is, then it knows it
|
||||
// really lost.
|
||||
RemoteHANDLE m = m_pAppDomainCB->m_hMutex;
|
||||
m_pAppDomainCB->m_hMutex.m_hLocal = NULL;
|
||||
|
||||
// And bring us back to a fully uninitialized state.
|
||||
ZeroMemory(m_pAppDomainCB, sizeof(*m_pAppDomainCB));
|
||||
|
||||
// We're done. release and close the mutex. Note that this must be done
|
||||
// after we clear it out above to ensure there is no race condition.
|
||||
if( m != NULL )
|
||||
{
|
||||
VERIFY(ReleaseMutex(m));
|
||||
m.Close();
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
#ifndef DACCESS_COMPILE
|
||||
|
||||
//
|
||||
|
|
|
@ -1116,8 +1116,8 @@ protected:
|
|||
// different part of the address space (not on the heap).
|
||||
// ------------------------------------------------------------------------ */
|
||||
|
||||
constexpr uint64_t DBG_MAX_EXECUTABLE_ALLOC_SIZE=112;
|
||||
constexpr uint64_t EXPECTED_CHUNKSIZE=128;
|
||||
constexpr uint64_t DBG_MAX_EXECUTABLE_ALLOC_SIZE=120; // sizeof (SharedPatchBypassBuffer)
|
||||
constexpr uint64_t EXPECTED_CHUNKSIZE=256; // This must be a power of 2. It represents the size of DebuggerHeapExecutableMemoryChunk, can be the sizeof (DataChunk) or sizeof (BookkeepingChunk). Changes to DBG_MAX_EXECUTABLE_ALLOC_SIZE can affect this number. Currently we require 136 bytes, and so the closest power of 2 is 256.
|
||||
constexpr uint64_t DEBUGGERHEAP_PAGESIZE=4096;
|
||||
constexpr uint64_t CHUNKS_PER_DEBUGGERHEAP=(DEBUGGERHEAP_PAGESIZE / EXPECTED_CHUNKSIZE);
|
||||
constexpr uint64_t MAX_CHUNK_MASK=((1ull << CHUNKS_PER_DEBUGGERHEAP) - 1);
|
||||
|
@ -2617,14 +2617,7 @@ public:
|
|||
BOOL ShouldAutoAttach();
|
||||
BOOL FallbackJITAttachPrompt();
|
||||
|
||||
HRESULT AddAppDomainToIPC (AppDomain *pAppDomain);
|
||||
HRESULT RemoveAppDomainFromIPC (AppDomain *pAppDomain);
|
||||
HRESULT UpdateAppDomainEntryInIPC (AppDomain *pAppDomain);
|
||||
|
||||
void SendCreateAppDomainEvent(AppDomain * pAppDomain);
|
||||
|
||||
// Notify the debugger that an assembly has been loaded
|
||||
void LoadAssembly(DomainAssembly * pDomainAssembly);
|
||||
void AppDomainCreated(AppDomain * pAppDomain);
|
||||
|
||||
// Notify the debugger that an assembly has been unloaded
|
||||
void UnloadAssembly(DomainAssembly * pDomainAssembly);
|
||||
|
@ -2840,9 +2833,6 @@ private:
|
|||
DebuggerLaunchSetting GetDbgJITDebugLaunchSetting();
|
||||
|
||||
public:
|
||||
HRESULT InitAppDomainIPC(void);
|
||||
HRESULT TerminateAppDomainIPC(void);
|
||||
|
||||
bool ResumeThreads(AppDomain* pAppDomain);
|
||||
|
||||
void ProcessAnyPendingEvals(Thread *pThread);
|
||||
|
@ -2923,7 +2913,6 @@ private:
|
|||
Volatile<BOOL> m_jitAttachInProgress;
|
||||
BOOL m_launchingDebugger;
|
||||
BOOL m_LoggingEnabled;
|
||||
AppDomainEnumerationIPCBlock *m_pAppDomainCB;
|
||||
|
||||
LONG m_dClassLoadCallbackCount;
|
||||
|
||||
|
|
|
@ -62,6 +62,8 @@ struct InstructionAttribute
|
|||
}
|
||||
};
|
||||
|
||||
#ifndef DACCESS_COMPILE
|
||||
|
||||
/* ------------------------------------------------------------------------- *
|
||||
* Classes
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
@ -280,4 +282,6 @@ private:
|
|||
};
|
||||
#endif
|
||||
|
||||
#endif // DACCESS_COMPILE
|
||||
|
||||
#endif // WALKER_H_
|
||||
|
|
|
@ -140,239 +140,6 @@ struct RemoteHANDLE {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
// AppDomain publishing server support:
|
||||
// Information about all appdomains in the process will be maintained
|
||||
// in the shared memory block for use by the debugger, etc.
|
||||
// This structure defines the layout of the information that will
|
||||
// be maintained.
|
||||
struct AppDomainEnumerationIPCBlock
|
||||
{
|
||||
// !!! The binary format of this layout must remain the same across versions so that
|
||||
// !!! a V2.0 publisher can inspect a v1.0 app.
|
||||
|
||||
// lock for serialization while manipulating AppDomain list.
|
||||
RemoteHANDLE m_hMutex;
|
||||
|
||||
// Number of slots in AppDomainListElement array
|
||||
int m_iTotalSlots;
|
||||
int m_iNumOfUsedSlots;
|
||||
int m_iLastFreedSlot;
|
||||
int m_iSizeInBytes; // Size of AppDomainInfo in bytes
|
||||
|
||||
// We can use psapi!GetModuleFileNameEx to get the module name.
|
||||
// This provides an alternative.
|
||||
int m_iProcessNameLengthInBytes;
|
||||
WCHAR *m_szProcessName;
|
||||
|
||||
AppDomainInfo *m_rgListOfAppDomains;
|
||||
BOOL m_fLockInvalid;
|
||||
|
||||
|
||||
#ifndef RIGHT_SIDE_COMPILE
|
||||
/*************************************************************************
|
||||
* Locks the list
|
||||
*************************************************************************/
|
||||
BOOL Lock()
|
||||
{
|
||||
DWORD dwRes = WaitForSingleObject(m_hMutex, 3000);
|
||||
if (dwRes == WAIT_TIMEOUT)
|
||||
{
|
||||
// Nobody should get stuck holding this lock.
|
||||
// If we timeout on the wait, then either:
|
||||
// - it's a really bad race and somebody got preempted for a long time
|
||||
// - perhaps somebody's doing a DOS attack and holding onto the mutex.
|
||||
m_fLockInvalid = TRUE;
|
||||
}
|
||||
|
||||
|
||||
// The only time this can happen is if we're in shutdown and a thread
|
||||
// that held this lock is killed. If this happens, assume that this
|
||||
// IPC block is in an invalid state and return FALSE to indicate
|
||||
// that people shouldn't do anything with the block anymore.
|
||||
if (dwRes == WAIT_ABANDONED)
|
||||
{
|
||||
m_fLockInvalid = TRUE;
|
||||
}
|
||||
|
||||
if (m_fLockInvalid)
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
|
||||
return (dwRes == WAIT_OBJECT_0 && !m_fLockInvalid);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Unlocks the list
|
||||
*************************************************************************/
|
||||
void Unlock()
|
||||
{
|
||||
// Lock may or may not be valid at this point. Thus Release may fail,
|
||||
// but we'll just ignore that.
|
||||
ReleaseMutex(m_hMutex);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Gets a free AppDomainInfo entry, and will allocate room if there are
|
||||
* no free slots left.
|
||||
*************************************************************************/
|
||||
AppDomainInfo *GetFreeEntry()
|
||||
{
|
||||
// first check to see if there is space available. If not, then realloc.
|
||||
if (m_iNumOfUsedSlots == m_iTotalSlots)
|
||||
{
|
||||
// need to realloc
|
||||
AppDomainInfo *pTemp =
|
||||
new (nothrow) AppDomainInfo [m_iTotalSlots*2];
|
||||
|
||||
if (pTemp == NULL)
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
memcpy (pTemp, m_rgListOfAppDomains, m_iSizeInBytes);
|
||||
|
||||
delete [] m_rgListOfAppDomains;
|
||||
|
||||
// Initialize the increased portion of the realloced memory
|
||||
int iNewSlotSize = m_iTotalSlots * 2;
|
||||
|
||||
for (int iIndex = m_iTotalSlots; iIndex < iNewSlotSize; iIndex++)
|
||||
pTemp[iIndex].FreeEntry();
|
||||
|
||||
m_rgListOfAppDomains = pTemp;
|
||||
m_iTotalSlots = iNewSlotSize;
|
||||
m_iSizeInBytes *= 2;
|
||||
}
|
||||
|
||||
// Walk the list looking for an empty slot. Start from the last
|
||||
// one which was freed.
|
||||
{
|
||||
int i = m_iLastFreedSlot;
|
||||
|
||||
do
|
||||
{
|
||||
// Pointer to the entry being examined
|
||||
AppDomainInfo *pADInfo = &(m_rgListOfAppDomains[i]);
|
||||
|
||||
// is the slot available?
|
||||
if (pADInfo->IsEmpty())
|
||||
return (pADInfo);
|
||||
|
||||
i = (i + 1) % m_iTotalSlots;
|
||||
|
||||
} while (i != m_iLastFreedSlot);
|
||||
}
|
||||
|
||||
_ASSERTE(!"ADInfo::GetFreeEntry: should never get here.");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Returns an AppDomainInfo slot to the free list.
|
||||
*************************************************************************/
|
||||
void FreeEntry(AppDomainInfo *pADInfo)
|
||||
{
|
||||
_ASSERTE(pADInfo >= m_rgListOfAppDomains &&
|
||||
pADInfo < m_rgListOfAppDomains + m_iSizeInBytes);
|
||||
_ASSERTE(((size_t)pADInfo - (size_t)m_rgListOfAppDomains) %
|
||||
sizeof(AppDomainInfo) == 0);
|
||||
|
||||
// Mark this slot as free
|
||||
pADInfo->FreeEntry();
|
||||
|
||||
#ifdef _DEBUG
|
||||
*pADInfo = {};
|
||||
#endif
|
||||
|
||||
// decrement the used slot count
|
||||
m_iNumOfUsedSlots--;
|
||||
|
||||
// Save the last freed slot.
|
||||
m_iLastFreedSlot = (int)((size_t)pADInfo - (size_t)m_rgListOfAppDomains) /
|
||||
sizeof(AppDomainInfo);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Finds an AppDomainInfo entry corresponding to the AppDomain pointer.
|
||||
* Returns NULL if no such entry exists.
|
||||
*************************************************************************/
|
||||
AppDomainInfo *FindEntry(AppDomain *pAD)
|
||||
{
|
||||
// Walk the list looking for a matching entry
|
||||
for (int i = 0; i < m_iTotalSlots; i++)
|
||||
{
|
||||
AppDomainInfo *pADInfo = &(m_rgListOfAppDomains[i]);
|
||||
|
||||
if (!pADInfo->IsEmpty() &&
|
||||
pADInfo->m_pAppDomain == pAD)
|
||||
return pADInfo;
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Returns the first AppDomainInfo entry in the list. Returns NULL if
|
||||
* no such entry exists.
|
||||
*************************************************************************/
|
||||
AppDomainInfo *FindFirst()
|
||||
{
|
||||
// Walk the list looking for a non-empty entry
|
||||
for (int i = 0; i < m_iTotalSlots; i++)
|
||||
{
|
||||
AppDomainInfo *pADInfo = &(m_rgListOfAppDomains[i]);
|
||||
|
||||
if (!pADInfo->IsEmpty())
|
||||
return pADInfo;
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Returns the next AppDomainInfo entry after pADInfo. Returns NULL if
|
||||
* pADInfo was the last in the list.
|
||||
*************************************************************************/
|
||||
AppDomainInfo *FindNext(AppDomainInfo *pADInfo)
|
||||
{
|
||||
_ASSERTE(pADInfo >= m_rgListOfAppDomains &&
|
||||
pADInfo < m_rgListOfAppDomains + m_iSizeInBytes);
|
||||
_ASSERTE(((size_t)pADInfo - (size_t)m_rgListOfAppDomains) %
|
||||
sizeof(AppDomainInfo) == 0);
|
||||
|
||||
// Walk the list looking for the next non-empty entry
|
||||
for (int i = (int)((size_t)pADInfo - (size_t)m_rgListOfAppDomains)
|
||||
/ sizeof(AppDomainInfo) + 1;
|
||||
i < m_iTotalSlots;
|
||||
i++)
|
||||
{
|
||||
AppDomainInfo *pADInfoTemp = &(m_rgListOfAppDomains[i]);
|
||||
|
||||
if (!pADInfoTemp->IsEmpty())
|
||||
return pADInfoTemp;
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
#endif // RIGHT_SIDE_COMPILE
|
||||
};
|
||||
|
||||
// Enforce the AppDomain IPC block binary layout doesn't change between versions.
|
||||
// Only an issue for x86 since that's the only platform w/ multiple versions.
|
||||
#if defined(TARGET_X86)
|
||||
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_hMutex) == 0x0);
|
||||
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iTotalSlots) == 0x4);
|
||||
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iNumOfUsedSlots) == 0x8);
|
||||
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iLastFreedSlot) == 0xc);
|
||||
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iSizeInBytes) == 0x10);
|
||||
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_iProcessNameLengthInBytes) == 0x14);
|
||||
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_szProcessName) == 0x18);
|
||||
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_rgListOfAppDomains) == 0x1c);
|
||||
static_assert_no_msg(offsetof(AppDomainEnumerationIPCBlock, m_fLockInvalid) == 0x20);
|
||||
#endif
|
||||
|
||||
#endif //DbgAppDomain_H
|
||||
|
||||
|
||||
|
|
|
@ -474,7 +474,7 @@ typedef DECLSPEC_ALIGN(16) struct {
|
|||
|
||||
|
||||
#if !defined(CROSS_COMPILE) && !defined(TARGET_WINDOWS)
|
||||
static_assert(sizeof(DT_CONTEXT) == offsetof(T_CONTEXT, XStateFeaturesMask), "DT_CONTEXT must not include the SVE registers on AMD64");
|
||||
static_assert(sizeof(DT_CONTEXT) == offsetof(T_CONTEXT, XStateFeaturesMask), "DT_CONTEXT must not include the SVE registers on ARM64");
|
||||
#else
|
||||
static_assert(sizeof(DT_CONTEXT) == sizeof(T_CONTEXT), "DT_CONTEXT size must equal the T_CONTEXT size on ARM64");
|
||||
#endif
|
||||
|
|
|
@ -341,7 +341,7 @@ public:
|
|||
#ifdef RIGHT_SIDE_COMPILE
|
||||
HRESULT Init(const ProcessDescriptor& pd, HANDLE hProcessExited);
|
||||
#else
|
||||
HRESULT Init(DebuggerIPCControlBlock * pDCB, AppDomainEnumerationIPCBlock * pADB);
|
||||
HRESULT Init(DebuggerIPCControlBlock * pDCB);
|
||||
#endif // RIGHT_SIDE_COMPILE
|
||||
|
||||
// Drive the session to the SS_Closed state, which will deallocate all remaining transport resources
|
||||
|
@ -426,9 +426,6 @@ public:
|
|||
HRESULT GetDCB(DebuggerIPCControlBlock *pDCB);
|
||||
HRESULT SetDCB(DebuggerIPCControlBlock *pDCB);
|
||||
|
||||
// Read the AppDomain control block on the LS from the RS.
|
||||
HRESULT GetAppDomainCB(AppDomainEnumerationIPCBlock *pADB);
|
||||
|
||||
#endif // RIGHT_SIDE_COMPILE
|
||||
|
||||
private:
|
||||
|
@ -469,7 +466,6 @@ private:
|
|||
MT_WriteMemory, // RS <-> LS : RS wants to write LS memory block (or LS is replying to such a request)
|
||||
MT_GetDCB, // RS <-> LS : RS wants to read LS DCB (or LS is replying to such a request)
|
||||
MT_SetDCB, // RS <-> LS : RS wants to write LS DCB (or LS is replying to such a request)
|
||||
MT_GetAppDomainCB, // RS <-> LS : RS wants to read LS AppDomainCB (or LS is replying to such a request)
|
||||
};
|
||||
|
||||
// Reasons the LS can give for rejecting a session. These codes should *not* be changed other than by
|
||||
|
@ -589,7 +585,6 @@ private:
|
|||
LONG m_cSentWriteMemory;
|
||||
LONG m_cSentGetDCB;
|
||||
LONG m_cSentSetDCB;
|
||||
LONG m_cSentGetAppDomainCB;
|
||||
LONG m_cSentDDMessage;
|
||||
|
||||
// Message type counts for receives.
|
||||
|
@ -603,7 +598,6 @@ private:
|
|||
LONG m_cReceivedWriteMemory;
|
||||
LONG m_cReceivedGetDCB;
|
||||
LONG m_cReceivedSetDCB;
|
||||
LONG m_cReceivedGetAppDomainCB;
|
||||
LONG m_cReceivedDDMessage;
|
||||
|
||||
// Low level block counts.
|
||||
|
@ -747,7 +741,6 @@ private:
|
|||
// The LS requires the addresses of a couple of runtime data structures in order to service MT_GetDCB etc.
|
||||
// These are provided by the runtime at initialization time.
|
||||
DebuggerIPCControlBlock *m_pDCB;
|
||||
AppDomainEnumerationIPCBlock *m_pADB;
|
||||
#endif // !RIGHT_SIDE_COMPILE
|
||||
|
||||
HRESULT SendEventWorker(DebuggerIPCEvent * pEvent, IPCEventType type);
|
||||
|
|
|
@ -18,7 +18,7 @@ extern const uintptr_t contractDescriptorPointerData[];
|
|||
const uintptr_t contractDescriptorPointerData[] = {
|
||||
(uintptr_t)0, // placeholder
|
||||
#define CDAC_GLOBAL_POINTER(name,value) (uintptr_t)(value),
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ struct CDacStringPoolSizes
|
|||
#define CDAC_GLOBAL_POINTER(name,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name))
|
||||
#define CDAC_GLOBAL(name,tyname,value) DECL_LEN(MAKE_GLOBALLEN_NAME(name), sizeof(#name)) \
|
||||
DECL_LEN(MAKE_GLOBALTYPELEN_NAME(name), sizeof(#tyname))
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
char cdac_string_pool_trailing_nil;
|
||||
#undef DECL_LEN
|
||||
};
|
||||
|
@ -107,7 +107,7 @@ enum
|
|||
CDacBlobTypesCount =
|
||||
#define CDAC_TYPES_BEGIN() 0
|
||||
#define CDAC_TYPE_BEGIN(name) + 1
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
};
|
||||
|
||||
// count the field pool size.
|
||||
|
@ -118,7 +118,7 @@ enum
|
|||
#define CDAC_TYPES_BEGIN() 1
|
||||
#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) + 1
|
||||
#define CDAC_TYPE_END(name) + 1
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
};
|
||||
|
||||
// count the literal globals
|
||||
|
@ -127,7 +127,7 @@ enum
|
|||
CDacBlobGlobalLiteralsCount =
|
||||
#define CDAC_GLOBALS_BEGIN() 0
|
||||
#define CDAC_GLOBAL(name,tyname,value) + 1
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
};
|
||||
|
||||
// count the aux vector globals
|
||||
|
@ -136,7 +136,7 @@ enum
|
|||
CDacBlobGlobalPointersCount =
|
||||
#define CDAC_GLOBALS_BEGIN() 0
|
||||
#define CDAC_GLOBAL_POINTER(name,value) + 1
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
};
|
||||
|
||||
// count the global strings
|
||||
|
@ -145,7 +145,7 @@ enum
|
|||
CDacBlobGlobalStringsCount =
|
||||
#define CDAC_GLOBALS_BEGIN() 0
|
||||
#define CDAC_GLOBAL_STRING(name,value) + 1
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
};
|
||||
|
||||
|
||||
|
@ -175,7 +175,7 @@ struct CDacFieldsPoolSizes
|
|||
#define CDAC_TYPE_FIELD(tyname,membertyname,membername,offset) DECL_LEN(CONCAT4(cdac_fields_pool_member__, tyname, __, membername))
|
||||
#define CDAC_TYPE_END(name) DECL_LEN(CONCAT4(cdac_fields_pool_member__, tyname, _, endmarker)) \
|
||||
} MAKE_TYPEFIELDS_TYNAME(name);
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
#undef DECL_LEN
|
||||
};
|
||||
|
||||
|
@ -197,7 +197,7 @@ struct CDacGlobalPointerIndex
|
|||
#define DECL_LEN(membername) char membername;
|
||||
#define CDAC_GLOBALS_BEGIN() DECL_LEN(cdac_global_pointer_index_start_placeholder__)
|
||||
#define CDAC_GLOBAL_POINTER(name,value) DECL_LEN(CONCAT(cdac_global_pointer_index__, name))
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
#undef DECL_LEN
|
||||
};
|
||||
|
||||
|
@ -295,7 +295,7 @@ struct MagicAndBlob BlobDataDescriptor = {
|
|||
#define CDAC_TYPE_INDETERMINATE(name) /*.Size = */ 0,
|
||||
#define CDAC_TYPE_SIZE(size) /* .Size = */ size,
|
||||
#define CDAC_TYPE_END(name) },
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
},
|
||||
|
||||
/* .FieldsPool = */ {
|
||||
|
@ -306,22 +306,22 @@ struct MagicAndBlob BlobDataDescriptor = {
|
|||
/* .FieldOffset = */ offset, \
|
||||
},
|
||||
#define CDAC_TYPE_END(name) { 0, },
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
},
|
||||
|
||||
/* .GlobalLiteralValues = */ {
|
||||
#define CDAC_GLOBAL(name,tyname,value) { /*.Name = */ GET_GLOBAL_NAME(name), /* .TypeName = */ GET_GLOBALTYPE_NAME(name), /* .Value = */ value },
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
},
|
||||
|
||||
/* .GlobalPointerValues = */ {
|
||||
#define CDAC_GLOBAL_POINTER(name,value) { /* .Name = */ GET_GLOBAL_NAME(name), /* .PointerDataIndex = */ GET_GLOBAL_POINTER_INDEX(name) },
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
},
|
||||
|
||||
/* .GlobalStringValues = */ {
|
||||
#define CDAC_GLOBAL_STRING(name,value) { /* .Name = */ GET_GLOBAL_NAME(name), /* .Value = */ GET_GLOBALSTRING_VALUE(name) },
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
},
|
||||
|
||||
/* .NamesPool = */ ("\0" // starts with a nul
|
||||
|
@ -331,7 +331,7 @@ struct MagicAndBlob BlobDataDescriptor = {
|
|||
#define CDAC_GLOBAL_STRING(name,value) #name "\0" STRINGIFY(value) "\0"
|
||||
#define CDAC_GLOBAL_POINTER(name,value) #name "\0"
|
||||
#define CDAC_GLOBAL(name,tyname,value) #name "\0" #tyname "\0"
|
||||
#include "datadescriptor.h"
|
||||
#include "datadescriptor.inc"
|
||||
),
|
||||
|
||||
/* .EndMagic = */ { 0x01, 0x02, 0x03, 0x04 },
|
||||
|
|
|
@ -258,13 +258,22 @@ CDAC_TYPE_END(Assembly)
|
|||
CDAC_TYPE_BEGIN(LoaderAllocator)
|
||||
CDAC_TYPE_INDETERMINATE(LoaderAllocator)
|
||||
CDAC_TYPE_FIELD(LoaderAllocator, /*uint32*/, ReferenceCount, cdac_data<LoaderAllocator>::ReferenceCount)
|
||||
CDAC_TYPE_FIELD(LoaderAllocator, /*pointer*/, HighFrequencyHeap, cdac_data<LoaderAllocator>::HighFrequencyHeap)
|
||||
CDAC_TYPE_FIELD(LoaderAllocator, /*pointer*/, LowFrequencyHeap, cdac_data<LoaderAllocator>::LowFrequencyHeap)
|
||||
CDAC_TYPE_FIELD(LoaderAllocator, /*pointer*/, StubHeap, cdac_data<LoaderAllocator>::StubHeap)
|
||||
CDAC_TYPE_END(LoaderAllocator)
|
||||
|
||||
CDAC_TYPE_BEGIN(PEAssembly)
|
||||
CDAC_TYPE_INDETERMINATE(PEAssembly)
|
||||
CDAC_TYPE_FIELD(PEAssembly, /*pointer*/, PEImage, cdac_data<PEAssembly>::PEImage)
|
||||
CDAC_TYPE_FIELD(PEAssembly, /*pointer*/, AssemblyBinder, cdac_data<PEAssembly>::AssemblyBinder)
|
||||
CDAC_TYPE_END(PEAssembly)
|
||||
|
||||
CDAC_TYPE_BEGIN(AssemblyBinder)
|
||||
CDAC_TYPE_INDETERMINATE(AssemblyBinder)
|
||||
CDAC_TYPE_FIELD(AssemblyBinder, /*pointer*/, ManagedAssemblyLoadContext, cdac_data<AssemblyBinder>::ManagedAssemblyLoadContext)
|
||||
CDAC_TYPE_END(AssemblyBinder)
|
||||
|
||||
CDAC_TYPE_BEGIN(PEImage)
|
||||
CDAC_TYPE_INDETERMINATE(PEImage)
|
||||
CDAC_TYPE_FIELD(PEImage, /*pointer*/, LoadedImageLayout, cdac_data<PEImage>::LoadedImageLayout)
|
||||
|
@ -292,8 +301,14 @@ CDAC_TYPE_BEGIN(AppDomain)
|
|||
CDAC_TYPE_INDETERMINATE(AppDomain)
|
||||
CDAC_TYPE_FIELD(AppDomain, /*pointer*/, RootAssembly, cdac_data<AppDomain>::RootAssembly)
|
||||
CDAC_TYPE_FIELD(AppDomain, /*DomainAssemblyList*/, DomainAssemblyList, cdac_data<AppDomain>::DomainAssemblyList)
|
||||
CDAC_TYPE_FIELD(AppDomain, /*pointer*/, FriendlyName, cdac_data<AppDomain>::FriendlyName)
|
||||
CDAC_TYPE_END(AppDomain)
|
||||
|
||||
CDAC_TYPE_BEGIN(SystemDomain)
|
||||
CDAC_TYPE_INDETERMINATE(SystemDomain)
|
||||
CDAC_TYPE_FIELD(SystemDomain, /*GlobalLoaderAllocator*/, GlobalLoaderAllocator, cdac_data<SystemDomain>::GlobalLoaderAllocator)
|
||||
CDAC_TYPE_END(SystemDomain)
|
||||
|
||||
CDAC_TYPE_BEGIN(ArrayListBase)
|
||||
CDAC_TYPE_INDETERMINATE(ArrayListBase)
|
||||
CDAC_TYPE_FIELD(ArrayListBase, /*uint32*/, Count, cdac_data<ArrayListBase>::Count)
|
||||
|
@ -333,8 +348,12 @@ CDAC_TYPE_BEGIN(EEClass)
|
|||
CDAC_TYPE_INDETERMINATE(EEClass)
|
||||
CDAC_TYPE_FIELD(EEClass, /*pointer*/, MethodTable, cdac_data<EEClass>::MethodTable)
|
||||
CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumMethods, cdac_data<EEClass>::NumMethods)
|
||||
CDAC_TYPE_FIELD(EEClass, /*pointer*/, FieldDescList, cdac_data<EEClass>::FieldDescList)
|
||||
CDAC_TYPE_FIELD(EEClass, /*uint32*/, CorTypeAttr, cdac_data<EEClass>::CorTypeAttr)
|
||||
CDAC_TYPE_FIELD(EEClass, /*uint8*/, InternalCorElementType, cdac_data<EEClass>::InternalCorElementType)
|
||||
CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumInstanceFields, cdac_data<EEClass>::NumInstanceFields)
|
||||
CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumStaticFields, cdac_data<EEClass>::NumStaticFields)
|
||||
CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumThreadStaticFields, cdac_data<EEClass>::NumThreadStaticFields)
|
||||
CDAC_TYPE_FIELD(EEClass, /*uint16*/, NumNonVirtualSlots, cdac_data<EEClass>::NumNonVirtualSlots)
|
||||
CDAC_TYPE_END(EEClass)
|
||||
|
||||
|
@ -927,7 +946,7 @@ CDAC_GLOBAL_STRING(RID, RID_STRING)
|
|||
CDAC_GLOBAL(GCInfoVersion, uint32, GCINFO_VERSION)
|
||||
|
||||
CDAC_GLOBAL_POINTER(AppDomain, &AppDomain::m_pTheAppDomain)
|
||||
CDAC_GLOBAL_POINTER(SystemDomain, cdac_data<SystemDomain>::SystemDomain)
|
||||
CDAC_GLOBAL_POINTER(SystemDomain, cdac_data<SystemDomain>::SystemDomainPtr)
|
||||
CDAC_GLOBAL_POINTER(ThreadStore, &ThreadStore::s_pThreadStore)
|
||||
CDAC_GLOBAL_POINTER(FinalizerThread, &::g_pFinalizerThread)
|
||||
CDAC_GLOBAL_POINTER(GCThread, &::g_pSuspensionThread)
|
||||
|
@ -959,6 +978,9 @@ CDAC_GLOBAL(MethodDescAlignment, uint64, MethodDesc::ALIGNMENT)
|
|||
CDAC_GLOBAL(ObjectHeaderSize, uint64, OBJHEADER_SIZE)
|
||||
CDAC_GLOBAL(SyncBlockValueToObjectOffset, uint16, OBJHEADER_SIZE - cdac_data<ObjHeader>::SyncBlockValue)
|
||||
CDAC_GLOBAL(StubCodeBlockLast, uint8, STUB_CODE_BLOCK_LAST)
|
||||
CDAC_GLOBAL(DefaultADID, uint32, DefaultADID)
|
||||
CDAC_GLOBAL(MaxClrNotificationArgs, uint32, MAX_CLR_NOTIFICATION_ARGS)
|
||||
CDAC_GLOBAL_POINTER(ClrNotificationArguments, &::g_clrNotificationArguments)
|
||||
CDAC_GLOBAL_POINTER(ArrayBoundsZero, cdac_data<ArrayBase>::ArrayBoundsZero)
|
||||
CDAC_GLOBAL_POINTER(ExceptionMethodTable, &::g_pExceptionClass)
|
||||
CDAC_GLOBAL_POINTER(FreeObjectMethodTable, &::g_pFreeObjectMethodTable)
|
||||
|
@ -968,6 +990,11 @@ CDAC_GLOBAL_POINTER(StringMethodTable, &::g_pStringClass)
|
|||
CDAC_GLOBAL_POINTER(SyncTableEntries, &::g_pSyncTable)
|
||||
CDAC_GLOBAL_POINTER(MiniMetaDataBuffAddress, &::g_MiniMetaDataBuffAddress)
|
||||
CDAC_GLOBAL_POINTER(MiniMetaDataBuffMaxSize, &::g_MiniMetaDataBuffMaxSize)
|
||||
CDAC_GLOBAL_POINTER(DacNotificationFlags, &::g_dacNotificationFlags)
|
||||
CDAC_GLOBAL_POINTER(OffsetOfCurrentThreadInfo, &::g_offsetOfCurrentThreadInfo)
|
||||
#ifdef TARGET_WINDOWS
|
||||
CDAC_GLOBAL_POINTER(TlsIndexBase, &::_tls_index)
|
||||
#endif // TARGET_WINDOWS
|
||||
#ifdef STRESS_LOG
|
||||
CDAC_GLOBAL(StressLogEnabled, uint8, 1)
|
||||
CDAC_GLOBAL_POINTER(StressLog, &g_pStressLog)
|
|
@ -67,7 +67,7 @@ DbgTransportSession::~DbgTransportSession()
|
|||
#ifdef RIGHT_SIDE_COMPILE
|
||||
HRESULT DbgTransportSession::Init(const ProcessDescriptor& pd, HANDLE hProcessExited)
|
||||
#else // RIGHT_SIDE_COMPILE
|
||||
HRESULT DbgTransportSession::Init(DebuggerIPCControlBlock *pDCB, AppDomainEnumerationIPCBlock *pADB)
|
||||
HRESULT DbgTransportSession::Init(DebuggerIPCControlBlock *pDCB)
|
||||
#endif // RIGHT_SIDE_COMPILE
|
||||
{
|
||||
_ASSERTE(m_eState == SS_Closed);
|
||||
|
@ -111,7 +111,6 @@ HRESULT DbgTransportSession::Init(DebuggerIPCControlBlock *pDCB, AppDomainEnumer
|
|||
m_fDebuggerAttached = false;
|
||||
#else // RIGHT_SIDE_COMPILE
|
||||
m_pDCB = pDCB;
|
||||
m_pADB = pADB;
|
||||
#endif // RIGHT_SIDE_COMPILE
|
||||
|
||||
m_sStateLock.Init();
|
||||
|
@ -555,17 +554,6 @@ HRESULT DbgTransportSession::SetDCB(DebuggerIPCControlBlock *pDCB)
|
|||
|
||||
}
|
||||
|
||||
// Read the AppDomain control block on the LS from the RS.
|
||||
HRESULT DbgTransportSession::GetAppDomainCB(AppDomainEnumerationIPCBlock *pADB)
|
||||
{
|
||||
DbgTransportLog(LC_Requests, "Sending 'GetAppDomainCB'");
|
||||
DBG_TRANSPORT_INC_STAT(SentGetAppDomainCB);
|
||||
|
||||
Message sMessage;
|
||||
sMessage.Init(MT_GetAppDomainCB, NULL, 0, (PBYTE)pADB, sizeof(AppDomainEnumerationIPCBlock));
|
||||
return SendRequestMessageAndWait(&sMessage);
|
||||
}
|
||||
|
||||
#endif // RIGHT_SIDE_COMPILE
|
||||
|
||||
// Worker function for code:DbgTransportSession::SendEvent and code:DbgTransportSession::SendDebugEvent.
|
||||
|
@ -948,8 +936,7 @@ void DbgTransportSession::FlushSendQueue(DWORD dwLastProcessedId)
|
|||
if (eType != MT_ReadMemory &&
|
||||
eType != MT_WriteMemory &&
|
||||
eType != MT_GetDCB &&
|
||||
eType != MT_SetDCB &&
|
||||
eType != MT_GetAppDomainCB)
|
||||
eType != MT_SetDCB)
|
||||
#endif // RIGHT_SIDE_COMPILE
|
||||
{
|
||||
#ifdef RIGHT_SIDE_COMPILE
|
||||
|
@ -1658,8 +1645,7 @@ void DbgTransportSession::TransportWorker()
|
|||
|
||||
// Since we care about security here, perform some additional validation checks that make it
|
||||
// harder for a malicious sender to attack with random message data.
|
||||
if (sReceiveHeader.m_eType > MT_GetAppDomainCB ||
|
||||
(sReceiveHeader.m_dwId <= m_dwLastMessageIdSeen &&
|
||||
if ((sReceiveHeader.m_dwId <= m_dwLastMessageIdSeen &&
|
||||
sReceiveHeader.m_dwId != (DWORD)0) ||
|
||||
(sReceiveHeader.m_dwReplyId >= m_dwNextMessageId &&
|
||||
sReceiveHeader.m_dwReplyId != (DWORD)0) ||
|
||||
|
@ -1974,17 +1960,6 @@ void DbgTransportSession::TransportWorker()
|
|||
#endif // RIGHT_SIDE_COMPILE
|
||||
break;
|
||||
|
||||
case MT_GetAppDomainCB:
|
||||
#ifdef RIGHT_SIDE_COMPILE
|
||||
if (!ProcessReply(&sReceiveHeader))
|
||||
HANDLE_TRANSIENT_ERROR();
|
||||
#else // RIGHT_SIDE_COMPILE
|
||||
fReplyRequired = true;
|
||||
pbOptReplyData = (PBYTE)m_pADB;
|
||||
cbOptReplyData = sizeof(AppDomainEnumerationIPCBlock);
|
||||
#endif // RIGHT_SIDE_COMPILE
|
||||
break;
|
||||
|
||||
default:
|
||||
_ASSERTE(!"Unknown message type");
|
||||
HANDLE_CRITICAL_ERROR();
|
||||
|
@ -2089,7 +2064,6 @@ void DbgTransportSession::TransportWorker()
|
|||
case MT_WriteMemory:
|
||||
case MT_GetDCB:
|
||||
case MT_SetDCB:
|
||||
case MT_GetAppDomainCB:
|
||||
// On the RS these are the original requests. Signal the completion event.
|
||||
SignalReplyEvent(pMsg);
|
||||
break;
|
||||
|
@ -2098,7 +2072,6 @@ void DbgTransportSession::TransportWorker()
|
|||
case MT_WriteMemory:
|
||||
case MT_GetDCB:
|
||||
case MT_SetDCB:
|
||||
case MT_GetAppDomainCB:
|
||||
// On the LS these are replies to the original request. Nobody's waiting on these.
|
||||
break;
|
||||
#endif // RIGHT_SIDE_COMPILE
|
||||
|
@ -2501,8 +2474,6 @@ const char *DbgTransportSession::MessageName(MessageType eType)
|
|||
return "GetDCB";
|
||||
case MT_SetDCB:
|
||||
return "SetDCB";
|
||||
case MT_GetAppDomainCB:
|
||||
return "GetAppDomainCB";
|
||||
default:
|
||||
_ASSERTE(!"Unknown message type");
|
||||
return NULL;
|
||||
|
@ -2561,10 +2532,6 @@ void DbgTransportSession::DbgTransportLogMessageReceived(MessageHeader *pHeader)
|
|||
DbgTransportLog(LC_Requests, "Received 'SetDCB' reply");
|
||||
DBG_TRANSPORT_INC_STAT(ReceivedSetDCB);
|
||||
return;
|
||||
case MT_GetAppDomainCB:
|
||||
DbgTransportLog(LC_Requests, "Received 'GetAppDomainCB' reply");
|
||||
DBG_TRANSPORT_INC_STAT(ReceivedGetAppDomainCB);
|
||||
return;
|
||||
#else // RIGHT_SIDE_COMPILE
|
||||
case MT_ReadMemory:
|
||||
DbgTransportLog(LC_Requests, "Received 'ReadMemory(0x%08X, %u)'",
|
||||
|
@ -2586,10 +2553,6 @@ void DbgTransportSession::DbgTransportLogMessageReceived(MessageHeader *pHeader)
|
|||
DbgTransportLog(LC_Requests, "Received 'SetDCB'");
|
||||
DBG_TRANSPORT_INC_STAT(ReceivedSetDCB);
|
||||
return;
|
||||
case MT_GetAppDomainCB:
|
||||
DbgTransportLog(LC_Requests, "Received 'GetAppDomainCB'");
|
||||
DBG_TRANSPORT_INC_STAT(ReceivedGetAppDomainCB);
|
||||
return;
|
||||
#endif // RIGHT_SIDE_COMPILE
|
||||
default:
|
||||
_ASSERTE(!"Unknown message type");
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
LIBRARY mscordbi
|
||||
|
||||
EXPORTS
|
||||
// COM-instantiation - for CorPublish
|
||||
// COM-instantiation
|
||||
DllGetClassObjectInternal private
|
||||
|
||||
// In-proc (Whidbey-style) creation path from the shim - CDIFV and it's replacement
|
||||
|
|
|
@ -56,23 +56,28 @@ endif (CLR_CMAKE_HOST_WIN32)
|
|||
|
||||
add_definitions(-DFX_VER_INTERNALNAME_STR=CoreCLR.dll)
|
||||
|
||||
add_library_clr(coreclr
|
||||
SHARED
|
||||
${CLR_SOURCES}
|
||||
)
|
||||
if (NOT CLR_CMAKE_HOST_ARCH_WASM)
|
||||
add_library_clr(coreclr
|
||||
SHARED
|
||||
${CLR_SOURCES}
|
||||
)
|
||||
|
||||
add_custom_target(coreclr_exports DEPENDS ${EXPORTS_FILE})
|
||||
add_custom_target(coreclr_def DEPENDS ${DEF_FILE})
|
||||
add_custom_target(coreclr_exports DEPENDS ${EXPORTS_FILE})
|
||||
add_custom_target(coreclr_def DEPENDS ${DEF_FILE})
|
||||
|
||||
add_dependencies(coreclr coreclr_def)
|
||||
add_dependencies(coreclr coreclr_exports)
|
||||
add_dependencies(coreclr coreclr_def)
|
||||
add_dependencies(coreclr coreclr_exports)
|
||||
|
||||
set_property(TARGET coreclr APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION})
|
||||
set_property(TARGET coreclr APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE})
|
||||
set_property(TARGET coreclr APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION})
|
||||
set_property(TARGET coreclr APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE})
|
||||
set(LIB_CORDBEE cordbee_wks)
|
||||
set(LIB_INTEROP interop)
|
||||
set(LIB_CDAC_CONTRACT_DESCRIPTOR cdac_contract_descriptor)
|
||||
endif(NOT CLR_CMAKE_HOST_ARCH_WASM)
|
||||
|
||||
if (CLR_CMAKE_HOST_UNIX)
|
||||
if (CLR_CMAKE_HOST_UNIX AND NOT CLR_CMAKE_TARGET_ARCH_WASM)
|
||||
set(LIB_UNWINDER unwinder_wks)
|
||||
endif (CLR_CMAKE_HOST_UNIX)
|
||||
endif (CLR_CMAKE_HOST_UNIX AND NOT CLR_CMAKE_TARGET_ARCH_WASM)
|
||||
|
||||
# IMPORTANT! Please do not rearrange the order of the libraries. The linker on Linux is
|
||||
# order dependent and changing the order can result in undefined symbols in the shared
|
||||
|
@ -80,7 +85,7 @@ endif (CLR_CMAKE_HOST_UNIX)
|
|||
set(CORECLR_LIBRARIES
|
||||
utilcode
|
||||
${START_LIBRARY_GROUP} # Start group of libraries that have circular references
|
||||
cordbee_wks
|
||||
${LIB_CORDBEE}
|
||||
debug-pal
|
||||
${LIB_UNWINDER}
|
||||
v3binder
|
||||
|
@ -95,10 +100,10 @@ set(CORECLR_LIBRARIES
|
|||
utilcode
|
||||
v3binder
|
||||
System.Globalization.Native-Static
|
||||
interop
|
||||
${LIB_INTEROP}
|
||||
coreclrminipal
|
||||
gc_pal
|
||||
cdac_contract_descriptor
|
||||
${LIB_CDAC_CONTRACT_DESCRIPTOR}
|
||||
)
|
||||
|
||||
if(CLR_CMAKE_TARGET_ARCH_AMD64)
|
||||
|
@ -168,16 +173,34 @@ if(FEATURE_PERFTRACING)
|
|||
endif(CLR_CMAKE_TARGET_LINUX)
|
||||
endif(FEATURE_PERFTRACING)
|
||||
|
||||
if(FEATURE_STATICALLY_LINKED)
|
||||
set(CLRJIT_STATIC clrjit_static)
|
||||
if (FEATURE_STATICALLY_LINKED)
|
||||
if (FEATURE_JIT)
|
||||
set(CLRJIT_STATIC clrjit_static gcinfo)
|
||||
endif(FEATURE_JIT)
|
||||
if (FEATURE_INTERPRETER)
|
||||
set(CLRINTERPRETER_STATIC clrinterpreter)
|
||||
endif(FEATURE_INTERPRETER)
|
||||
endif(FEATURE_STATICALLY_LINKED)
|
||||
|
||||
if(FEATURE_JIT)
|
||||
set(CORECLR_STATIC_CLRJIT_STATIC clrjit_static)
|
||||
endif(FEATURE_JIT)
|
||||
|
||||
if(NOT CLR_CMAKE_HOST_ARCH_WASM)
|
||||
set(CEE_WKS_STATIC cee_wks_mergeable)
|
||||
else()
|
||||
set(CEE_WKS_STATIC cee_wks)
|
||||
endif(NOT CLR_CMAKE_HOST_ARCH_WASM)
|
||||
|
||||
if (CLR_CMAKE_TARGET_OSX)
|
||||
find_library(FOUNDATION Foundation REQUIRED)
|
||||
endif()
|
||||
|
||||
target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} cee_wks_core cee_wks ${FOUNDATION})
|
||||
target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} cee_wks_core clrjit_static cee_wks_mergeable ${FOUNDATION})
|
||||
if(NOT CLR_CMAKE_HOST_ARCH_WASM)
|
||||
target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} ${CLRINTERPRETER_STATIC} cee_wks_core cee_wks ${FOUNDATION})
|
||||
endif(NOT CLR_CMAKE_HOST_ARCH_WASM)
|
||||
|
||||
target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} cee_wks_core ${CORECLR_STATIC_CLRJIT_STATIC} ${CEE_WKS_STATIC} ${FOUNDATION})
|
||||
target_compile_definitions(coreclr_static PUBLIC CORECLR_EMBEDDED)
|
||||
|
||||
if (CLR_CMAKE_HOST_ANDROID)
|
||||
|
@ -227,10 +250,13 @@ if(CLR_CMAKE_TARGET_WIN32)
|
|||
endif(CLR_CMAKE_TARGET_WIN32)
|
||||
|
||||
# add the install targets
|
||||
install_clr(TARGETS coreclr DESTINATIONS . sharedFramework COMPONENT runtime)
|
||||
if(CLR_CMAKE_HOST_MACCATALYST OR CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID)
|
||||
if(NOT CLR_CMAKE_HOST_ARCH_WASM)
|
||||
install_clr(TARGETS coreclr DESTINATIONS . sharedFramework COMPONENT runtime)
|
||||
endif(NOT CLR_CMAKE_HOST_ARCH_WASM)
|
||||
|
||||
if(CLR_CMAKE_HOST_MACCATALYST OR CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID OR CLR_CMAKE_HOST_ARCH_WASM)
|
||||
install_clr(TARGETS coreclr_static DESTINATIONS . sharedFramework COMPONENT runtime)
|
||||
endif(CLR_CMAKE_HOST_MACCATALYST OR CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID)
|
||||
endif(CLR_CMAKE_HOST_MACCATALYST OR CLR_CMAKE_HOST_IOS OR CLR_CMAKE_HOST_TVOS OR CLR_CMAKE_HOST_ANDROID OR CLR_CMAKE_HOST_ARCH_WASM)
|
||||
|
||||
# Enable profile guided optimization
|
||||
add_pgo(coreclr)
|
||||
|
|
|
@ -308,6 +308,7 @@ BEGIN
|
|||
IDS_CLASSLOAD_INLINE_ARRAY_FIELD_COUNT "InlineArrayAttribute requires that the target type has a single instance field. Type: '%1'. Assembly: '%2'."
|
||||
IDS_CLASSLOAD_INLINE_ARRAY_LENGTH "InlineArrayAttribute requires that the length argument is greater than 0. Type: '%1'. Assembly: '%2'."
|
||||
IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT "InlineArrayAttribute cannot be applied to a type with explicit layout. Type: '%1'. Assembly: '%2'."
|
||||
IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT_SIZE "InlineArrayAttribute cannot be applied to a type with explicit size. Type: '%1'. Assembly: '%2'."
|
||||
|
||||
IDS_CLASSLOAD_BYREF_OF_BYREF "Could not create a ByRef of a ByRef. Type: '%1'. Assembly: '%2'."
|
||||
IDS_CLASSLOAD_POINTER_OF_BYREF "Could not create a pointer to a ByRef. Type: '%1'. Assembly: '%2'."
|
||||
|
|
|
@ -160,6 +160,8 @@
|
|||
#define IDS_CLASSLOAD_BYREF_OF_BYREF 0x17af
|
||||
#define IDS_CLASSLOAD_POINTER_OF_BYREF 0x17b0
|
||||
|
||||
#define IDS_CLASSLOAD_INLINE_ARRAY_EXPLICIT_SIZE 0x17b1
|
||||
|
||||
#define IDS_INVALID_REDIM 0x17c3
|
||||
#define IDS_INVALID_PINVOKE_CALLCONV 0x17c4
|
||||
#define IDS_CLASSLOAD_NSTRUCT_EXPLICIT_OFFSET 0x17c7
|
||||
|
|
|
@ -97,7 +97,6 @@ enum LogFacility
|
|||
LF_GC = 0x00000001,
|
||||
LF_GCALLOC = 0x00000100,
|
||||
LF_GCROOTS = 0x00080000,
|
||||
LF_ALWAYS = 0x80000000,
|
||||
};
|
||||
|
||||
enum LogLevel
|
||||
|
@ -192,19 +191,25 @@ struct StressLogMsg
|
|||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
void* StressLogMsg::ConvertArgument(float arg) = delete;
|
||||
|
||||
#if TARGET_64BIT
|
||||
template<>
|
||||
inline void* StressLogMsg::ConvertArgument(double arg)
|
||||
{
|
||||
return (void*)(size_t)(*((uint64_t*)&arg));
|
||||
}
|
||||
// COMPAT: Convert 32-bit floats to 64-bit doubles.
|
||||
template<>
|
||||
inline void* StressLogMsg::ConvertArgument(float arg)
|
||||
{
|
||||
return StressLogMsg::ConvertArgument((double)arg);
|
||||
}
|
||||
#else
|
||||
template<>
|
||||
void* StressLogMsg::ConvertArgument(double arg) = delete;
|
||||
|
||||
template<>
|
||||
void* StressLogMsg::ConvertArgument(float arg) = delete;
|
||||
|
||||
// COMPAT: Truncate 64-bit integer arguments to 32-bit
|
||||
template<>
|
||||
inline void* StressLogMsg::ConvertArgument(uint64_t arg)
|
||||
|
@ -234,7 +239,7 @@ public:
|
|||
|
||||
static void LogMsg(unsigned dprintfLevel, const StressLogMsg& msg)
|
||||
{
|
||||
GCToEEInterface::LogStressMsg(LL_ALWAYS, LF_ALWAYS|(dprintfLevel<<16)|LF_GC, msg);
|
||||
GCToEEInterface::LogStressMsg(LL_ALWAYS, (dprintfLevel<<16)|LF_GC, msg);
|
||||
}
|
||||
|
||||
static void LogMsg(unsigned level, unsigned facility, const StressLogMsg& msg)
|
||||
|
|
|
@ -7463,7 +7463,7 @@ bool gc_heap::virtual_commit (void* address, size_t size, int bucket, int h_numb
|
|||
|
||||
if ((base + size) > limit)
|
||||
{
|
||||
dprintf (1, ("%zd + %zd = %zd > limit %zd ", base, size, (base + size), limit));
|
||||
dprintf (2, ("%zd + %zd = %zd > limit %zd ", base, size, (base + size), limit));
|
||||
exceeded_p = true;
|
||||
}
|
||||
}
|
||||
|
@ -8280,9 +8280,9 @@ uint8_t* get_plug_start_in_saved (uint8_t* old_loc, mark* pinned_plug_entry)
|
|||
{
|
||||
uint8_t* saved_pre_plug_info = (uint8_t*)(pinned_plug_entry->get_pre_plug_reloc_info());
|
||||
uint8_t* plug_start_in_saved = saved_pre_plug_info + (old_loc - (pinned_plug (pinned_plug_entry) - sizeof (plug_and_gap)));
|
||||
//dprintf (1, ("detected a very short plug: %zx before PP %zx, pad %zx",
|
||||
//dprintf (2, ("detected a very short plug: %zx before PP %zx, pad %zx",
|
||||
// old_loc, pinned_plug (pinned_plug_entry), plug_start_in_saved));
|
||||
dprintf (1, ("EP: %p(%p), %p", old_loc, pinned_plug (pinned_plug_entry), plug_start_in_saved));
|
||||
dprintf (2, ("EP: %p(%p), %p", old_loc, pinned_plug (pinned_plug_entry), plug_start_in_saved));
|
||||
return plug_start_in_saved;
|
||||
}
|
||||
|
||||
|
@ -13531,7 +13531,7 @@ void gc_heap::distribute_free_regions()
|
|||
|
||||
size_t total_basic_free_regions = total_num_free_regions[basic_free_region] + surplus_regions[basic_free_region].get_num_free_regions();
|
||||
total_budget_in_region_units[basic_free_region] = compute_basic_region_budgets(heap_budget_in_region_units[basic_free_region], min_heap_budget_in_region_units[basic_free_region], total_basic_free_regions);
|
||||
|
||||
|
||||
bool aggressive_decommit_large_p = joined_last_gc_before_oom || dt_high_memory_load_p() || near_heap_hard_limit_p();
|
||||
|
||||
int region_factor[count_distributed_free_region_kinds] = { 1, LARGE_REGION_FACTOR };
|
||||
|
@ -31148,7 +31148,7 @@ void gc_heap::realloc_plan_generation_start (generation* gen, generation* consin
|
|||
generation_allocation_pointer (consing_gen) += allocation_left;
|
||||
}
|
||||
|
||||
dprintf (1, ("plan re-alloc gen%d start at %p (ptr: %p, limit: %p)", gen->gen_num,
|
||||
dprintf (2, ("plan re-alloc gen%d start at %p (ptr: %p, limit: %p)", gen->gen_num,
|
||||
generation_plan_allocation_start (consing_gen),
|
||||
generation_allocation_pointer (consing_gen),
|
||||
generation_allocation_limit (consing_gen)));
|
||||
|
@ -32751,7 +32751,7 @@ void gc_heap::process_remaining_regions (int current_plan_gen_num, generation* c
|
|||
}
|
||||
}
|
||||
|
||||
dprintf (1, ("we still need %d regions, %d will be empty", plan_regions_needed, to_be_empty_regions));
|
||||
dprintf (REGIONS_LOG, ("we still need %d regions, %d will be empty", plan_regions_needed, to_be_empty_regions));
|
||||
if (plan_regions_needed > to_be_empty_regions)
|
||||
{
|
||||
dprintf (REGIONS_LOG, ("h%d %d regions will be empty but we still need %d regions!!", heap_number, to_be_empty_regions, plan_regions_needed));
|
||||
|
@ -34104,7 +34104,7 @@ void gc_heap::plan_phase (int condemned_gen_number)
|
|||
#else
|
||||
0;
|
||||
#endif //SHORT_PLUGS
|
||||
dprintf (1, ("gen%d: NON PIN alloc: %zd, pin com: %zd, sweep: %zd, surv: %zd, pinsurv: %zd(%d%% added, %d%% art), np surv: %zd, pad: %zd",
|
||||
dprintf (2, ("gen%d: NON PIN alloc: %zd, pin com: %zd, sweep: %zd, surv: %zd, pinsurv: %zd(%d%% added, %d%% art), np surv: %zd, pad: %zd",
|
||||
gen_idx,
|
||||
generation_allocation_size (temp_gen),
|
||||
generation_pinned_allocation_compact_size (temp_gen),
|
||||
|
@ -42140,10 +42140,13 @@ BOOL gc_heap::card_transition (uint8_t* po, uint8_t* end, size_t card_word_end,
|
|||
//dprintf(3,(" Clearing cards [%zx, %zx[ ",
|
||||
dprintf(3,(" CC [%zx, %zx[ ",
|
||||
(size_t)card_address(card), (size_t)po));
|
||||
clear_cards (card, card_of(po));
|
||||
n_card_set -= (card_of (po) - card);
|
||||
n_cards_cleared += (card_of (po) - card);
|
||||
|
||||
uint8_t* card_clearing_limit = po;
|
||||
#ifdef FEATURE_CARD_MARKING_STEALING
|
||||
card_clearing_limit = min (limit, po);
|
||||
#endif // FEATURE_CARD_MARKING_STEALING
|
||||
clear_cards (card, card_of (card_clearing_limit));
|
||||
n_card_set -= (card_of (card_clearing_limit) - card);
|
||||
n_cards_cleared += (card_of (card_clearing_limit) - card);
|
||||
}
|
||||
n_eph +=cg_pointers_found;
|
||||
cg_pointers_found = 0;
|
||||
|
@ -43929,7 +43932,7 @@ generation* gc_heap::expand_heap (int condemned_generation,
|
|||
BOOL should_promote_ephemeral = FALSE;
|
||||
ptrdiff_t eph_size = total_ephemeral_size;
|
||||
#ifdef BACKGROUND_GC
|
||||
dprintf(2,("%s: ---- Heap Expansion ----", (gc_heap::background_running_p() ? "FGC" : "NGC")));
|
||||
dprintf(2,("%s: ---- Heap Expansion ----", get_str_gc_type()));
|
||||
#endif //BACKGROUND_GC
|
||||
settings.heap_expansion = TRUE;
|
||||
|
||||
|
@ -44431,7 +44434,7 @@ size_t gc_heap::desired_new_allocation (dynamic_data* dd,
|
|||
{
|
||||
size_t allocated = 0;
|
||||
size_t committed = uoh_committed_size (gen_number, &allocated);
|
||||
dprintf (1, ("GC#%zd h%d, GMI: UOH budget, UOH commit %zd (obj %zd, frag %zd), total commit: %zd (recorded: %zd)",
|
||||
dprintf (2, ("GC#%zd h%d, GMI: UOH budget, UOH commit %zd (obj %zd, frag %zd), total commit: %zd (recorded: %zd)",
|
||||
(size_t)settings.gc_index, heap_number,
|
||||
committed, allocated,
|
||||
dd_fragmentation (dynamic_data_of (gen_number)),
|
||||
|
@ -44508,7 +44511,7 @@ size_t gc_heap::desired_new_allocation (dynamic_data* dd,
|
|||
|
||||
dd_surv (dd) = cst;
|
||||
|
||||
dprintf (1, (ThreadStressLog::gcDesiredNewAllocationMsg(),
|
||||
dprintf (2, (ThreadStressLog::gcDesiredNewAllocationMsg(),
|
||||
heap_number, gen_number, out, current_size, (dd_desired_allocation (dd) - dd_gc_new_allocation (dd)),
|
||||
(int)(cst*100), (int)(f*100), current_size + new_allocation, new_allocation));
|
||||
|
||||
|
@ -47802,18 +47805,18 @@ void gc_heap::descr_generations (const char* msg)
|
|||
#endif //!TRACE_GC
|
||||
|
||||
#ifdef STRESS_LOG
|
||||
if (StressLog::StressLogOn(LF_GC, LL_INFO10))
|
||||
if (StressLog::StressLogOn(LF_GC, LL_INFO1000))
|
||||
{
|
||||
gc_heap* hp = 0;
|
||||
#ifdef MULTIPLE_HEAPS
|
||||
hp= this;
|
||||
#endif //MULTIPLE_HEAPS
|
||||
|
||||
STRESS_LOG1(LF_GC, LL_INFO10, "GC Heap %p\n", hp);
|
||||
STRESS_LOG1(LF_GC, LL_INFO1000, "GC Heap %p\n", hp);
|
||||
for (int n = max_generation; n >= 0; --n)
|
||||
{
|
||||
#ifndef USE_REGIONS
|
||||
STRESS_LOG4(LF_GC, LL_INFO10, " Generation %d [%p, %p] cur = %p\n",
|
||||
STRESS_LOG4(LF_GC, LL_INFO1000, " Generation %d [%p, %p] cur = %p\n",
|
||||
n,
|
||||
generation_allocation_start(generation_of(n)),
|
||||
generation_allocation_limit(generation_of(n)),
|
||||
|
@ -47823,7 +47826,7 @@ void gc_heap::descr_generations (const char* msg)
|
|||
heap_segment* seg = generation_start_segment(generation_of(n));
|
||||
while (seg)
|
||||
{
|
||||
STRESS_LOG4(LF_GC, LL_INFO10, " Segment mem %p alloc = %p used %p committed %p\n",
|
||||
STRESS_LOG4(LF_GC, LL_INFO1000, " Segment mem %p alloc = %p used %p committed %p\n",
|
||||
heap_segment_mem(seg),
|
||||
heap_segment_allocated(seg),
|
||||
heap_segment_used(seg),
|
||||
|
@ -48653,7 +48656,7 @@ void gc_heap::verify_heap (BOOL begin_gc_p)
|
|||
dprintf (2,("[%s]GC#%zu(%s): Verifying heap - begin",
|
||||
(begin_gc_p ? "BEG" : "END"),
|
||||
VolatileLoad(&settings.gc_index),
|
||||
(settings.concurrent ? "BGC" : (gc_heap::background_running_p() ? "FGC" : "NGC"))));
|
||||
get_str_gc_type()));
|
||||
#else
|
||||
dprintf (2,("[%s]GC#%zu: Verifying heap - begin",
|
||||
(begin_gc_p ? "BEG" : "END"), VolatileLoad(&settings.gc_index)));
|
||||
|
@ -49060,7 +49063,7 @@ void gc_heap::verify_heap (BOOL begin_gc_p)
|
|||
|
||||
#ifdef BACKGROUND_GC
|
||||
dprintf (2, ("(%s)(%s)(%s) total_objects_verified is %zd, total_objects_verified_deep is %zd",
|
||||
(settings.concurrent ? "BGC" : (gc_heap::background_running_p () ? "FGC" : "NGC")),
|
||||
get_str_gc_type(),
|
||||
(begin_gc_p ? "BEG" : "END"),
|
||||
((current_c_gc_state == c_gc_state_planning) ? "in plan" : "not in plan"),
|
||||
total_objects_verified, total_objects_verified_deep));
|
||||
|
@ -49113,7 +49116,7 @@ void gc_heap::verify_heap (BOOL begin_gc_p)
|
|||
}
|
||||
dprintf (2,("GC%zu(%s): Verifying heap - end",
|
||||
VolatileLoad(&settings.gc_index),
|
||||
(settings.concurrent ? "BGC" : (gc_heap::background_running_p() ? "FGC" : "NGC"))));
|
||||
get_str_gc_type()));
|
||||
#else
|
||||
dprintf (2,("GC#d: Verifying heap - end", VolatileLoad(&settings.gc_index)));
|
||||
#endif //BACKGROUND_GC
|
||||
|
@ -49779,10 +49782,10 @@ HRESULT GCHeap::Initialize()
|
|||
// GC callback functions
|
||||
bool GCHeap::IsPromoted(Object* object)
|
||||
{
|
||||
return IsPromoted(object, true);
|
||||
return IsPromoted2(object, true);
|
||||
}
|
||||
|
||||
bool GCHeap::IsPromoted(Object* object, bool bVerifyNextHeader)
|
||||
bool GCHeap::IsPromoted2(Object* object, bool bVerifyNextHeader)
|
||||
{
|
||||
uint8_t* o = (uint8_t*)object;
|
||||
|
||||
|
@ -50878,6 +50881,15 @@ last_recorded_gc_info* gc_heap::get_completed_bgc_info()
|
|||
}
|
||||
#endif //BACKGROUND_GC
|
||||
|
||||
const char* gc_heap::get_str_gc_type()
|
||||
{
|
||||
#ifdef BACKGROUND_GC
|
||||
return (settings.concurrent ? "BGC" : (gc_heap::background_running_p () ? "FGC" : "NGC"));
|
||||
#else // BACKGROUND_GC
|
||||
return "NGC";
|
||||
#endif // BACKGROUND_GC
|
||||
}
|
||||
|
||||
void gc_heap::do_pre_gc()
|
||||
{
|
||||
STRESS_LOG_GC_STACK;
|
||||
|
@ -50906,14 +50918,21 @@ void gc_heap::do_pre_gc()
|
|||
#ifdef TRACE_GC
|
||||
size_t total_allocated_since_last_gc[total_oh_count];
|
||||
get_total_allocated_since_last_gc (total_allocated_since_last_gc);
|
||||
|
||||
bool compatibleWithStressLog = true;
|
||||
#ifdef SIMPLE_DPRINTF
|
||||
compatibleWithStressLog = false;
|
||||
#endif //SIMPLE_DPRINTF
|
||||
bgc_state b_state = bgc_not_in_process;
|
||||
#ifdef BACKGROUND_GC
|
||||
b_state = settings.b_state;
|
||||
#endif //BACKGROUND_GC
|
||||
|
||||
size_t heap_size_before = get_total_heap_size();
|
||||
uint64_t start_gc_time = GetHighPrecisionTimeStamp();
|
||||
uint64_t elapsed_since_last_gc_us = start_gc_time - last_alloc_reset_suspended_end_time;
|
||||
max_peak_heap_size = max (max_peak_heap_size, heap_size_before);
|
||||
|
||||
dprintf (6666, (ThreadStressLog::gcDetailedStartMsg(),
|
||||
dprintf (6666, (ThreadStressLog::gcDetailedStartMsg(compatibleWithStressLog),
|
||||
VolatileLoad(&settings.gc_index),
|
||||
dd_collection_count (hp->dynamic_data_of (0)),
|
||||
settings.condemned_generation,
|
||||
|
@ -50926,18 +50945,11 @@ void gc_heap::do_pre_gc()
|
|||
(elapsed_since_last_gc_us ? (total_allocated_since_last_gc[gc_oh_num::loh] / 1000.0 / elapsed_since_last_gc_us) : 0),
|
||||
total_allocated_since_last_gc[gc_oh_num::poh],
|
||||
(elapsed_since_last_gc_us ? (total_allocated_since_last_gc[gc_oh_num::poh] / 1000.0 / elapsed_since_last_gc_us) : 0),
|
||||
(settings.concurrent ? "BGC" : (gc_heap::background_running_p() ? "FGC" : "NGC")),
|
||||
settings.b_state,
|
||||
n_heaps,
|
||||
(heap_size_before / 1000.0 / 1000.0),
|
||||
(max_peak_heap_size / 1000.0 / 1000.0)));
|
||||
#else
|
||||
dprintf (1, ("*GC* %d(gen0:%d)(%d)(alloc: %zd)",
|
||||
VolatileLoad(&settings.gc_index),
|
||||
dd_collection_count(hp->dynamic_data_of(0)),
|
||||
settings.condemned_generation,
|
||||
(total_allocated_since_last_gc[0] + total_allocated_since_last_gc[1] + total_allocated_since_last_gc[2])));
|
||||
#endif //BACKGROUND_GC
|
||||
get_str_gc_type(),
|
||||
b_state,
|
||||
n_heaps
|
||||
SIMPLE_DPRINTF_ARG(heap_size_before / 1000.0 / 1000.0)
|
||||
SIMPLE_DPRINTF_ARG(max_peak_heap_size / 1000.0 / 1000.0)));
|
||||
|
||||
if (heap_hard_limit)
|
||||
{
|
||||
|
@ -51356,18 +51368,12 @@ void gc_heap::do_post_gc()
|
|||
}
|
||||
#endif //BGC_SERVO_TUNING
|
||||
|
||||
#ifdef BACKGROUND_GC
|
||||
const char* str_gc_type = (settings.concurrent ? "BGC" : (gc_heap::background_running_p () ? "FGC" : "NGC"));
|
||||
#else
|
||||
const char* str_gc_type = "NGC";
|
||||
#endif //BACKGROUND_GC
|
||||
|
||||
dprintf (6666, (ThreadStressLog::gcDetailedEndMsg(),
|
||||
VolatileLoad (&settings.gc_index),
|
||||
dd_collection_count (hp->dynamic_data_of (0)),
|
||||
(get_total_heap_size() / 1000.0 / 1000.0),
|
||||
settings.condemned_generation,
|
||||
str_gc_type,
|
||||
get_str_gc_type(),
|
||||
(settings.compaction ? "C" : "S"),
|
||||
(settings.promotion ? "P" : "S"),
|
||||
settings.entry_memory_load,
|
||||
|
|
|
@ -285,11 +285,16 @@ struct alloc_context : gc_alloc_context
|
|||
#endif // FEATURE_SVR_GC
|
||||
};
|
||||
|
||||
// NOTE!
|
||||
// Do not add overloaded methods, always use a different name, different from any methods declared here or
|
||||
// on the IGCHeap interface.
|
||||
class IGCHeapInternal : public IGCHeap {
|
||||
public:
|
||||
virtual int GetNumberOfHeaps () PURE_VIRTUAL
|
||||
virtual int GetHomeHeapNumber () PURE_VIRTUAL
|
||||
virtual size_t GetPromotedBytes(int heap_index) PURE_VIRTUAL
|
||||
// Used by the bridge code.
|
||||
virtual bool IsPromoted2(Object* object, bool bVerifyNextHeader) PURE_VIRTUAL
|
||||
|
||||
unsigned GetMaxGeneration()
|
||||
{
|
||||
|
@ -344,9 +349,23 @@ inline bool IsServerHeap()
|
|||
#define MAX_LONGPATH 1024
|
||||
#endif // MAX_LONGPATH
|
||||
|
||||
// #define TRACE_GC
|
||||
// TRACE_GC has two sub-modes: the standard VM stress log mechanism and
|
||||
// SIMPLE_DPRINTF, which is text output. By default, we enable TRACE_GC (not
|
||||
// SIMPLE_DPRINTF) for debug/checked builds so that we can catch build breaks.
|
||||
// HOST_64BIT is required because logging dprintf to the stress log is only
|
||||
// supported on 64 bit platforms. We could consider enabling it in release
|
||||
// builds and for more logging sites (see below for details) but are being
|
||||
// conservative about performance impact.
|
||||
//
|
||||
// Normal development time changes are to enable SIMPLE_DPRINTF here (which
|
||||
// will automatically set TRACE_GC) or to only enable TRACE_GC.
|
||||
|
||||
// #define SIMPLE_DPRINTF
|
||||
|
||||
#if defined(SIMPLE_DPRINTF) || (defined(_DEBUG) && defined(HOST_64BIT))
|
||||
#define TRACE_GC
|
||||
#endif // _DEBUG
|
||||
|
||||
#ifdef TRACE_GC
|
||||
#define MIN_CUSTOM_LOG_LEVEL 7
|
||||
#define SEG_REUSE_LOG_0 (MIN_CUSTOM_LOG_LEVEL)
|
||||
|
@ -375,10 +394,79 @@ HRESULT initialize_log_file();
|
|||
void flush_gc_log (bool);
|
||||
void GCLog (const char *fmt, ... );
|
||||
#define dprintf(l,x) {if ((l == 1) || (l == GTC_LOG)) {GCLog x;}}
|
||||
#define SIMPLE_DPRINTF_ARG(x) , x
|
||||
|
||||
#else //SIMPLE_DPRINTF
|
||||
|
||||
#ifdef HOST_64BIT
|
||||
#define dprintf(l,x) STRESS_LOG_VA(l,x);
|
||||
|
||||
// -------------------------------
|
||||
// Stress log / dprintf background
|
||||
// -------------------------------
|
||||
//
|
||||
// This code connects dprintf to the stress log mechanism. These machanisms
|
||||
// and their usage has evolved a bit separately over time, so there are some
|
||||
// rough edges here.
|
||||
//
|
||||
// The stress log mechanism has a LogFacility and a LogLevel. Facilities can be
|
||||
// chosen through DOTNET_LogFacility, and the facility is recorded in the
|
||||
// stress log. LogFacility is a bitmask. The GC only has a few bits reserved
|
||||
// in the bitmask, and most GC logging uses a single value (LF_GC, which is 0x1).
|
||||
//
|
||||
// The stress log logging level can be chosen through DOTNET_LogLevel. This
|
||||
// causes filtering at runtime, and the level is not recorded in the stress log.
|
||||
// The first argument to dprintf is similar, though it can record either a level
|
||||
// (values below 7) or a GC area (values starting with SEG_REUSE_LOG_0 above).
|
||||
// Developers often use StressLogAnalyzer to filter by this value at _analysis_
|
||||
// time, which doesn't match usual stress log usage.
|
||||
//
|
||||
// In practice, dprintf(1) and LL_INFO10 (which has the value 4) have been used
|
||||
// similarly on log messages. A dprintf(1) is generally called about a few times per
|
||||
// GC, and LL_INFO10 is "10 logs per small but not trivial run". Other values
|
||||
// have been audited. We could consider moving the GC values to be in line with
|
||||
// the rest of the runtime (change 1 to 4 to make room for errors/warnings, etc.)
|
||||
// or (to avoid churn) convert them by adding 3.
|
||||
//
|
||||
// To allow StressLogAnalyzer to use the GC level values, we abuse the stress
|
||||
// log LogLevel by storing the GC value in the upper 16 bits of LogLevel and
|
||||
// also settings LF_GC (0x1). This works because we don't enable other logging
|
||||
// when doing GC investigations. However, we don't want to do this by default
|
||||
// because setting the upper bits will cause GC logging to masquerade as non-GC
|
||||
// logging. For example, dprintf(3) would use (3 << 16) | LF_GC == 0x30001,
|
||||
// which is LF_ASSERT | LF_VERIFIER | LF_GC in other contexts.
|
||||
//
|
||||
// Lastly, we have GC logging for some very low level operations, so by default
|
||||
// we don't want to even have the check that logging is enabled for performance
|
||||
// reasons. Right now we are very conservative and only allow dprintf(1) to go
|
||||
// to the stress log in default builds, but we could consider allowing more in
|
||||
// the future.
|
||||
|
||||
// -----------------------------
|
||||
// Stress log / dprintf settings
|
||||
// -----------------------------
|
||||
//
|
||||
// (See above for details.)
|
||||
//
|
||||
// The following line works for normal debug/checked builds (where STRESS_LOG is
|
||||
// defined and SIMPLE_DPRINTF is not). All dprintf sites are checked for
|
||||
// compilation errors, yet all but those with level 1 can be statically
|
||||
// optimized away. In the future after more auditing, this could be expanded to
|
||||
// more levels.
|
||||
//
|
||||
// Note that zero is passed because STRESS_LOG_VA/LogMsg will add LF_GC and in
|
||||
// normal builds we don't want conflicts in the upper bits of LogFacility.
|
||||
#define dprintf(l,x) if (l == 1) {STRESS_LOG_VA(0,x);}
|
||||
|
||||
// For private builds where it is ok (and useful) to have conflicts in the upper
|
||||
// bits of LogFacility, more events can be allowed and the dprintf level can be
|
||||
// passed through. Usually this is going to be a GC investigation and the other
|
||||
// logging will be disabled, so the theoretical conflict won't happen in
|
||||
// practice. Note that in these examples, 'l' ("ell", not "one") is passed
|
||||
// rather than '0'.
|
||||
//#define dprintf(l,x) STRESS_LOG_VA(l,x);
|
||||
//#define dprintf(l,x) {if ((l <= 2) || (l == 6666)) {STRESS_LOG_VA(l,x);}}
|
||||
|
||||
#define SIMPLE_DPRINTF_ARG(x)
|
||||
#else //HOST_64BIT
|
||||
#error Logging dprintf to stress log on 32 bits platforms is not supported.
|
||||
#endif //HOST_64BIT
|
||||
|
|
|
@ -666,7 +666,7 @@ static bool PushObject(Object* obj, void* unused)
|
|||
}
|
||||
|
||||
// We only care about dead objects
|
||||
if (!data && g_theGCHeap->IsPromoted(obj, false))
|
||||
if (!data && g_theGCHeap->IsPromoted2(obj, false))
|
||||
{
|
||||
#if DUMP_GRAPH
|
||||
printf ("alive\n");
|
||||
|
|
|
@ -126,7 +126,7 @@ public:
|
|||
// Check if an argument is promoted (ONLY CALL DURING
|
||||
// THE PROMOTIONSGRANTED CALLBACK.)
|
||||
bool IsPromoted (Object *object);
|
||||
bool IsPromoted (Object *object, bool bVerifyNextHeader);
|
||||
bool IsPromoted2 (Object *object, bool bVerifyNextHeader);
|
||||
|
||||
size_t GetPromotedBytes (int heap_index);
|
||||
|
||||
|
|
|
@ -644,6 +644,9 @@ enum class GCConfigurationType
|
|||
using ConfigurationValueFunc = void (*)(void* context, void* name, void* publicKey, GCConfigurationType type, int64_t data);
|
||||
|
||||
// IGCHeap is the interface that the VM will use when interacting with the GC.
|
||||
// NOTE!
|
||||
// Only add methods to the end.
|
||||
// Do not add overloaded methods. Always use a different name.
|
||||
class IGCHeap {
|
||||
public:
|
||||
/*
|
||||
|
@ -1065,9 +1068,6 @@ public:
|
|||
virtual void DiagWalkHeapWithACHandling(walk_fn fn, void* context, int gen_number, bool walk_large_object_heap_p) PURE_VIRTUAL
|
||||
|
||||
virtual void NullBridgeObjectsWeakRefs(size_t length, void* unreachableObjectHandles) PURE_VIRTUAL;
|
||||
|
||||
// Returns whether nor this GC was promoted by the last GC.
|
||||
virtual bool IsPromoted(Object* object, bool bVerifyNextHeader) PURE_VIRTUAL
|
||||
};
|
||||
|
||||
#ifdef WRITE_BARRIER_CHECK
|
||||
|
|
|
@ -1578,6 +1578,8 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
PER_HEAP_ISOLATED_METHOD const char* get_str_gc_type();
|
||||
|
||||
#ifdef TRACE_GC
|
||||
PER_HEAP_METHOD void print_free_list (int gen, heap_segment* seg);
|
||||
#endif // TRACE_GC
|
||||
|
|
|
@ -222,7 +222,7 @@ bool GCToOSInterface::Initialize()
|
|||
//
|
||||
// support for FlusProcessWriteBuffers
|
||||
//
|
||||
|
||||
#ifndef TARGET_WASM
|
||||
assert(s_flushUsingMemBarrier == 0);
|
||||
|
||||
if (CanFlushUsingMembarrier())
|
||||
|
@ -262,6 +262,7 @@ bool GCToOSInterface::Initialize()
|
|||
}
|
||||
}
|
||||
#endif // !TARGET_APPLE
|
||||
#endif // !TARGET_WASM
|
||||
|
||||
InitializeCGroup();
|
||||
|
||||
|
@ -412,6 +413,7 @@ bool GCToOSInterface::CanGetCurrentProcessorNumber()
|
|||
// Flush write buffers of processors that are executing threads of the current process
|
||||
void GCToOSInterface::FlushProcessWriteBuffers()
|
||||
{
|
||||
#ifndef TARGET_WASM
|
||||
#if defined(__linux__) || HAVE_SYS_MEMBARRIER_H
|
||||
if (s_flushUsingMemBarrier)
|
||||
{
|
||||
|
@ -490,6 +492,7 @@ void GCToOSInterface::FlushProcessWriteBuffers()
|
|||
CHECK_MACH("vm_deallocate()", machret);
|
||||
}
|
||||
#endif // TARGET_APPLE
|
||||
#endif // !TARGET_WASM
|
||||
}
|
||||
|
||||
// Break into a debugger. Uses a compiler intrinsic if one is available,
|
||||
|
@ -576,7 +579,7 @@ static void* VirtualReserveInner(size_t size, size_t alignment, uint32_t flags,
|
|||
}
|
||||
|
||||
pRetVal = pAlignedRetVal;
|
||||
#ifdef MADV_DONTDUMP
|
||||
#if defined(MADV_DONTDUMP) && !defined(TARGET_WASM)
|
||||
// Do not include reserved uncommitted memory in coredump.
|
||||
if (!committing)
|
||||
{
|
||||
|
@ -624,9 +627,13 @@ bool GCToOSInterface::VirtualRelease(void* address, size_t size)
|
|||
// true if it has succeeded, false if it has failed
|
||||
static bool VirtualCommitInner(void* address, size_t size, uint16_t node, bool newMemory)
|
||||
{
|
||||
#ifndef TARGET_WASM
|
||||
bool success = mprotect(address, size, PROT_WRITE | PROT_READ) == 0;
|
||||
#else
|
||||
bool success = true;
|
||||
#endif // !TARGET_WASM
|
||||
|
||||
#ifdef MADV_DODUMP
|
||||
#if defined(MADV_DONTDUMP) && !defined(TARGET_WASM)
|
||||
if (success && !newMemory)
|
||||
{
|
||||
// Include committed memory in coredump. New memory is included by default.
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
include_directories(inc)
|
||||
|
||||
if(CLR_CMAKE_HOST_WIN32)
|
||||
add_subdirectory(coreshim)
|
||||
endif(CLR_CMAKE_HOST_WIN32)
|
||||
if (CLR_CMAKE_TARGET_ARCH_WASM)
|
||||
add_subdirectory(corewasmrun)
|
||||
else()
|
||||
if(CLR_CMAKE_HOST_WIN32)
|
||||
add_subdirectory(coreshim)
|
||||
endif(CLR_CMAKE_HOST_WIN32)
|
||||
|
||||
add_subdirectory(corerun)
|
||||
add_subdirectory(corerun)
|
||||
endif()
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
project(corewasmrun)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
if (DEFINED CLR_CMAKE_ICU_DIR)
|
||||
link_directories(${CLR_CMAKE_ICU_DIR}/lib)
|
||||
endif(DEFINED CLR_CMAKE_ICU_DIR)
|
||||
|
||||
add_executable_clr(corewasmrun
|
||||
corewasmrun.cpp
|
||||
)
|
||||
|
||||
set(_WASM_PRELOAD_DIR "${CMAKE_INSTALL_PREFIX}/IL")
|
||||
if (EXISTS "${_WASM_PRELOAD_DIR}")
|
||||
set(_WASM_PRELOAD_FILE --preload-file ${_WASM_PRELOAD_DIR}@/)
|
||||
endif (EXISTS "${_WASM_PRELOAD_DIR}")
|
||||
|
||||
target_compile_options(corewasmrun PRIVATE -fwasm-exceptions)
|
||||
target_link_options(corewasmrun PRIVATE -fwasm-exceptions -sEXIT_RUNTIME=1 -sINITIAL_MEMORY=134217728 -sFORCE_FILESYSTEM=1 ${_WASM_PRELOAD_FILE} -Wl,-error-limit=0)
|
||||
|
||||
target_link_libraries(corewasmrun PRIVATE coreclr_static)
|
||||
target_link_libraries(corewasmrun PRIVATE clrinterpreter)
|
||||
|
||||
target_link_libraries(corewasmrun PRIVATE icuuc)
|
||||
target_link_libraries(corewasmrun PRIVATE icui18n)
|
||||
target_link_libraries(corewasmrun PRIVATE icudata)
|
||||
|
||||
install_clr(TARGETS corewasmrun DESTINATIONS . COMPONENT hosts)
|
|
@ -0,0 +1,49 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
//
|
||||
|
||||
#include <cstdio>
|
||||
#include <coreclrhost.h>
|
||||
|
||||
static void log_error_info(const char* line)
|
||||
{
|
||||
std::fprintf(stderr, "log error: %s\n", line);
|
||||
}
|
||||
|
||||
// The current CoreCLR instance details.
|
||||
static void* CurrentClrInstance;
|
||||
static unsigned int CurrentAppDomainId;
|
||||
|
||||
static int run()
|
||||
{
|
||||
const char* exe_path = "<coreclr-wasm>";
|
||||
const char* app_domain_name = "corewasmrun";
|
||||
const char* entry_assembly = "ManagedAssembly.dll";
|
||||
|
||||
coreclr_set_error_writer(log_error_info);
|
||||
|
||||
printf("call coreclr_initialize\n");
|
||||
int retval = coreclr_initialize(exe_path, app_domain_name, 0, nullptr, nullptr, &CurrentClrInstance, &CurrentAppDomainId);
|
||||
|
||||
if (retval < 0)
|
||||
{
|
||||
std::fprintf(stderr, "coreclr_initialize failed - Error: 0x%08x\n", retval);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("coreclr_initialize succeeded - retval: 0x%08x\n", retval);
|
||||
}
|
||||
|
||||
// coreclr_execute_assembly();
|
||||
// coreclr_shutdown();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int retval = run();
|
||||
|
||||
return retval;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>corewasmrun</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>corewasmrun</h1>
|
||||
<pre id="log"></pre>
|
||||
<script>
|
||||
Module = {
|
||||
preRun: [ function () {
|
||||
ENV.PAL_DBG_CHANNELS="+all.all";
|
||||
// ENV.PAL_DBG_CHANNELS="+all.ERROR";
|
||||
}],
|
||||
onExit: function (code) {
|
||||
console.log("onExit, code: " + code);
|
||||
},
|
||||
};
|
||||
|
||||
const originalConsoleLog = console.log;
|
||||
console.log = function(message) {
|
||||
originalConsoleLog(message);
|
||||
fetch('/log=corewasmrun-log.txt', {
|
||||
method: 'POST',
|
||||
body: ('stdout: ' + message),
|
||||
headers: {
|
||||
'Content-Type': 'text/plain'
|
||||
}
|
||||
});
|
||||
const elt = document.createElement("span");
|
||||
elt.textContent = message + "\n";
|
||||
document.querySelector("#log").appendChild(elt);
|
||||
};
|
||||
const originalConsoleError = console.error;
|
||||
console.error = function(message) {
|
||||
originalConsoleError(message);
|
||||
fetch('/log=corewasmrun-log.txt', {
|
||||
method: 'POST',
|
||||
body: ('stderr: ' + message),
|
||||
headers: {
|
||||
'Content-Type': 'text/plain'
|
||||
}
|
||||
});
|
||||
const elt = document.createElement("span");
|
||||
elt.textContent = message + "\n";
|
||||
elt.style.color = "red";
|
||||
document.querySelector("#log").appendChild(elt);
|
||||
};
|
||||
</script>
|
||||
<script src="corewasmrun.js"></script>
|
||||
</body>
|
|
@ -5,7 +5,6 @@ set( CORGUIDS_IDL_SOURCES
|
|||
clrinternal.idl
|
||||
xclrdata.idl
|
||||
corprof.idl
|
||||
corpub.idl
|
||||
corsym.idl
|
||||
sospriv.idl
|
||||
)
|
||||
|
|
|
@ -78,7 +78,7 @@ Crst AppDomainCache
|
|||
End
|
||||
|
||||
Crst PinnedHeapHandleTable
|
||||
AcquiredBefore AvailableParamTypes HandleTable IbcProfile SyncBlockCache SystemDomainDelayedUnloadList
|
||||
AcquiredBefore AvailableParamTypes HandleTable SyncBlockCache SystemDomainDelayedUnloadList
|
||||
SystemDomain
|
||||
End
|
||||
|
||||
|
@ -91,7 +91,7 @@ Crst AvailableClass
|
|||
End
|
||||
|
||||
Crst AvailableParamTypes
|
||||
AcquiredBefore ModuleLookupTable IbcProfile LoaderHeap
|
||||
AcquiredBefore ModuleLookupTable LoaderHeap
|
||||
End
|
||||
|
||||
Crst CCompRC
|
||||
|
@ -103,7 +103,7 @@ Crst ClassFactInfoHash
|
|||
End
|
||||
|
||||
Crst ClassInit
|
||||
AcquiredBefore DeadlockDetection IbcProfile
|
||||
AcquiredBefore DeadlockDetection
|
||||
SameLevelAs Jit
|
||||
End
|
||||
|
||||
|
@ -176,14 +176,14 @@ Crst DbgTransport
|
|||
End
|
||||
|
||||
Crst GenericDictionaryExpansion
|
||||
AcquiredBefore PinnedHeapHandleTable IbcProfile LoaderHeap SystemDomainDelayedUnloadList UniqueStack
|
||||
AcquiredBefore PinnedHeapHandleTable LoaderHeap SystemDomainDelayedUnloadList UniqueStack
|
||||
End
|
||||
|
||||
Crst DynamicIL
|
||||
End
|
||||
|
||||
Crst DynamicMT
|
||||
AcquiredBefore IbcProfile CodeVersioning
|
||||
AcquiredBefore CodeVersioning
|
||||
End
|
||||
|
||||
Crst EventStore
|
||||
|
@ -209,7 +209,7 @@ Crst MethodTableExposedObject
|
|||
End
|
||||
|
||||
Crst FuncPtrStubs
|
||||
AcquiredBefore IbcProfile LoaderHeap UniqueStack CodeFragmentHeap JumpStubCache
|
||||
AcquiredBefore LoaderHeap UniqueStack CodeFragmentHeap JumpStubCache
|
||||
End
|
||||
|
||||
Crst FusionAppCtx
|
||||
|
@ -221,16 +221,13 @@ Crst GCCover
|
|||
End
|
||||
|
||||
Crst GlobalStrLiteralMap
|
||||
AcquiredBefore PinnedHeapHandleTable HandleTable IbcProfile SyncBlockCache SystemDomainDelayedUnloadList ThreadStore UniqueStack
|
||||
AcquiredBefore PinnedHeapHandleTable HandleTable SyncBlockCache SystemDomainDelayedUnloadList ThreadStore UniqueStack
|
||||
End
|
||||
|
||||
Crst HandleTable
|
||||
SameLevelAs HandleTable
|
||||
End
|
||||
|
||||
Crst IbcProfile
|
||||
End
|
||||
|
||||
Crst IJWFixupData
|
||||
AcquiredBefore FuncPtrStubs IJWHash LoaderHeap
|
||||
End
|
||||
|
@ -329,7 +326,7 @@ Crst PendingTypeLoadEntry
|
|||
AcquiredBefore AppDomainCache PinnedHeapHandleTable AssemblyLoader AvailableClass AvailableParamTypes
|
||||
ClassInit DeadlockDetection DebuggerController DebuggerJitInfo DebuggerMutex
|
||||
GenericDictionaryExpansion Exception FuncPtrStubs
|
||||
FusionAppCtx GlobalStrLiteralMap HandleTable IbcProfile
|
||||
FusionAppCtx GlobalStrLiteralMap HandleTable
|
||||
IJWFixupData IJWHash ISymUnmanagedReader Jit JumpStubCache LoaderHeap
|
||||
Module ModuleLookupTable PEImage
|
||||
SigConvert SingleUseLock StubDispatchCache
|
||||
|
@ -352,7 +349,7 @@ Crst ProfilingAPIStatus
|
|||
End
|
||||
|
||||
Crst RCWCache
|
||||
AcquiredBefore IbcProfile LoaderHeap RCWCleanupList
|
||||
AcquiredBefore LoaderHeap RCWCleanupList
|
||||
End
|
||||
|
||||
Crst RCWCleanupList
|
||||
|
@ -415,7 +412,7 @@ Crst SyncHashLock
|
|||
End
|
||||
|
||||
Crst SystemDomain
|
||||
AcquiredBefore DebuggerMutex HandleTable IbcProfile
|
||||
AcquiredBefore DebuggerMutex HandleTable
|
||||
ThreadIdDispenser ThreadStore
|
||||
End
|
||||
|
||||
|
@ -431,7 +428,7 @@ End
|
|||
|
||||
Crst ThreadStore
|
||||
AcquiredBefore AvailableParamTypes DeadlockDetection DebuggerController
|
||||
DebuggerHeapLock DebuggerJitInfo DynamicIL HandleTable IbcProfile
|
||||
DebuggerHeapLock DebuggerJitInfo DynamicIL HandleTable
|
||||
JumpStubCache LoaderHeap ModuleLookupTable ProfilerGCRefDataFreeList
|
||||
SingleUseLock SyncBlockCache SystemDomainDelayedUnloadList ThreadIdDispenser DebuggerMutex
|
||||
JitInlineTrackingMap
|
||||
|
@ -453,11 +450,11 @@ Crst UniqueStack
|
|||
End
|
||||
|
||||
Crst UnresolvedClassLock
|
||||
AcquiredBefore AvailableParamTypes IbcProfile JumpStubCache
|
||||
AcquiredBefore AvailableParamTypes JumpStubCache
|
||||
End
|
||||
|
||||
Crst WrapperTemplate
|
||||
AcquiredBefore IbcProfile
|
||||
AcquiredBefore ExecutableAllocatorLock
|
||||
End
|
||||
|
||||
Crst UMEntryThunkCache
|
||||
|
@ -479,7 +476,6 @@ Crst MulticoreJitManager
|
|||
End
|
||||
|
||||
Crst InlineTrackingMap
|
||||
AcquiredBefore IbcProfile
|
||||
End
|
||||
|
||||
Crst JitInlineTrackingMap
|
||||
|
|
|
@ -453,7 +453,7 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadSuspendInjection, W("INTERNAL_ThreadSusp
|
|||
///
|
||||
/// Thread (miscellaneous)
|
||||
///
|
||||
RETAIL_CONFIG_DWORD_INFO(INTERNAL_DefaultStackSize, W("DefaultStackSize"), 0, "Stack size to use for new VM threads when thread is created with default stack size (dwStackSize == 0).")
|
||||
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_Thread_DefaultStackSize, W("Thread_DefaultStackSize"), 0, "Stack size to use for new VM threads when thread is created with default stack size (dwStackSize == 0).")
|
||||
RETAIL_CONFIG_DWORD_INFO(INTERNAL_Thread_DeadThreadCountThresholdForGCTrigger, W("Thread_DeadThreadCountThresholdForGCTrigger"), 75, "In the heuristics to clean up dead threads, this threshold must be reached before triggering a GC will be considered. Set to 0 to disable triggering a GC based on dead threads.")
|
||||
RETAIL_CONFIG_DWORD_INFO(INTERNAL_Thread_DeadThreadGCTriggerPeriodMilliseconds, W("Thread_DeadThreadGCTriggerPeriodMilliseconds"), 1000 * 60 * 30, "In the heuristics to clean up dead threads, this much time must have elapsed since the previous max-generation GC before triggering another GC will be considered")
|
||||
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_Thread_UseAllCpuGroups, W("Thread_UseAllCpuGroups"), 0, "Specifies whether to query and use CPU group information for determining the processor count.")
|
||||
|
@ -708,6 +708,9 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableRiscV64Zba, W("EnableRiscV64
|
|||
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_EnableRiscV64Zbb, W("EnableRiscV64Zbb"), 1, "Allows RiscV64 Zbb hardware intrinsics to be disabled")
|
||||
#endif
|
||||
|
||||
// Runtime-async
|
||||
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_RuntimeAsync, W("RuntimeAsync"), 0, "Enables runtime async method support")
|
||||
|
||||
///
|
||||
/// Uncategorized
|
||||
///
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue