close
Skip to content

Tags: DataDog/dd-trace-dotnet

Tags

v3.49.0

Toggle v3.49.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
[Tests] Handle UTF-16 output from ProcDump v12.01 (#8890)

## Summary of changes

Normalize ProcDump output before evaluating its startup and shutdown
messages.

## Reason for change

Windows x64 integration tests started hanging after the unversioned
Microsoft download began serving ProcDump v12.01.

The test harness:

1. Starts the instrumented process in a suspended state.
2. Attaches ProcDump.
3. Waits for ProcDump’s readiness message.
4. Resumes the instrumented process.

ProcDump v12.01 emits redirected output as UTF-16. The test helper read
this with embedded null characters, such as `P\0r\0e\0s\0s...`.
Consequently, the exact readiness-message comparison failed and the
instrumented process remained suspended indefinitely.

The same encoding change prevented the helper from recognizing the
normal `"Dump count not reached"` shutdown message. It therefore treated
normal shutdown as abnormal and logged ProcDump’s entire buffered
exception history.

This primarily affected x64 tests because ProcDump crash monitoring is
disabled for x86 tests.

## Implementation details

- Remove embedded null characters before comparing ProcDump’s readiness
message.
- Normalize buffered stdout and stderr after ProcDump exits.
- Use normalized stdout for readiness and dump-count checks.
- Log normalized output only when a dump occurred or ProcDump exited
unexpectedly.

Output from older ProcDump versions is unchanged because removing null
characters is a no-op.

## Test coverage

Tested locally with:


`Datadog.Trace.Security.IntegrationTests.AspNetCore5BlockingTemplatesJson.TestGet`

- **ProcDump v12.0 with the original code:** Passed without excessive
ProcDump logging.
- **ProcDump v12.01 with the original code:** Reproduced the hang.
ProcDump attached successfully, but the target remained suspended with
one thread and zero CPU.
- **ProcDump v12.01 with this change:** Passed without logging the full
ProcDump exception buffer.

## Other details

This only changes test infrastructure behavior. Crash-dump monitoring
remains enabled, and this change does not pin a ProcDump version.

#incident-57303

<!-- Fixes #{issue} -->


<!--  ⚠️ Note:

Where possible, please obtain 2 approvals prior to merging. Unless
CODEOWNERS specifies otherwise, for external teams it is typically best
to have one review from a team member, and one review from apm-dotnet.
Trivial changes do not require 2 reviews.

MergeQueue is NOT enabled in this repository. If you have write access
to the repo, the PR has 1-2 approvals (see above), and all of the
required checks have passed, you can use the Squash and Merge button to
merge the PR. If you don't have write access, or you need help, reach
out in the #apm-dotnet channel in Slack.
-->

v3.48.0

Toggle v3.48.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
[CI] Add net10.0 to AWS Lambda test runtimes (#8819)

## Summary of changes

Add `net10.0` to the .NET TFMs used in AWS Lambda tests.

## Reason for change

We support .NET 10, so the AWS Lambda tests should run against it.

## Implementation details

- add a `net10` matrix entry (`net10.0` TFM,
`public.ecr.aws/lambda/dotnet:10` base image) to the AWS Lambda test
stage in `ultimate-pipeline.yml`
- existing `net6`/`net7`/`net8`/`net9` entries are unchanged

## Test coverage

This PR adds a runtime version that the existing AWS Lambda tests run
on.

## Other details
<!-- Fixes #{issue} -->
n/a

> *"net6 and net7 walked back in like they forgot their keys. We let
them stay and gave net10 the spare bedroom."* — Claude 🤖


<!--  ⚠️ Note:

Where possible, please obtain 2 approvals prior to merging. Unless
CODEOWNERS specifies otherwise, for external teams it is typically best
to have one review from a team member, and one review from apm-dotnet.
Trivial changes do not require 2 reviews.

MergeQueue is NOT enabled in this repository. If you have write access
to the repo, the PR has 1-2 approvals (see above), and all of the
required checks have passed, you can use the Squash and Merge button to
merge the PR. If you don't have write access, or you need help, reach
out in the #apm-dotnet channel in Slack.
-->

v3.47.0

Toggle v3.47.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
[Debugger] Avoid instantiating state machine attributes (#8816)

## Summary of changes
- Add a debugger helper that reads compiler state-machine attributes
through `CustomAttributeData` instead of constructing attribute
instances.
- Use the helper in exception replay method matching, async kickoff
method lookup, fully-qualified method name resolution, and ILAnalyzer
async `MoveNext` selection.
- Add regression coverage for overloaded async method matching with a
custom method attribute whose constructor must not run.

## Reason for change
Debugger state-machine resolution only needs compiler metadata such as
`AsyncStateMachineAttribute`, `IteratorStateMachineAttribute`, and
`AsyncIteratorStateMachineAttribute`. Instantiating attributes can
execute user attribute constructors, so these resolution paths should
stay metadata-only.

## Implementation details
The helper compares attribute type full names and reads the
state-machine type from `CustomAttributeData.ConstructorArguments`. It
preserves the previous async/iterator behavior, including marking
iterator and async-iterator state machines so `GetFullyQualifiedName()`
still appends the `+MoveNext()` annotation where expected.

## Test coverage
- `MethodMatcherTests|ILAnalyzerTests`

---------

Co-authored-by: Cursor <cursoragent@cursor.com>

v3.46.0

Toggle v3.46.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
[Profiler] Improve memory consumption `LibrariesInfoCache` (#8777)

## Summary of changes

Improve memory overhead of the `LibrariesCacheInfo`.

## Reason for change

`LibrariesCacheInfo` component caches ELF symbols to improve stack
walking. But this comes at a cost CPU + Memory.

Today (master)
```
[2026-06-11 10:58:49.687 | info | PId: 140997 | TId: 140997] LibrariesInfoCache stats:
[2026-06-11 10:58:49.687 | info | PId: 140997 | TId: 140997]   Cache reloads: 10
[2026-06-11 10:58:49.687 | info | PId: 140997 | TId: 140997]   Total CPU (worker): 42 ms
[2026-06-11 10:58:49.687 | info | PId: 140997 | TId: 140997]   Libraries in cache: 21
[2026-06-11 10:58:49.687 | info | PId: 140997 | TId: 140997]   Module regions: 18
[2026-06-11 10:58:49.687 | info | PId: 140997 | TId: 140997]   Symbol entries: 27179
[2026-06-11 10:58:49.687 | info | PId: 140997 | TId: 140997]   Memory current: 1410520 bytes
```

We can see a 42ms CPU usage and 1.4MB memory usage for 27179 symbols.
42ms of CPU over the lifetime of the application is totally negligible,
but 1.4MB leaves a mark.

This PR does 2 improvements:
- Replace std::function Deleters
- Compact FuncEntry for ARM64

With this PR
```
[2026-06-11 07:53:01.910 | info | PId: 20347 | TId: 20347] LibrariesInfoCache stats:
[2026-06-11 07:53:01.910 | info | PId: 20347 | TId: 20347]   Cache reloads: 13
[2026-06-11 07:53:01.910 | info | PId: 20347 | TId: 20347]   Total CPU (worker): 57 ms
[2026-06-11 07:53:01.910 | info | PId: 20347 | TId: 20347]   Libraries in cache: 21
[2026-06-11 07:53:01.910 | info | PId: 20347 | TId: 20347]   Module regions: 18
[2026-06-11 07:53:01.910 | info | PId: 20347 | TId: 20347]   Symbol entries: 27179
[2026-06-11 07:53:01.910 | info | PId: 20347 | TId: 20347]   Memory current: 565528 bytes
```

## Implementation details
- Replace std::unique_ptr<T, std::function<void(void*)>> with a trivial
deleter struct `PmrDeleter`
- Store function entries relative to their module base:
Works because: modules are always < 4GB (shared libraries mapped within
32-bit offset range from their base)


## Test coverage

## Other details
<!-- Fixes #{issue} -->


<!--  ⚠️ Note:

Where possible, please obtain 2 approvals prior to merging. Unless
CODEOWNERS specifies otherwise, for external teams it is typically best
to have one review from a team member, and one review from apm-dotnet.
Trivial changes do not require 2 reviews.

MergeQueue is NOT enabled in this repository. If you have write access
to the repo, the PR has 1-2 approvals (see above), and all of the
required checks have passed, you can use the Squash and Merge button to
merge the PR. If you don't have write access, or you need help, reach
out in the #apm-dotnet channel in Slack.
-->

v3.45.0

Toggle v3.45.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
[Opentelemetry] Prevent OTLP array attribute stack overflow on cyclic…

…/deep arrays (#8707)

## Summary of changes
Both OTLP trace serializers (`OtlpTracesProtobufSerializer` and
`OtlpTracesJsonSerializer`) now serialize each `AnyValue` array element
by calling `WriteAnyValue` with `expandArrays: false` instead of
recursing with array expansion enabled. Adds regression tests covering
self-referential, deeply nested, nested `object[]`, and nested `byte[]`
inputs in both serializers.

## Reason for change
`WriteAnyValue` takes a new `bool expandArrays` parameter (default
`true`). When `false` — the value passed for each array element — the
`byte[]` and `Array` cases `goto default;` and stringify via
`Convert.ToString(value, CultureInfo.InvariantCulture)` instead of
recursing. This caps recursion depth at 1 by construction (no cycle
tracker or depth limit needed) and mirrors OTel .NET SDK's
[`TagWriter.WriteToArrayTypeChecked`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/Shared/TagWriter/TagWriter.cs),
whose per-element writer also has no `byte[]`/`Array` case. Top-level
dispatch is unchanged, so only nested-array semantics shift and the
shift aligns dd-trace's output with the OTel SDK. Also splits `ulong`
out of the JSON integer cases so it stringifies (it overflows OTLP
`intValue`/int64), matching the protobuf serializer and the OTel SDK.

## Implementation details
`WriteAnyValue` takes a new `bool expandArrays` parameter (default
`true`). When `false` — the value passed for each array element — the
`byte[]` and `Array` cases `goto default;` and stringify via
`Convert.ToString(value, CultureInfo.InvariantCulture)` instead of
recursing. This caps recursion depth at 1 by construction (no cycle
tracker or depth limit needed) and mirrors OTel .NET SDK's
[`TagWriter.WriteToArrayTypeChecked`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/Shared/TagWriter/TagWriter.cs),
whose per-element writer also has no `byte[]`/`Array` case. Top-level
dispatch is unchanged, so only nested-array semantics shift and the
shift aligns dd-trace's output with the OTel SDK. Also splits `ulong`
out of the JSON integer cases so it stringifies (it overflows OTLP
`intValue`/int64), matching the protobuf serializer and the OTel SDK.

## Test coverage
Four regression tests per serializer:
`SelfReferentialObjectArray_IsBoundedAtOneLevel` (`a[0] = a` no longer
recurses), `DeeplyNestedArray_IsBoundedAtOneLevel` (5 000-deep array
serializes in constant stack),
`NestedObjectArray_StringifiesInsteadOfArrayValue`, and
`NestedByteArray_StringifiesInsteadOfBytesValue`, plus a JSON
`WriteAnyValue_Ulong_EmitsStringValue` test for the `ulong` change. All
existing flat-array tests and the
`OpenTelemetrySdkTests.SubmitsOtlpTraces` integration test pass
unchanged.

v3.44.0

Toggle v3.44.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
[Debugger] Fix Timer leaks and missing rate updates in probe rate lim…

…iter (#8619)

## Summary of changes

Fixes Timer/sampler leaks and a latent rate-update bug in
`ProbeRateLimiter` and `AdaptiveSampler`. `AdaptiveSampler` allocates a
`System.Threading.Timer` that the runtime roots until disposed; three
code paths previously dropped samplers without disposing them, leaking
one Timer (plus captured state) on every probe removal and on every
dictionary insert race. Separately, RCM-driven rate updates were
silently ignored when a sampler already existed.

## Reason for change

- Long-running services using Dynamic Instrumentation accumulate `Timer`
instances on every RCM probe rotation — unbounded growth over the
process lifetime.
- Line probes that go through the unbound → bound transition could end
up stuck at the default rate of 1 because `CheckUnboundProbes`
registered the sampler **after** making the IL live, opening a race
window where the first probe hit inserts a default-rate sampler and the
configured rate is then dropped by `SetRate`.

## Implementation details

- `IAdaptiveSampler` extends `IDisposable`; `AdaptiveSampler.Dispose`
releases the internal `Timer`; `NopAdaptiveSampler.Dispose` is a no-op
(singleton).
- `AdaptiveSampler.SetRate` mutates `_samplesPerWindow` /
`_samplesBudget` in place. Uses the same relaxed memory semantics as the
rest of the class.
- `ProbeRateLimiter.GerOrAddSampler` uses `TryGetValue` → `TryAdd` →
`Dispose-on-lose` instead of `ConcurrentDictionary.GetOrAdd`, which can
invoke its factory multiple times.
- `ProbeRateLimiter.SetRate` applies the new rate to the existing
sampler instead of logging and returning; disposes the candidate if it
loses the insert race.
- `ProbeRateLimiter.ResetRate` disposes the removed sampler.
- `DynamicInstrumentation.CheckUnboundProbes` now registers samplers and
processors **before** calling `DebuggerNativeMethods.InstrumentProbes`,
matching the ordering in `InstrumentAddedProbes` and closing the race at
its source.

## Test coverage

- `AdaptiveSamplerTests` — `SetRate` updates budget and preserves
running stats; `Dispose` is idempotent.
- `ProbeRateLimiterTests` (new) — `SetRate` updates the existing sampler
in place; `ResetRate` disposes the removed sampler; `GerOrAddSampler`
does not dispose existing entries.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>

v3.43.0

Toggle v3.43.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Apply baggage limits on extract (#8555)

## Summary of changes

Honor `DD_TRACE_BAGGAGE_MAX_ITEMS` and `DD_TRACE_BAGGAGE_MAX_BYTES` when
parsing inbound baggage headers

## Reason for change

## Implementation details

## Test coverage

Added unit tests for it.

## Other details
<!-- Fixes #{issue} -->


<!--  ⚠️ Note:

Where possible, please obtain 2 approvals prior to merging. Unless
CODEOWNERS specifies otherwise, for external teams it is typically best
to have one review from a team member, and one review from apm-dotnet.
Trivial changes do not require 2 reviews.

MergeQueue is NOT enabled in this repository. If you have write access
to the repo, the PR has 1-2 approvals (see above), and all of the
required checks have passed, you can use the Squash and Merge button to
merge the PR. If you don't have write access, or you need help, reach
out in the #apm-dotnet channel in Slack.
-->

v3.42.0

Toggle v3.42.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
[Test Package Versions Bump] Updating package versions (#8441)

Updates the package versions for integration tests.

## Package Version Cooldown Report

The following versions were published less than **2 days** ago and have
been overridden.
These require manual review before inclusion.

| Package | Integration | Overridden Version | Published | Age (days) |
Using Instead |

|---------|-------------|--------------------|-----------|------------|---------------|
| Quartz | Quartz | 3.18.0 | 2026-04-11 | 0 | 3.17.1 |
| AWSSDK.Core | AwsSdk | 4.0.3.29 | 2026-04-10 | 1 | 4.0.3.28 |
| AWSSDK.DynamoDBv2 | AwsDynamoDb | 4.0.17.8 | 2026-04-10 | 1 | 4.0.17.7
|
| AWSSDK.Kinesis | AwsKinesis | 4.0.8.11 | 2026-04-10 | 1 | 4.0.8.10 |
| AWSSDK.SQS | AwsSqs | 4.0.2.25 | 2026-04-10 | 1 | 4.0.2.24 |
| AWSSDK.SimpleNotificationService | AwsSns | 4.0.2.27 | 2026-04-10 | 1
| 4.0.2.26 |
| AWSSDK.EventBridge | AwsEventBridge | 4.0.5.26 | 2026-04-10 | 1 |
4.0.5.25 |
| AWSSDK.S3 | AwsS3 | 4.0.21.1 | 2026-04-10 | 1 | 4.0.21 |
| AWSSDK.StepFunctions | AwsStepFunctions | 4.0.2.20 | 2026-04-10 | 1 |
4.0.2.19 |
| HotChocolate.AspNetCore | HotChocolate | 15.1.14 | 2026-04-10 | 1 |
15.1.13 |
| Selenium.WebDriver | Selenium | 4.43.0 | 2026-04-10 | 1 | 4.42.0 |

---------

Co-authored-by: bouwkast <8877527+bouwkast@users.noreply.github.com>
Co-authored-by: Andrew Lock <andrew.lock@datadoghq.com>

v3.41.0

Toggle v3.41.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
maybe fix macos smoketests (#8413)

## Summary of changes

## Reason for change

## Implementation details

## Test coverage

## Other details
<!-- Fixes #{issue} -->


<!--  ⚠️ Note:

Where possible, please obtain 2 approvals prior to merging. Unless
CODEOWNERS specifies otherwise, for external teams it is typically best
to have one review from a team member, and one review from apm-dotnet.
Trivial changes do not require 2 reviews.

MergeQueue is NOT enabled in this repository. If you have write access
to the repo, the PR has 1-2 approvals (see above), and all of the
required checks have passed, you can use the Squash and Merge button to
merge the PR. If you don't have write access, or you need help, reach
out in the #apm-dotnet channel in Slack.
-->

v3.40.0

Toggle v3.40.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
Support adding kafka_cluster_id for Confluent.Kafka (#7702)

## Summary of changes

- Adds kafka_cluster_id as a tag for APM Spans and DSM
checkpoints/offsets. (Note that **DSM is enabled by default**). Without
this, we cannot differentiate between reported offsets on the same topic
but across different clusters, which leads us to wildly incorrect metric
values. (For example, a prod cluster with consume/produce offsets at
1000,1001 should have an offset lag of 1. If there is also a matching
dev cluster with offsets at 0 and 1, then we can calculate the offset
lag as 1000).
- In most tracer libraries (python, java, node) we support tracking
`kafka_cluster_id`. Without this, metrics become incorrect when there
are the same topics across different clusters (i.e. dev/prod
environments).
- It's available for Confluent.Kafka 2.3.0 and above only - roughly half
of orgs that use this library according to telemetry. (For DSM where
this is most useful, we can add a recommendation to our docs to use this
version or above.)

**Note:** I drafted an alternative approach calling librdkafka directly
[here](#8264). That gives
the cluster id without any external API call or version dependency (It's
available and unchanged from librdkafka 1.0.0), but calls into unmanaged
code

## Reason for change

This functionality exists in other tracers:
1. Java (doesn't block, intercepts the metadata response to enrich
cluster id going forwards, see
[here](https://github.com/DataDog/dd-trace-java/blob/master/dd-java-agent/instrumentation/kafka/kafka-clients-3.8/src/main/java17/datadog/trace/instrumentation/kafka_clients38/ProducerAdvice.java#L44)
and
[here](https://github.com/DataDog/dd-trace-java/blob/master/dd-java-agent/instrumentation/kafka/kafka-clients-0.11/src/main/java/datadog/trace/instrumentation/kafka_clients/MetadataInstrumentation.java#L82))

2. Node (blocks, see
[here](https://github.com/DataDog/dd-trace-js/blob/master/packages/datadog-instrumentations/src/kafkajs.js#L234)
and
[here](https://github.com/DataDog/dd-trace-py/blob/main/ddtrace/contrib/internal/kafka/patch.py#L183))

3. Python (blocks with a 1 second timeout, see
[here](https://github.com/DataDog/dd-trace-py/blob/main/ddtrace/contrib/internal/kafka/patch.py#L360)
and
[here](https://github.com/DataDog/dd-trace-py/blob/main/ddtrace/contrib/internal/kafka/patch.py#L183))

## Implementation details

Constructs the Kafka Admin API client and queries for the cluster id
directly on consumer/producer startup.
We cache this by bootstrap servers, so we expect to make this API call
once.

## Test coverage

## Other details
These DSM metrics will now tag by kafka_cluster_id
<img width="2412" height="1070" alt="Screenshot 2026-02-25 at 12 42
00 pm"
src="https://github.com/user-attachments/assets/416091c6-9b9b-4f90-aea1-fa4735b21df8"
/>
Added to spans (I checked this on produce too, I just don't have a
screenshot of it)
<img width="889" height="809" alt="Screenshot 2026-02-24 at 5 21 59 pm"
src="https://github.com/user-attachments/assets/b9383fa2-6390-4a2a-8a54-b342b4c7dc1b"
/>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>