-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FileLoadException: Add Profiler fix #671
Merged
zacharycmontoya
merged 25 commits into
master
from
zach/profiler/fileloadexception/profiler-fix
Mar 11, 2020
Merged
FileLoadException: Add Profiler fix #671
zacharycmontoya
merged 25 commits into
master
from
zach/profiler/fileloadexception/profiler-fix
Mar 11, 2020
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
src/Datadog.Trace.ClrProfiler.Managed/Integrations/WebRequestIntegration.cs
Outdated
Show resolved
Hide resolved
25a7d5a
to
1e05292
Compare
…us know it is no longer safe to instrument domain-neutral assemblies. We still crash because at this point we've already added a dependency to System.Web.
…odsCore instead of System.Web.Compilation.BuildManager.InvokePreStartInitMethods
…at holds base classes needed for automatic instrumentation that does not rely on the Tracer.
…ple input assemblies with InterceptMethodAttributes
…er.Managed to Datadog.Trace.ClrProfiler.Managed.Utilities
…getMethod, and modify GenerateIntegrationDefinitions to remove the previous fallback implementation. The result is the exact same integrations.json file, and the explicit attribute may be necessary for doing the AspNet injection I'd like to do.
…ke when it sees a wrapper method, giving flexibility to either replace the target method or insert the method call at the beginning or end of the calling method. All existing integrations have the action "ReplaceTargetMethod" but we may have variations in the future.
…rProfiler.Managed.Utilities. This name is likely temporary as the naming convention doesn't make much sense. The most important quality of this assembly is it has no framework dependencies outside System.Web. Modify the profiler to insert method calls at the beginning of the instrumented method if they have the InsertFirst action.
Move startup logic into a new assembly Datadog.Trace.AspNet.Loader Update integrations and wix files with the new assembly.
…lse whenever we see it being loaded not domain-neutral. Only emit the warning when it was previously loaded domain-neutral.
…rently stop a lot of IIS applications from getting System.Net.Http and System.Data spans.
Refactor profiler code.
c83fd1e
to
bf885dd
Compare
bobuva
reviewed
Mar 9, 2020
bobuva
reviewed
Mar 9, 2020
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, thanks.
src/Datadog.Trace.ClrProfiler.Managed.Core/MethodReplacementActionType.cs
Show resolved
Hide resolved
src/Datadog.Trace.ClrProfiler.Managed.Core/MethodReplacementActionType.cs
Show resolved
Hide resolved
…unt for the new projects.
src/Datadog.Trace.ClrProfiler.Managed.Core/Datadog.Trace.ClrProfiler.Managed.Core.csproj
Show resolved
Hide resolved
lucaspimentel
approved these changes
Mar 11, 2020
src/Datadog.Trace.ClrProfiler.Managed.Core/MethodReplacementActionType.cs
Show resolved
Hide resolved
bobuva
approved these changes
Mar 11, 2020
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
…atadog.Trace.ClrProfiler.Managed.Core to AssemblyVersion 1.0.0.0
MikeGoldsmith
pushed a commit
to lightstep/ls-trace-dotnet
that referenced
this pull request
Mar 20, 2020
Fix FileLoadException: Loading this assembly would produce a different grant set from other instances. (Exception from HRESULT: 0x80131401) ## Problem ### Issue 1 Our CLR Profiler currently assumes that as long as the `Datadog.Trace.ClrProfiler.Managed` assembly has been loaded domain-neutral once, all AppDomains can use that assembly. Under this false assumption, we always instrument domain-neutral assemblies which adds an AssemblyReference to our managed profiler and affects how the CLR shares code between AppDomains. However, some applications may have BindingRedirect's specified on dependencies of the managed profiler like `System.Net.Http` which can force `Datadog.Trace.ClrProfiler.Managed` to no longer be loaded domain-neutral. When we instrument a domain-neutral assembly with a non-domain-neutral `Datadog.Trace.ClrProfiler.Managed` in one AppDomain and then another AppDomain tries to use the instrumented domain-neutral assembly, the second AppDomain crashes with the FileLoadException. ### Issue 2 Our new mechanism for automatically instrumenting AspNet uses the CLR Profiler to intercept a method call inside `System.Web` to call into `Datadog.Trace.ClrProfiler.Managed`. `System.Web` is always loaded domain-neutral but, as noted above, there are circumstances that can cause our assembly to not be loaded domain-neutral. We need to change the way we invoke the AspNet integration so that the assembly that runs the integration code is always domain-neutral. ## Changes proposed in this pull request: ### Addressing Issue 1 - Modify the profiler to never inject method calls to `Datadog.Trace.ClrProfiler.Managed` if the calling assembly was loaded domain-neutral. ### Addressing Issue 2 - Move basic types like `InterceptMethodAttribute` and friends to a new `Datadog.Trace.ClrProfiler.Managed.Core` that has no external dependencies. - Move the AspNet integration into a new assembly called `Datadog.Trace.AspNet.Loader` whose only dependencies are `Datadog.Trace.ClrProfiler.Managed.Core` and `System.Web`. This assembly closure guarantees that the assembly will always be loaded domain-neutral. This is now a safe entry point for `System.Web` to call into during application setup. Also, the method responsible for adding the AspNet integration does not wrap any methods (that would require `Sigil`). - To enable the minimal method call above that is simply called and returns to the caller without wrapping any target method, modify the method replacement infrastructure to support an `action`. The default value is `ReplaceTargetMethod` which performs the usual method replacement as before, but a new action `InsertFirst` will add a call to the method as the first instruction in the matching caller method. When generating `integrations.json`, add checks on the new `InsertFirst` integration methods. ## Consequences - Fix `Loading this assembly would produce a different grant set from other instances. (Exception from HRESULT: 0x80131401)` - For ASP.NET applications (or other scenarios where `LoaderOptimizationAttribute=MultiDomainHost`), there may be missing spans from calls between framework assemblies. Affected integrations include: - HttpMessageHandler - WebRequest - Wcf (server)
MikeGoldsmith
pushed a commit
to lightstep/ls-trace-dotnet
that referenced
this pull request
Mar 27, 2020
Fix FileLoadException: Loading this assembly would produce a different grant set from other instances. (Exception from HRESULT: 0x80131401) ## Problem ### Issue 1 Our CLR Profiler currently assumes that as long as the `Datadog.Trace.ClrProfiler.Managed` assembly has been loaded domain-neutral once, all AppDomains can use that assembly. Under this false assumption, we always instrument domain-neutral assemblies which adds an AssemblyReference to our managed profiler and affects how the CLR shares code between AppDomains. However, some applications may have BindingRedirect's specified on dependencies of the managed profiler like `System.Net.Http` which can force `Datadog.Trace.ClrProfiler.Managed` to no longer be loaded domain-neutral. When we instrument a domain-neutral assembly with a non-domain-neutral `Datadog.Trace.ClrProfiler.Managed` in one AppDomain and then another AppDomain tries to use the instrumented domain-neutral assembly, the second AppDomain crashes with the FileLoadException. ### Issue 2 Our new mechanism for automatically instrumenting AspNet uses the CLR Profiler to intercept a method call inside `System.Web` to call into `Datadog.Trace.ClrProfiler.Managed`. `System.Web` is always loaded domain-neutral but, as noted above, there are circumstances that can cause our assembly to not be loaded domain-neutral. We need to change the way we invoke the AspNet integration so that the assembly that runs the integration code is always domain-neutral. ## Changes proposed in this pull request: ### Addressing Issue 1 - Modify the profiler to never inject method calls to `Datadog.Trace.ClrProfiler.Managed` if the calling assembly was loaded domain-neutral. ### Addressing Issue 2 - Move basic types like `InterceptMethodAttribute` and friends to a new `Datadog.Trace.ClrProfiler.Managed.Core` that has no external dependencies. - Move the AspNet integration into a new assembly called `Datadog.Trace.AspNet.Loader` whose only dependencies are `Datadog.Trace.ClrProfiler.Managed.Core` and `System.Web`. This assembly closure guarantees that the assembly will always be loaded domain-neutral. This is now a safe entry point for `System.Web` to call into during application setup. Also, the method responsible for adding the AspNet integration does not wrap any methods (that would require `Sigil`). - To enable the minimal method call above that is simply called and returns to the caller without wrapping any target method, modify the method replacement infrastructure to support an `action`. The default value is `ReplaceTargetMethod` which performs the usual method replacement as before, but a new action `InsertFirst` will add a call to the method as the first instruction in the matching caller method. When generating `integrations.json`, add checks on the new `InsertFirst` integration methods. ## Consequences - Fix `Loading this assembly would produce a different grant set from other instances. (Exception from HRESULT: 0x80131401)` - For ASP.NET applications (or other scenarios where `LoaderOptimizationAttribute=MultiDomainHost`), there may be missing spans from calls between framework assemblies. Affected integrations include: - HttpMessageHandler - WebRequest - Wcf (server)
zacharycmontoya
added a commit
that referenced
this pull request
Apr 3, 2020
…ain-neutral assemblies (#690) Add new CLR Profiler environment variable `DD_TRACE_DOMAIN_NEUTRAL_INSTRUMENTATION` to override the default instrumentation behavior introduced in #671. The default behavior refuses to instrument a method call inside a domain-neutral assembly, which completely avoids the scenario that can cause a sharing violation (`HRESULT 0x80131401`) seen in #592. However, as noted in the original PR, this can cause some callsites for the HttpMessageHandler, WebClient, and WCF integrations to not be instrumented when the application is hosted in IIS. As a temporary measure to receive the same spans before upgrading to .NET Tracer v1.14.2, this new environment variable can safely be set under one condition: **all IIS Application Pools on the machine have at most one application.** Additional changes in this PR include: - Test the `DD_TRACE_DOMAIN_NEUTRAL_INSTRUMENTATION` flag by: - Modifying Samples.HttpMessageHandler to use `LoaderOptimization.MultiDomainHost` when run on .NET Framework. This simulates IIS where Framework assemblies in the GAC are loaded in domain-neutral. - Injecting the environment variable into the Samples.HttpMessageHandler integration test case - Adding `Datadog.Trace.ClrProfiler.Managed.dll` and its dependencies to the GAC before executing the integration tests - Small fix in `MockTracerAgent` to always get the next port from the `TcpPortProvider` instead of incrementing the port number by 1
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
area:automatic-instrumentation
Automatic instrumentation managed C# code (Datadog.Trace.ClrProfiler.Managed)
area:native-library
Automatic instrumentation native C++ code (Datadog.Trace.ClrProfiler.Native)
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
Issue 1
Our CLR Profiler currently assumes that as long as the
Datadog.Trace.ClrProfiler.Managed
assembly has been loaded domain-neutral once, all AppDomains can use that assembly. Under this false assumption, we always instrument domain-neutral assemblies which adds an AssemblyReference to our managed profiler and affects how the CLR shares code between AppDomains.However, some applications may have BindingRedirect's specified on dependencies of the managed profiler like
System.Net.Http
which can forceDatadog.Trace.ClrProfiler.Managed
to no longer be loaded domain-neutral. When we instrument a domain-neutral assembly with a non-domain-neutralDatadog.Trace.ClrProfiler.Managed
in one AppDomain and then another AppDomain tries to use the instrumented domain-neutral assembly, the second AppDomain crashes with the FileLoadException.Issue 2
Our new mechanism for automatically instrumenting AspNet uses the CLR Profiler to intercept a method call inside
System.Web
to call intoDatadog.Trace.ClrProfiler.Managed
.System.Web
is always loaded domain-neutral but, as noted above, there are circumstances that can cause our assembly to not be loaded domain-neutral. We need to change the way we invoke the AspNet integration so that the assembly that runs the integration code is always domain-neutral.Changes proposed in this pull request:
Addressing Issue 1
Datadog.Trace.ClrProfiler.Managed
if the calling assembly was loaded domain-neutral.Addressing Issue 2
InterceptMethodAttribute
and friends to a newDatadog.Trace.ClrProfiler.Managed.Core
that has no external dependencies.Datadog.Trace.AspNet.Loader
whose only dependencies areDatadog.Trace.ClrProfiler.Managed.Core
andSystem.Web
. This assembly closure guarantees that the assembly will always be loaded domain-neutral. This is now a safe entry point forSystem.Web
to call into during application setup. Also, the method responsible for adding the AspNet integration does not wrap any methods (that would requireSigil
).action
. The default value isReplaceTargetMethod
which performs the usual method replacement as before, but a new actionInsertFirst
will add a call to the method as the first instruction in the matching caller method. When generatingintegrations.json
, add checks on the newInsertFirst
integration methods.Consequences
Loading this assembly would produce a different grant set from other instances. (Exception from HRESULT: 0x80131401)
LoaderOptimizationAttribute=MultiDomainHost
), there may be missing spans from calls between framework assemblies. Affected integrations include:@DataDog/apm-dotnet