Skip to content

[Tracer] Exit early during automatic instrumentation when the application is .NET Core 1.x#3114

Merged
zacharycmontoya merged 1 commit into
masterfrom
zach/fix/exit-gracefully-netcore1x
Aug 23, 2022
Merged

[Tracer] Exit early during automatic instrumentation when the application is .NET Core 1.x#3114
zacharycmontoya merged 1 commit into
masterfrom
zach/fix/exit-gracefully-netcore1x

Conversation

@zacharycmontoya

@zacharycmontoya zacharycmontoya commented Aug 22, 2022

Copy link
Copy Markdown
Contributor

Summary of changes

Adds logic to exit initialization of the native Tracer CLR Profiler when a .NET Core 1.x process is detected.

Reason for change

Without this fix, the tracer's managed loader fails to initialize when running on .NET Core 1.0 or .NET Core 1.1 because the managed loader is built against .NET Core 2.0 and it exhibits the following stack trace:

Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'System.Runtime, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
   at System.Reflection.RuntimeAssembly.GetType(RuntimeAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type, ObjectHandleOnStack keepAlive)
   at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
   at System.Reflection.Assembly.CreateInstance(String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
   at System.Reflection.Assembly.CreateInstance(String typeName)
   at __DDVoidMethodType__.__DDVoidMethodCall__()
   at console_app.Program.Main(String[] args)

Even though our public documentation indicates support begins at .NET Core 2.1, it's possible for the environment variables to be set machine-wide and enable automatic instrumentation for .NET Core 1.x applications.

Implementation details

Fortunately for us, the ICorProfilerInfo8 interface was added in .NET Core 2.0 so we can check whether the interface is present to determine if the application is running on .NET Core 1.x. If the interface is not present and the runtime is CoreCLR, we exit the native tracer's initialization and log warning message.

Test coverage

Confirmed the following test cases locally:

  • .NET Core 1.0 app no longer crashes when automatic instrumentation is enabled
  • .NET Core 1.1 app no longer crashes when automatic instrumentation is enabled
  • .NET Core 2.0 app continues to run successfully
  • .NET Framework app executed by .NET Framework 4.6.1 continues to run successfully
    • This was tested because the ICorProfilerInfo8 interface involved in the new check was not introduced in .NET Framework until 4.7.2, so the test ensured that the CoreCLR runtime part of the check was correct.

No regression tests have been added because I'm not sure if it's worth installing the .NET Core 1.0 SDK to run one test application.

Other details

N/A

…en a .NET Core 1.x process is detected, instead of crashing during the tracer managed loader initialization
@zacharycmontoya
zacharycmontoya requested a review from a team as a code owner August 22, 2022 21:40
@zacharycmontoya zacharycmontoya self-assigned this Aug 22, 2022
@andrewlock

Copy link
Copy Markdown
Member

Benchmarks Report 🐌

Benchmarks for #3114 compared to master:

  • All benchmarks have the same speed
  • All benchmarks have the same allocations

The following thresholds were used for comparing the benchmark speeds:

  • Mann–Whitney U test with statistical test for significance of 5%
  • Only results indicating a difference greater than 10% and 0.3 ns are considered.

Allocation changes below 0.5% are ignored.

Benchmark details

Benchmarks.Trace.AgentWriterBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master WriteAndFlushEnrichedTraces net472 725μs 284ns 1.06μs 0.361 0 0 3.18 KB
master WriteAndFlushEnrichedTraces netcoreapp3.1 477μs 121ns 437ns 0 0 0 2.58 KB
#3114 WriteAndFlushEnrichedTraces net472 740μs 362ns 1.4μs 0.363 0 0 3.18 KB
#3114 WriteAndFlushEnrichedTraces netcoreapp3.1 451μs 63.9ns 221ns 0 0 0 2.59 KB
Benchmarks.Trace.AppSecBodyBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master AllCycleSimpleBody net472 182ns 0.136ns 0.51ns 0.0675 9.1E-05 0 425 B
master AllCycleSimpleBody netcoreapp3.1 234ns 0.338ns 1.31ns 0.00576 0 0 424 B
master AllCycleMoreComplexBody net472 179ns 0.0918ns 0.343ns 0.0637 0 0 401 B
master AllCycleMoreComplexBody netcoreapp3.1 238ns 0.203ns 0.784ns 0.0055 0 0 400 B
master BodyExtractorSimpleBody net472 270ns 0.951ns 3.68ns 0.0573 0 0 361 B
master BodyExtractorSimpleBody netcoreapp3.1 232ns 0.157ns 0.589ns 0.0037 0 0 272 B
master BodyExtractorMoreComplexBody net472 14.3μs 13ns 50.4ns 1.21 0.0215 0 7.62 KB
master BodyExtractorMoreComplexBody netcoreapp3.1 12.4μs 13ns 48.8ns 0.093 0 0 6.75 KB
#3114 AllCycleSimpleBody net472 184ns 0.115ns 0.415ns 0.0676 9.18E-05 0 425 B
#3114 AllCycleSimpleBody netcoreapp3.1 241ns 0.343ns 1.33ns 0.00563 0 0 424 B
#3114 AllCycleMoreComplexBody net472 180ns 0.189ns 0.733ns 0.0637 0 0 401 B
#3114 AllCycleMoreComplexBody netcoreapp3.1 236ns 0.335ns 1.3ns 0.00548 0 0 400 B
#3114 BodyExtractorSimpleBody net472 275ns 0.414ns 1.49ns 0.0573 0 0 361 B
#3114 BodyExtractorSimpleBody netcoreapp3.1 254ns 0.414ns 1.6ns 0.00377 0 0 272 B
#3114 BodyExtractorMoreComplexBody net472 14.5μs 10.6ns 41ns 1.2 0.0218 0 7.62 KB
#3114 BodyExtractorMoreComplexBody netcoreapp3.1 12.5μs 8.77ns 32.8ns 0.0867 0 0 6.75 KB
Benchmarks.Trace.AspNetCoreBenchmark - Unknown 🤷 Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master SendRequest net472 0ns 0ns 0ns 0 0 0 0 b
master SendRequest netcoreapp3.1 178μs 143ns 555ns 0.268 0 0 20.33 KB
#3114 SendRequest net472 0ns 0ns 0ns 0 0 0 0 b
#3114 SendRequest netcoreapp3.1 178μs 222ns 858ns 0.268 0 0 20.34 KB
Benchmarks.Trace.DbCommandBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master ExecuteNonQuery net472 1.6μs 0.673ns 2.43ns 0.126 0.000793 0 794 B
master ExecuteNonQuery netcoreapp3.1 1.22μs 0.293ns 1.01ns 0.011 0 0 824 B
#3114 ExecuteNonQuery net472 1.59μs 0.56ns 2.17ns 0.126 0.000792 0 794 B
#3114 ExecuteNonQuery netcoreapp3.1 1.29μs 0.432ns 1.5ns 0.011 0 0 824 B
Benchmarks.Trace.ElasticsearchBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master CallElasticsearch net472 2.16μs 0.55ns 2.06ns 0.159 0 0 1 KB
master CallElasticsearch netcoreapp3.1 1.4μs 0.417ns 1.5ns 0.0126 0 0 984 B
master CallElasticsearchAsync net472 2.31μs 1.59ns 5.95ns 0.18 0 0 1.14 KB
master CallElasticsearchAsync netcoreapp3.1 1.45μs 0.933ns 3.61ns 0.0146 0 0 1.1 KB
#3114 CallElasticsearch net472 2.18μs 0.689ns 2.67ns 0.159 0 0 1 KB
#3114 CallElasticsearch netcoreapp3.1 1.34μs 2.75ns 10.7ns 0.0133 0 0 984 B
#3114 CallElasticsearchAsync net472 2.43μs 0.979ns 3.79ns 0.181 0 0 1.14 KB
#3114 CallElasticsearchAsync netcoreapp3.1 1.48μs 0.444ns 1.66ns 0.0148 0 0 1.1 KB
Benchmarks.Trace.GraphQLBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master ExecuteAsync net472 2.31μs 2.68ns 10ns 0.2 0 0 1.26 KB
master ExecuteAsync netcoreapp3.1 1.56μs 2.27ns 8.49ns 0.0165 0 0 1.22 KB
#3114 ExecuteAsync net472 2.41μs 6.81ns 26.4ns 0.199 0 0 1.26 KB
#3114 ExecuteAsync netcoreapp3.1 1.6μs 1.5ns 5.82ns 0.016 0 0 1.22 KB
Benchmarks.Trace.HttpClientBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master SendAsync net472 4.97μs 7.37ns 28.6ns 0.392 0 0 2.48 KB
master SendAsync netcoreapp3.1 3.19μs 4.01ns 15ns 0.032 0 0 2.36 KB
#3114 SendAsync net472 4.89μs 13.9ns 51.9ns 0.393 0 0 2.48 KB
#3114 SendAsync netcoreapp3.1 3.25μs 4.56ns 17ns 0.0326 0 0 2.36 KB
Benchmarks.Trace.ILoggerBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net472 3μs 1.72ns 6.65ns 0.263 0 0 1.66 KB
master EnrichedLog netcoreapp3.1 2.37μs 1.12ns 4.35ns 0.0237 0 0 1.73 KB
#3114 EnrichedLog net472 2.75μs 1.53ns 5.94ns 0.263 0 0 1.66 KB
#3114 EnrichedLog netcoreapp3.1 2.32μs 1.91ns 7.39ns 0.0236 0 0 1.73 KB
Benchmarks.Trace.Log4netBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net472 150μs 245ns 947ns 0.679 0.226 0 4.5 KB
master EnrichedLog netcoreapp3.1 116μs 101ns 390ns 0.058 0 0 4.38 KB
#3114 EnrichedLog net472 150μs 188ns 727ns 0.679 0.226 0 4.5 KB
#3114 EnrichedLog netcoreapp3.1 114μs 234ns 905ns 0.0571 0 0 4.38 KB
Benchmarks.Trace.NLogBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net472 5.42μs 14.3ns 51.6ns 0.545 0.0027 0 3.43 KB
master EnrichedLog netcoreapp3.1 4.15μs 14ns 54.1ns 0.0513 0 0 3.8 KB
#3114 EnrichedLog net472 5.29μs 12.6ns 48.8ns 0.545 0.00267 0 3.43 KB
#3114 EnrichedLog netcoreapp3.1 4.41μs 9.43ns 36.5ns 0.0507 0 0 3.8 KB
Benchmarks.Trace.RedisBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master SendReceive net472 2.07μs 2.16ns 8.37ns 0.193 0 0 1.22 KB
master SendReceive netcoreapp3.1 1.67μs 0.624ns 2.42ns 0.0158 0 0 1.21 KB
#3114 SendReceive net472 2.02μs 0.71ns 2.46ns 0.193 0 0 1.22 KB
#3114 SendReceive netcoreapp3.1 1.63μs 4.43ns 16.6ns 0.017 0 0 1.21 KB
Benchmarks.Trace.SerilogBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master EnrichedLog net472 4.7μs 1.77ns 6.86ns 0.329 0 0 2.08 KB
master EnrichedLog netcoreapp3.1 4.22μs 2.27ns 8.8ns 0.0212 0 0 1.69 KB
#3114 EnrichedLog net472 4.71μs 1.75ns 6.79ns 0.33 0 0 2.08 KB
#3114 EnrichedLog netcoreapp3.1 4.09μs 1.88ns 6.5ns 0.0224 0 0 1.69 KB
Benchmarks.Trace.SpanBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master StartFinishSpan net472 911ns 0.477ns 1.72ns 0.104 0 0 658 B
master StartFinishSpan netcoreapp3.1 719ns 0.257ns 0.995ns 0.00864 0 0 648 B
master StartFinishScope net472 1.12μs 0.525ns 2.03ns 0.117 0 0 738 B
master StartFinishScope netcoreapp3.1 909ns 0.395ns 1.42ns 0.0105 0 0 768 B
#3114 StartFinishSpan net472 944ns 0.231ns 0.864ns 0.105 0 0 658 B
#3114 StartFinishSpan netcoreapp3.1 779ns 0.432ns 1.62ns 0.00862 0 0 648 B
#3114 StartFinishScope net472 1.13μs 2.45ns 9.18ns 0.117 0 0 738 B
#3114 StartFinishScope netcoreapp3.1 881ns 0.684ns 2.47ns 0.0101 0 0 768 B
Benchmarks.Trace.TraceAnnotationsBenchmark - Same speed ✔️ Same allocations ✔️

Raw results

Branch Method Toolchain Mean StdError StdDev Gen 0 Gen 1 Gen 2 Allocated
master RunOnMethodBegin net472 1.26μs 0.497ns 1.92ns 0.117 0 0 738 B
master RunOnMethodBegin netcoreapp3.1 1.06μs 0.658ns 2.55ns 0.0105 0 0 768 B
#3114 RunOnMethodBegin net472 1.17μs 0.333ns 1.25ns 0.117 0 0 738 B
#3114 RunOnMethodBegin netcoreapp3.1 974ns 0.354ns 1.28ns 0.0103 0 0 768 B

@andrewlock

Copy link
Copy Markdown
Member

Code Coverage Report 📊

✔️ Merging #3114 into master will not change line coverage
✔️ Merging #3114 into master will not change branch coverage
✔️ Merging #3114 into master will not change complexity

master #3114 Change
Lines 16911 / 23281 16887 / 23281
Lines % 73% 73% 0% ✔️
Branches 10092 / 14362 10092 / 14362
Branches % 70% 70% 0% ✔️
Complexity 15458 15458 0 ✔️

View the full report for further details:

Datadog.Trace Breakdown ✔️

master #3114 Change
Lines % 73% 73% 0% ✔️
Branches % 70% 70% 0% ✔️
Complexity 15458 15458 0 ✔️

The following classes have significant coverage changes.

File Line coverage change Branch coverage change Complexity change
Datadog.Trace.Ci.GitInfo -17% -11% 0 ✔️
Datadog.Trace.Ci.CIVisibility 5% ✔️ 6% ✔️ 0 ✔️

View the full reports for further details:

@andrewlock andrewlock left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@zacharycmontoya
zacharycmontoya merged commit 9fb2754 into master Aug 23, 2022
@zacharycmontoya
zacharycmontoya deleted the zach/fix/exit-gracefully-netcore1x branch August 23, 2022 14:37
@github-actions github-actions Bot added this to the vNext milestone Aug 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants