[Dynamic Instrumentation] Avoid async instrumentation if the type AsyncMethodDebuggerInvokerV2 does not exist#7513
Conversation
AsyncMethodDebuggerInvokerV2 does not existAsyncMethodDebuggerInvokerV2 does not exist
828b76a to
7c4a455
Compare
7c4a455 to
4269588
Compare
Execution-Time Benchmarks Report ⏱️Execution-time results for samples comparing the following branches/commits: Execution-time benchmarks measure the whole time it takes to execute a program. And are intended to measure the one-off costs. Cases where the execution time results for the PR are worse than latest master results are shown in red. The following thresholds were used for comparing the execution times:
Note that these results are based on a single point-in-time result for each branch. For full results, see the dashboard. Graphs show the p99 interval based on the mean and StdDev of the test run, as well as the mean value of the run (shown as a diamond below the graph). gantt
title Execution time (ms) FakeDbCommand (.NET Framework 4.8)
dateFormat X
axisFormat %s
todayMarker off
section Bailout
This PR (7513) - mean (72ms) : 71, 73
. : milestone, 72,
master - mean (72ms) : 71, 73
. : milestone, 72,
section Baseline
This PR (7513) - mean (69ms) : 64, 73
. : milestone, 69,
master - mean (70ms) : 63, 76
. : milestone, 70,
section CallTarget+Inlining+NGEN
This PR (7513) - mean (1,001ms) : 979, 1022
. : milestone, 1001,
master - mean (999ms) : 976, 1021
. : milestone, 999,
gantt
title Execution time (ms) FakeDbCommand (.NET Core 3.1)
dateFormat X
axisFormat %s
todayMarker off
section Bailout
This PR (7513) - mean (107ms) : 106, 108
. : milestone, 107,
master - mean (107ms) : 105, 108
. : milestone, 107,
section Baseline
This PR (7513) - mean (106ms) : 104, 109
. : milestone, 106,
master - mean (106ms) : 104, 108
. : milestone, 106,
section CallTarget+Inlining+NGEN
This PR (7513) - mean (706ms) : 685, 726
. : milestone, 706,
master - mean (705ms) : 685, 726
. : milestone, 705,
gantt
title Execution time (ms) FakeDbCommand (.NET 6)
dateFormat X
axisFormat %s
todayMarker off
section Bailout
This PR (7513) - mean (94ms) : 93, 95
. : milestone, 94,
master - mean (94ms) : 93, 95
. : milestone, 94,
section Baseline
This PR (7513) - mean (94ms) : 91, 96
. : milestone, 94,
master - mean (93ms) : 92, 95
. : milestone, 93,
section CallTarget+Inlining+NGEN
This PR (7513) - mean (664ms) : 644, 684
. : milestone, 664,
master - mean (664ms) : 644, 684
. : milestone, 664,
gantt
title Execution time (ms) FakeDbCommand (.NET 8)
dateFormat X
axisFormat %s
todayMarker off
section Bailout
This PR (7513) - mean (93ms) : 92, 94
. : milestone, 93,
master - mean (93ms) : 92, 94
. : milestone, 93,
section Baseline
This PR (7513) - mean (92ms) : 90, 95
. : milestone, 92,
master - mean (92ms) : 90, 94
. : milestone, 92,
section CallTarget+Inlining+NGEN
This PR (7513) - mean (597ms) : 586, 607
. : milestone, 597,
master - mean (600ms) : 584, 617
. : milestone, 600,
gantt
title Execution time (ms) HttpMessageHandler (.NET Framework 4.8)
dateFormat X
axisFormat %s
todayMarker off
section Bailout
This PR (7513) - mean (198ms) : 194, 201
. : milestone, 198,
master - mean (194ms) : 191, 198
. : milestone, 194,
section Baseline
This PR (7513) - mean (193ms) : 189, 196
. : milestone, 193,
master - mean (191ms) : 183, 199
. : milestone, 191,
section CallTarget+Inlining+NGEN
This PR (7513) - mean (1,128ms) : 1096, 1160
. : milestone, 1128,
master - mean (1,104ms) : 1071, 1137
. : milestone, 1104,
gantt
title Execution time (ms) HttpMessageHandler (.NET Core 3.1)
dateFormat X
axisFormat %s
todayMarker off
section Bailout
This PR (7513) - mean (282ms) : 277, 287
. : milestone, 282,
master - mean (276ms) : 268, 283
. : milestone, 276,
section Baseline
This PR (7513) - mean (279ms) : 273, 285
. : milestone, 279,
master - mean (274ms) : 265, 283
. : milestone, 274,
section CallTarget+Inlining+NGEN
This PR (7513) - mean (908ms) : 880, 935
. : milestone, 908,
master - mean (890ms) : 852, 929
. : milestone, 890,
gantt
title Execution time (ms) HttpMessageHandler (.NET 6)
dateFormat X
axisFormat %s
todayMarker off
section Bailout
This PR (7513) - mean (274ms) : 269, 279
. : milestone, 274,
master - mean (267ms) : 262, 273
. : milestone, 267,
section Baseline
This PR (7513) - mean (274ms) : 269, 280
. : milestone, 274,
master - mean (267ms) : 262, 273
. : milestone, 267,
section CallTarget+Inlining+NGEN
This PR (7513) - mean (895ms) : 864, 925
. : milestone, 895,
master - mean (873ms) : 832, 913
. : milestone, 873,
gantt
title Execution time (ms) HttpMessageHandler (.NET 8)
dateFormat X
axisFormat %s
todayMarker off
section Bailout
This PR (7513) - mean (273ms) : 268, 278
. : milestone, 273,
master - mean (266ms) : 261, 271
. : milestone, 266,
section Baseline
This PR (7513) - mean (274ms) : 268, 280
. : milestone, 274,
master - mean (265ms) : 258, 271
. : milestone, 265,
section CallTarget+Inlining+NGEN
This PR (7513) - mean (803ms) : 780, 826
. : milestone, 803,
master - mean (782ms) : 761, 803
. : milestone, 782,
|
…e) is not applied if AsyncMethodDebuggerInvokerV2 is not present in loaded Datadog.Trace
4269588 to
91fd7fd
Compare
| // Also defined in `debugger_tokens.h` as `managed_profiler_debugger_async_method_invoker_type` | ||
| const shared::WSTRING asyncmethoddebuggerinvokerv2_type_name = WStr("Datadog.Trace.Debugger.Instrumentation.AsyncMethodDebuggerInvokerV2"); | ||
|
|
There was a problem hiding this comment.
Why do we need to define it twice? 🤔
andrewlock
left a comment
There was a problem hiding this comment.
LGTM on the non-debugger side (I defer to you on the correctness of that) but I'll let @tonyredondo weigh in too seeing as it's native code 😄
Summary of changes
In #7441, the injected field of async methods has been changed from
AsyncDebuggerStatetoSystem.Object. In this PR, we make sure instrumentation is not being applied if the loadedDatadog.Tracedoes not contain the new signatures that acceptSystem.Objectfor log/span probes.Reason for change & Implementation
Avoid instrumentation of async methods if the loaded
Datadog.Traceis an old version that does not contain the new signatures introduced in #7441.The only place where we can change the layout of a type is in
ModuleLoadFinished, this is why injection of our field is done there. This callback is fired by the runtime when a new module is being loaded. Modules of interest (including application's main module) may load before our managed loader had a chance to resolve and load our managedDatadog.Traceassembly into the application. The fact that at injection time we don't know if and which version ofDatadog.Traceis going to be loaded, we cannot guarantee that the new signatures will be there. OnceDatadog.Traceactually loads, we try to lookup for the existence of the typeAsyncMethodDebuggerInvokerV2as an anchor to know if the new signatures are there. If the type does not exist, we skip instrumentation on async methods (as there are no methods that accept the newly injectedSystem.Object), log appropriate message and emit probe status with a message that invites the customer to upgradeDatadog.Trace. In the case of bailing out our async instrumentation, the injectedSystem.Objectfield will effectively be a NOP.