Skip to content

feat(sidecar): track Data Streams Monitoring backlogs in shared memory - #2729

Open
arjunguhaswe wants to merge 10 commits into
arjun.guha/dsm-shm-tablefrom
arjun.guha/dsm2-450-php-tracer-complete-the-kafka-integration
Open

arjunguhaswe wants to merge 10 commits into
arjun.guha/dsm-shm-tablefrom
arjun.guha/dsm2-450-php-tracer-complete-the-kafka-integration

Conversation

@arjunguhaswe

Copy link
Copy Markdown

What does this PR do?

Stacked on #2674. Split back out of it (previously #2709).

libdd-ipc: the DataStreamsBacklogs schema (shm_dsm_backlog.rs)

  • The highest offset per Kafka partition (produce) and per consumer group and partition (commit) in each 10 s bucket. The backend turns these into consumer lag. Backlogs aren't keyed by pathway, so they get their own table, at 64 B per slot.
  • A slot's key is the value of each BacklogTag it carries: Topic, Type, KafkaClusterId, ConsumerGroup, Partition. Positions are append-only and in Java's order (DataStreamsTags), so Tags match Java's. Tags can be given in any order. An unknown key drops the offset.
  • Values are fetch_max, as in Java. Negative offsets, librdkafka's "unknown" markers, are dropped.
  • 128 slots and a 32 KiB string pool per bucket.

datadog-sidecar (data_streams_flusher.rs)

  • A second table per DsmTableKey, at /dddsb… (backlogs), next to /dddsm… (stats).
  • Both tables are created on the first point or backlog sent over IPC; backlogs through the new add_dsm_backlog call.
  • Both tables are drained with one now so both date a bucket the same way, and are merged by (start, duration) into one StatsBucket. They're retired together once both drains come back empty.
  • Payloads add Backlogs: [{Tags, Value}], omitted when empty.

Motivation

Kafka offsets go into a second table the same way, for consumer lag (DSM2-450).

Additional Notes

  • Not yet covered: the kafka_high_watermark backlog type, which Go reports and Java doesn't.
  • The two tables flip their active bucket one after the other, not atomically, so an offset recorded during the stats drain (about a millisecond) can land one interval off from a stats point recorded at the same moment.
  • If a bucket's string pool fills before its slots do, a new backlog key is stored with empty values. That needs topic or group names averaging over 256 B; a follow-up can handle it.

How to test the change?

cargo test -p libdd-ipc
cargo test -p datadog-sidecar --lib -- data_streams dsm

The DSM tests cover:

  • backlogs: the highest offset per bucket, negative offsets, colliding keys, tags in any order, unknown keys, and empty versus absent values
  • a backlog-only interval, the Backlogs field layout, and the IPC fallback

Manual Testing:

Many test apps were created, all functionally managed to use the tables to produce correct and consistent data, screenshots from one such test app have been provided below:

Lag Metrics

image

🤖 Generated with Claude Code

arjunguhaswe and others added 6 commits October 21, 2026 13:01
Adds a second DSM shared memory table, next to the stats table, holding
the highest offset per backlog (a Kafka partition's produce offset, a
consumer group's committed one) for each 10 s bucket. PHP workers cannot
keep that maximum across requests themselves.

- libdd-ipc: the `DataStreamsBacklogs` schema. Backlog tags have fixed,
  append-only positions (`BacklogTag`, in the Java tracer's order); a
  slot stores each present tag's value and a presence mask, and keys are
  compared byte for byte so that collisions cannot merge backlogs.
- datadog-sidecar: both tables are created, drained (at one instant)
  and retired together; backlogs go out in the `Backlogs` field of the
  bucket for their interval, omitted when empty as in the Java tracer.
  An `add_dsm_backlog` IPC call is the fallback until a worker has the
  table open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rjun.guha/dsm2-450-php-tracer-complete-the-kafka-integration

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s table key

Merging arjun.guha/dsm-shm-table brought two changes the backlog code
predates:

- Schema is no longer an unsafe trait: its Key and Value must be ShmSafe
  instead (#2673). ShmBacklogKey and ShmBacklogValue now implement ShmSafe,
  and DataStreamsBacklogs implements Schema without unsafe, as DataStreams
  does.
- DsmTableKey has no product any more (#2674), so add_dsm_backlog builds
  its key without one.

Also name ShmDsmBacklogTable::add_backlog in code spans. It aliases the
shared table type of the private shm_table module, so links to its methods
fail the doc lint, as #2674 found for ShmDsmTable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tracer-complete-the-kafka-integration

Carry the stats-to-checkpoints rename over to the backlog table and
the flusher that drains both: Drained::stats -> Drained::checkpoints,
and the wording that still called the checkpoint table the stats
table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cut the default backlogs per bucket from 1024 to 128, and size the
string pool from the slot count to keep 256 bytes of tag values per
backlog (32 KiB per bucket).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tracer-complete-the-kafka-integration

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@linear-code

linear-code Bot commented Oct 26, 2026

Copy link
Copy Markdown

DSM2-450

@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

🔒 Cargo Deny Results

⚠️ 17 issue(s) found, showing only errors (advisories, bans, sources)

📦 datadog-sidecar - 11 error(s)

Show output
info: syncing channel updates for 1.87.0-x86_64-unknown-linux-gnu
info: latest update on 2025-05-15 for version 1.87.0 (17067e9ac 2025-05-09)
info: downloading 6 components
warn: the missing active toolchain `1.87.0-x86_64-unknown-linux-gnu` has been auto-installed
warn: this might cause rustup commands to take longer time to finish than expected
info: you may opt out with `RUSTUP_AUTO_INSTALL=0` or `rustup set auto-install disable`
error[unmaintained]: Bincode is unmaintained
   ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:35:1
   │
35 │ bincode 1.3.3 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unmaintained advisory detected
   │
   ├ ID: RUSTSEC-2025-0141
   ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2025-0141
   ├ Due to a doxxing and harassment incident, the bincode team has taken the decision to cease development permanently.
     
     The team considers version 1.3.3 a complete version of bincode that is not in need of any updates.
     
     ## Alternatives to consider
     
     * [wincode](https://crates.io/crates/wincode)
     * [postcard](https://crates.io/crates/postcard)
     * [bitcode](https://crates.io/crates/bitcode)
     * [rkyv](https://crates.io/crates/rkyv)
   ├ Announcement: https://git.sr.ht/~stygianentity/bincode/tree/v3.0/item/README.md
   ├ Solution: No safe upgrade is available!
   ├ bincode v1.3.3
     ├── datadog-sidecar v0.0.1
     ├── (dev) libdd-ffe v2.0.0
     │   └── datadog-sidecar v0.0.1 (*)
     └── libdd-ipc v2.0.0
         └── datadog-sidecar v0.0.1 (*)

error[unsound]: Potential use-after-free due to lack of panic safety in `LruCache::pop()`
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:233:1
    │
233 │ lru 0.16.4 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unsound advisory detected
    │
    ├ ID: RUSTSEC-2026-0253
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0253
    ├ `LruCache::pop()` in `lru` was not panic-safe. If the `Drop` implementation of a stored key panics during `pop()`, `self.detach()` is never called, leaving dangling pointers in the internal doubly-linked list.
      
      A subsequent cache operation that triggers eviction can then dereference these dangling pointers:
      - The node is freed from the map, but remains linked in the LRU list due to the skipped `detach()` call
      - When a new insertion causes eviction, the LRU traversal encounters the dangling pointer
      - This results in a write to already-freed memory during the eviction process
      
      ## Impact
      
      - **CWE-416 (Use-After-Free):** memory corruption when subsequent cache operations access freed node pointers in the linked list
      - **CWE-415 (Double Free):** potential heap corruption when the same memory is freed multiple times
      
      Both types of undefined behavior can be invoked in safe Rust, but only if unwinding panics are enabled and `std::panic::catch_unwind` is used with key types that have potentially-panicking `Drop` implementations.
      
      ## Fix
      
      Fixed in `lru` 0.18.2 by detaching the node from the linked list before freeing it and dropping the key ([lru-rs#238](https://github.com/jeromefroe/lru-rs/pull/238)).
    ├ Announcement: https://github.com/jeromefroe/lru-rs/pull/238
    ├ Solution: Upgrade to >=0.18.2 (try `cargo update -p lru`)
    ├ lru v0.16.4
      └── libdd-ffe v2.0.0
          └── datadog-sidecar v0.0.1

error[vulnerability]: TLS 1.3 handshake messages incorrectly accepted across encryption level boundaries
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:334:1
    │
334 │ rustls 0.23.37 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0285
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0285
    ├ Rustls accepted TLS 1.3 handshake messages sent at the wrong encryption level
      when they followed a key-changing message in the same record. For example,
      a plaintext `EncryptedExtensions` message packed into the same record as the
      `ServerHello` was accepted.
      
      RFC 8446 section 5.1 requires that handshake messages do not span key changes,
      and that implementations terminate the connection with an "unexpected_message"
      alert if they do.
      
      The handshake transcript is still authenticated, so a network-position attacker
      cannot use this to alter or complete a handshake; the practical effect is that
      a peer could send handshake messages that should be encrypted in plaintext
      without rustls rejecting the connection.
      
      This is functionally the same bug as Go's
      [GO-2026-4340](https://pkg.go.dev/vuln/GO-2026-4340) (CVE-2025-61730).
    ├ Announcement: https://github.com/rustls/rustls/pull/3265
    ├ Solution: Upgrade to >=0.23.45 (try `cargo update -p rustls`)
    ├ rustls v0.23.37
      ├── hyper-rustls v0.27.7
      │   └── libdd-common v8.0.0
      │       ├── datadog-sidecar v0.0.1
      │       ├── libdd-capabilities-impl v7.0.0
      │       │   ├── datadog-sidecar v0.0.1 (*)
      │       │   ├── libdd-crashtracker v3.0.0
      │       │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   └── libdd-crashtracker-ffi v46.0.0
      │       │   │       └── datadog-sidecar v0.0.1 (*)
      │       │   ├── libdd-data-pipeline v12.0.0
      │       │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   └── libdd-live-debugger v1.0.0
      │       │   │       └── datadog-sidecar v0.0.1 (*)
      │       │   ├── (dev) libdd-ffe v2.0.0
      │       │   │   └── datadog-sidecar v0.0.1 (*)
      │       │   ├── libdd-live-debugger v1.0.0 (*)
      │       │   ├── libdd-remote-config v7.0.0
      │       │   │   ├── (dev) datadog-sidecar v0.0.1 (*)
      │       │   │   ├── libdd-ffe v2.0.0 (*)
      │       │   │   ├── libdd-live-debugger v1.0.0 (*)
      │       │   │   └── (dev) libdd-remote-config v7.0.0 (*)
      │       │   ├── libdd-shared-runtime v6.0.0
      │       │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   ├── libdd-dogstatsd-client v8.0.0
      │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   │   └── libdd-trace-stats v11.0.0
      │       │   │   │       ├── datadog-sidecar v0.0.1 (*)
      │       │   │   │       ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   │       └── libdd-ipc v2.0.0
      │       │   │   │           └── datadog-sidecar v0.0.1 (*)
      │       │   │   ├── libdd-telemetry v10.0.0
      │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   │   ├── libdd-crashtracker v3.0.0 (*)
      │       │   │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   │   └── libdd-trace-stats v11.0.0 (*)
      │       │   │   └── libdd-trace-stats v11.0.0 (*)
      │       │   ├── (dev) libdd-telemetry v10.0.0 (*)
      │       │   ├── libdd-trace-stats v11.0.0 (*)
      │       │   └── libdd-trace-utils v14.0.0
      │       │       ├── (dev) datadog-sidecar v0.0.1 (*)
      │       │       ├── libdd-data-pipeline v12.0.0 (*)
      │       │       ├── libdd-data-pipeline-core v3.0.0
      │       │       │   └── libdd-data-pipeline v12.0.0 (*)
      │       │       ├── libdd-trace-obfuscation v10.0.0
      │       │       │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │       │   ├── libdd-data-pipeline-core v3.0.0 (*)
      │       │       │   └── libdd-trace-stats v11.0.0 (*)
      │       │       ├── libdd-trace-stats v11.0.0 (*)
      │       │       └── (dev) libdd-trace-utils v14.0.0 (*)
      │       ├── libdd-common-ffi v46.0.0
      │       │   ├── datadog-sidecar v0.0.1 (*)
      │       │   └── libdd-crashtracker-ffi v46.0.0 (*)
      │       ├── (build) libdd-crashtracker v3.0.0 (*)
      │       ├── libdd-crashtracker-ffi v46.0.0 (*)
      │       ├── libdd-data-pipeline v12.0.0 (*)
      │       ├── libdd-data-pipeline-core v3.0.0 (*)
      │       ├── libdd-dogstatsd-client v8.0.0 (*)
      │       ├── libdd-ffe v2.0.0 (*)
      │       ├── libdd-ipc v2.0.0 (*)
      │       ├── libdd-live-debugger v1.0.0 (*)
      │       ├── libdd-remote-config v7.0.0 (*)
      │       ├── libdd-shared-runtime v6.0.0 (*)
      │       ├── libdd-telemetry v10.0.0 (*)
      │       ├── libdd-trace-obfuscation v10.0.0 (*)
      │       ├── libdd-trace-stats v11.0.0 (*)
      │       └── libdd-trace-utils v14.0.0 (*)
      ├── libdd-common v8.0.0 (*)
      ├── rustls-platform-verifier v0.6.2
      │   └── libdd-common v8.0.0 (*)
      └── tokio-rustls v0.26.0
          └── hyper-rustls v0.27.7 (*)

error[vulnerability]: `Debug` impls for client session values expose TLS secrets
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:334:1
    │
334 │ rustls 0.23.37 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0346
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0346
    ├ The `Debug` implementations of `Tls12ClientSessionValue` and
      `Tls13ClientSessionValue` were derived, and so included the TLS 1.2 master
      secret or TLS 1.3 resumption PSK in their output.
      
      Custom `ClientSessionStore` implementations that format these values with
      `Debug` (for example, when logging) could disclose these secrets to readers of
      the logs. This conflicts with rustls's
      [key-material redaction policy](https://github.com/rustls/rustls/blob/99f2358cae2954837dbb866faf6727de75489ab9/SECURITY.md#boundary-public-api).
      
      Ordinary connection and built-in session cache `Debug` output is redacted and
      is not affected.
    ├ Announcement: https://github.com/rustls/rustls/pull/3299
    ├ Solution: Upgrade to >=0.23.46 (try `cargo update -p rustls`)
    ├ rustls v0.23.37
      ├── hyper-rustls v0.27.7
      │   └── libdd-common v8.0.0
      │       ├── datadog-sidecar v0.0.1
      │       ├── libdd-capabilities-impl v7.0.0
      │       │   ├── datadog-sidecar v0.0.1 (*)
      │       │   ├── libdd-crashtracker v3.0.0
      │       │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   └── libdd-crashtracker-ffi v46.0.0
      │       │   │       └── datadog-sidecar v0.0.1 (*)
      │       │   ├── libdd-data-pipeline v12.0.0
      │       │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   └── libdd-live-debugger v1.0.0
      │       │   │       └── datadog-sidecar v0.0.1 (*)
      │       │   ├── (dev) libdd-ffe v2.0.0
      │       │   │   └── datadog-sidecar v0.0.1 (*)
      │       │   ├── libdd-live-debugger v1.0.0 (*)
      │       │   ├── libdd-remote-config v7.0.0
      │       │   │   ├── (dev) datadog-sidecar v0.0.1 (*)
      │       │   │   ├── libdd-ffe v2.0.0 (*)
      │       │   │   ├── libdd-live-debugger v1.0.0 (*)
      │       │   │   └── (dev) libdd-remote-config v7.0.0 (*)
      │       │   ├── libdd-shared-runtime v6.0.0
      │       │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   ├── libdd-dogstatsd-client v8.0.0
      │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   │   └── libdd-trace-stats v11.0.0
      │       │   │   │       ├── datadog-sidecar v0.0.1 (*)
      │       │   │   │       ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   │       └── libdd-ipc v2.0.0
      │       │   │   │           └── datadog-sidecar v0.0.1 (*)
      │       │   │   ├── libdd-telemetry v10.0.0
      │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   │   ├── libdd-crashtracker v3.0.0 (*)
      │       │   │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   │   └── libdd-trace-stats v11.0.0 (*)
      │       │   │   └── libdd-trace-stats v11.0.0 (*)
      │       │   ├── (dev) libdd-telemetry v10.0.0 (*)
      │       │   ├── libdd-trace-stats v11.0.0 (*)
      │       │   └── libdd-trace-utils v14.0.0
      │       │       ├── (dev) datadog-sidecar v0.0.1 (*)
      │       │       ├── libdd-data-pipeline v12.0.0 (*)
      │       │       ├── libdd-data-pipeline-core v3.0.0
      │       │       │   └── libdd-data-pipeline v12.0.0 (*)
      │       │       ├── libdd-trace-obfuscation v10.0.0
      │       │       │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │       │   ├── libdd-data-pipeline-core v3.0.0 (*)
      │       │       │   └── libdd-trace-stats v11.0.0 (*)
      │       │       ├── libdd-trace-stats v11.0.0 (*)
      │       │       └── (dev) libdd-trace-utils v14.0.0 (*)
      │       ├── libdd-common-ffi v46.0.0
      │       │   ├── datadog-sidecar v0.0.1 (*)
      │       │   └── libdd-crashtracker-ffi v46.0.0 (*)
      │       ├── (build) libdd-crashtracker v3.0.0 (*)
      │       ├── libdd-crashtracker-ffi v46.0.0 (*)
      │       ├── libdd-data-pipeline v12.0.0 (*)
      │       ├── libdd-data-pipeline-core v3.0.0 (*)
      │       ├── libdd-dogstatsd-client v8.0.0 (*)
      │       ├── libdd-ffe v2.0.0 (*)
      │       ├── libdd-ipc v2.0.0 (*)
      │       ├── libdd-live-debugger v1.0.0 (*)
      │       ├── libdd-remote-config v7.0.0 (*)
      │       ├── libdd-shared-runtime v6.0.0 (*)
      │       ├── libdd-telemetry v10.0.0 (*)
      │       ├── libdd-trace-obfuscation v10.0.0 (*)
      │       ├── libdd-trace-stats v11.0.0 (*)
      │       └── libdd-trace-utils v14.0.0 (*)
      ├── libdd-common v8.0.0 (*)
      ├── rustls-platform-verifier v0.6.2
      │   └── libdd-common v8.0.0 (*)
      └── tokio-rustls v0.26.0
          └── hyper-rustls v0.27.7 (*)

error[vulnerability]: Brotli certificate decompression can allocate up to 1 GiB before authentication
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:334:1
    │
334 │ rustls 0.23.37 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0348
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0348
    ├ The built-in Brotli certificate decompressor (enabled by the non-default
      `brotli` crate feature) bounded the size of the decompressed output, but
      accepted a peer-selected history window. Brotli's large-window extension was
      enabled, so a five-byte header could cause an allocation of 1 GiB. A peer can
      abort a process whose allocator cannot satisfy that request.
      
      No trusted certificate is required by the attacker. Affected configurations are:
      
      - clients that enable the `brotli` feature and connect to a malicious server, and
      - servers that enable the `brotli` feature and request client certificates.
      
      Applications that do not enable the `brotli` feature are not affected.
    ├ Announcement: https://github.com/rustls/rustls/pull/3297
    ├ Solution: Upgrade to >=0.23.46 (try `cargo update -p rustls`)
    ├ rustls v0.23.37
      ├── hyper-rustls v0.27.7
      │   └── libdd-common v8.0.0
      │       ├── datadog-sidecar v0.0.1
      │       ├── libdd-capabilities-impl v7.0.0
      │       │   ├── datadog-sidecar v0.0.1 (*)
      │       │   ├── libdd-crashtracker v3.0.0
      │       │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   └── libdd-crashtracker-ffi v46.0.0
      │       │   │       └── datadog-sidecar v0.0.1 (*)
      │       │   ├── libdd-data-pipeline v12.0.0
      │       │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   └── libdd-live-debugger v1.0.0
      │       │   │       └── datadog-sidecar v0.0.1 (*)
      │       │   ├── (dev) libdd-ffe v2.0.0
      │       │   │   └── datadog-sidecar v0.0.1 (*)
      │       │   ├── libdd-live-debugger v1.0.0 (*)
      │       │   ├── libdd-remote-config v7.0.0
      │       │   │   ├── (dev) datadog-sidecar v0.0.1 (*)
      │       │   │   ├── libdd-ffe v2.0.0 (*)
      │       │   │   ├── libdd-live-debugger v1.0.0 (*)
      │       │   │   └── (dev) libdd-remote-config v7.0.0 (*)
      │       │   ├── libdd-shared-runtime v6.0.0
      │       │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   ├── libdd-dogstatsd-client v8.0.0
      │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   │   └── libdd-trace-stats v11.0.0
      │       │   │   │       ├── datadog-sidecar v0.0.1 (*)
      │       │   │   │       ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   │       └── libdd-ipc v2.0.0
      │       │   │   │           └── datadog-sidecar v0.0.1 (*)
      │       │   │   ├── libdd-telemetry v10.0.0
      │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   │   ├── libdd-crashtracker v3.0.0 (*)
      │       │   │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   │   └── libdd-trace-stats v11.0.0 (*)
      │       │   │   └── libdd-trace-stats v11.0.0 (*)
      │       │   ├── (dev) libdd-telemetry v10.0.0 (*)
      │       │   ├── libdd-trace-stats v11.0.0 (*)
      │       │   └── libdd-trace-utils v14.0.0
      │       │       ├── (dev) datadog-sidecar v0.0.1 (*)
      │       │       ├── libdd-data-pipeline v12.0.0 (*)
      │       │       ├── libdd-data-pipeline-core v3.0.0
      │       │       │   └── libdd-data-pipeline v12.0.0 (*)
      │       │       ├── libdd-trace-obfuscation v10.0.0
      │       │       │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │       │   ├── libdd-data-pipeline-core v3.0.0 (*)
      │       │       │   └── libdd-trace-stats v11.0.0 (*)
      │       │       ├── libdd-trace-stats v11.0.0 (*)
      │       │       └── (dev) libdd-trace-utils v14.0.0 (*)
      │       ├── libdd-common-ffi v46.0.0
      │       │   ├── datadog-sidecar v0.0.1 (*)
      │       │   └── libdd-crashtracker-ffi v46.0.0 (*)
      │       ├── (build) libdd-crashtracker v3.0.0 (*)
      │       ├── libdd-crashtracker-ffi v46.0.0 (*)
      │       ├── libdd-data-pipeline v12.0.0 (*)
      │       ├── libdd-data-pipeline-core v3.0.0 (*)
      │       ├── libdd-dogstatsd-client v8.0.0 (*)
      │       ├── libdd-ffe v2.0.0 (*)
      │       ├── libdd-ipc v2.0.0 (*)
      │       ├── libdd-live-debugger v1.0.0 (*)
      │       ├── libdd-remote-config v7.0.0 (*)
      │       ├── libdd-shared-runtime v6.0.0 (*)
      │       ├── libdd-telemetry v10.0.0 (*)
      │       ├── libdd-trace-obfuscation v10.0.0 (*)
      │       ├── libdd-trace-stats v11.0.0 (*)
      │       └── libdd-trace-utils v14.0.0 (*)
      ├── libdd-common v8.0.0 (*)
      ├── rustls-platform-verifier v0.6.2
      │   └── libdd-common v8.0.0 (*)
      └── tokio-rustls v0.26.0
          └── hyper-rustls v0.27.7 (*)

error[vulnerability]: Unauthenticated ServerHello can downgrade later connections to classical key exchange
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:334:1
    │
334 │ rustls 0.23.37 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0349
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0349
    ├ The client recorded the server-selected key exchange group for each server
      name when processing the ServerHello, before the server was authenticated.
      This record is used to predict which key share to send in future ClientHellos
      to that server name.
      
      A network attacker can answer one connection attempt with a ServerHello
      selecting X25519, and then close the connection. Later ClientHellos for that
      name carry only an X25519 key share, while `supported_groups` still lists
      X25519MLKEM768 first. If the genuine server accepts that share rather than
      sending a HelloRetryRequest for its preferred hybrid group, the handshake
      completes with classical-only key exchange and no error. This persists for as
      long as the entry stays in the client's session store.
      
      The impact is loss of post-quantum confidentiality for affected connections
      ("harvest now, decrypt later"). There is no key compromise and no
      authentication bypass.
      
      The following are not affected:
      
      - connections to servers which send a HelloRetryRequest for their preferred group,
      - clients with resumption disabled (as nothing is stored), and
      - other server names.
      
      This behaviour is discussed in
      [draft-ietf-tls-key-share-prediction](https://www.ietf.org/archive/id/draft-ietf-tls-key-share-prediction-01.html#name-security-considerations),
      so the practical impact depends largely on server policy.
    ├ Announcement: https://github.com/rustls/rustls/pull/3355
    ├ Solution: Upgrade to >=0.23.46 (try `cargo update -p rustls`)
    ├ rustls v0.23.37
      ├── hyper-rustls v0.27.7
      │   └── libdd-common v8.0.0
      │       ├── datadog-sidecar v0.0.1
      │       ├── libdd-capabilities-impl v7.0.0
      │       │   ├── datadog-sidecar v0.0.1 (*)
      │       │   ├── libdd-crashtracker v3.0.0
      │       │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   └── libdd-crashtracker-ffi v46.0.0
      │       │   │       └── datadog-sidecar v0.0.1 (*)
      │       │   ├── libdd-data-pipeline v12.0.0
      │       │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   └── libdd-live-debugger v1.0.0
      │       │   │       └── datadog-sidecar v0.0.1 (*)
      │       │   ├── (dev) libdd-ffe v2.0.0
      │       │   │   └── datadog-sidecar v0.0.1 (*)
      │       │   ├── libdd-live-debugger v1.0.0 (*)
      │       │   ├── libdd-remote-config v7.0.0
      │       │   │   ├── (dev) datadog-sidecar v0.0.1 (*)
      │       │   │   ├── libdd-ffe v2.0.0 (*)
      │       │   │   ├── libdd-live-debugger v1.0.0 (*)
      │       │   │   └── (dev) libdd-remote-config v7.0.0 (*)
      │       │   ├── libdd-shared-runtime v6.0.0
      │       │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   ├── libdd-dogstatsd-client v8.0.0
      │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   │   └── libdd-trace-stats v11.0.0
      │       │   │   │       ├── datadog-sidecar v0.0.1 (*)
      │       │   │   │       ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   │       └── libdd-ipc v2.0.0
      │       │   │   │           └── datadog-sidecar v0.0.1 (*)
      │       │   │   ├── libdd-telemetry v10.0.0
      │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │       │   │   │   ├── libdd-crashtracker v3.0.0 (*)
      │       │   │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │   │   │   └── libdd-trace-stats v11.0.0 (*)
      │       │   │   └── libdd-trace-stats v11.0.0 (*)
      │       │   ├── (dev) libdd-telemetry v10.0.0 (*)
      │       │   ├── libdd-trace-stats v11.0.0 (*)
      │       │   └── libdd-trace-utils v14.0.0
      │       │       ├── (dev) datadog-sidecar v0.0.1 (*)
      │       │       ├── libdd-data-pipeline v12.0.0 (*)
      │       │       ├── libdd-data-pipeline-core v3.0.0
      │       │       │   └── libdd-data-pipeline v12.0.0 (*)
      │       │       ├── libdd-trace-obfuscation v10.0.0
      │       │       │   ├── libdd-data-pipeline v12.0.0 (*)
      │       │       │   ├── libdd-data-pipeline-core v3.0.0 (*)
      │       │       │   └── libdd-trace-stats v11.0.0 (*)
      │       │       ├── libdd-trace-stats v11.0.0 (*)
      │       │       └── (dev) libdd-trace-utils v14.0.0 (*)
      │       ├── libdd-common-ffi v46.0.0
      │       │   ├── datadog-sidecar v0.0.1 (*)
      │       │   └── libdd-crashtracker-ffi v46.0.0 (*)
      │       ├── (build) libdd-crashtracker v3.0.0 (*)
      │       ├── libdd-crashtracker-ffi v46.0.0 (*)
      │       ├── libdd-data-pipeline v12.0.0 (*)
      │       ├── libdd-data-pipeline-core v3.0.0 (*)
      │       ├── libdd-dogstatsd-client v8.0.0 (*)
      │       ├── libdd-ffe v2.0.0 (*)
      │       ├── libdd-ipc v2.0.0 (*)
      │       ├── libdd-live-debugger v1.0.0 (*)
      │       ├── libdd-remote-config v7.0.0 (*)
      │       ├── libdd-shared-runtime v6.0.0 (*)
      │       ├── libdd-telemetry v10.0.0 (*)
      │       ├── libdd-trace-obfuscation v10.0.0 (*)
      │       ├── libdd-trace-stats v11.0.0 (*)
      │       └── libdd-trace-utils v14.0.0 (*)
      ├── libdd-common v8.0.0 (*)
      ├── rustls-platform-verifier v0.6.2
      │   └── libdd-common v8.0.0 (*)
      └── tokio-rustls v0.26.0
          └── hyper-rustls v0.27.7 (*)

error[unsound]: `AsyncFd::new` and related constructors violate I/O safety
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:413:1
    │
413 │ tokio 1.49.0 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unsound advisory detected
    │
    ├ ID: RUSTSEC-2026-0386
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0386
    ├ `tokio::io::unix::AsyncFd` provides safe constructors (`new`, `with_interest`, `try_new`, and `try_with_interest`) that accept any `T: AsRawFd` rather than requiring proof of ownership or validity of the file descriptor. Because `RawFd` implements `AsRawFd`, safe code can construct an `AsyncFd` from an arbitrary or closed file descriptor, or close/replace the underlying file descriptor while the `AsyncFd` is still alive.
      
      This violates I/O safety in two ways:
      
      1. `AsyncFd<T>` implements `AsFd` for all `T: AsRawFd` by calling `BorrowedFd::borrow_raw(self.as_raw_fd())`, allowing safe code to obtain an arbitrary `BorrowedFd<'_>` without owning the file descriptor.
      2. Tokio's I/O driver stores a pointer to an internal allocation in the `epoll`/`kqueue` user data for registered file descriptors. If the underlying file descriptor is duplicated and then closed while an `AsyncFd` is alive, and the OS reuses that file descriptor number for a another IO resource on the same runtime, dropping the first `AsyncFd` deregisters the reused file descriptor number and frees the first while the original file description remains registered in `epoll`, leading to a use-after-free when a readiness event fires.
      
      Starting in Tokio 1.51.6, 1.53.3, and 1.54.0, `AsyncFd::new`, `AsyncFd::with_interest`, `AsyncFd::try_new`, and `AsyncFd::try_with_interest` are deprecated in favor of the `unsafe` constructors `AsyncFd::register` and `AsyncFd::register_with_interest`. Callers must ensure that the file descriptor remains valid, open, and unchanged for the lifetime of the `AsyncFd`.
    ├ Announcement: https://github.com/tokio-rs/tokio/pull/8587
    ├ Solution: Upgrade to >=1.51.6, <1.52.0 OR >=1.53.3 (try `cargo update -p tokio`)
    ├ tokio v1.49.0
      ├── datadog-sidecar v0.0.1
      ├── h2 v0.4.19
      │   ├── hyper v1.11.1
      │   │   ├── httpmock v0.8.0-alpha.1
      │   │   │   ├── (dev) datadog-sidecar v0.0.1 (*)
      │   │   │   ├── (dev) libdd-data-pipeline v12.0.0
      │   │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   │   │   └── libdd-live-debugger v1.0.0
      │   │   │   │       └── datadog-sidecar v0.0.1 (*)
      │   │   │   ├── (dev) libdd-ffe v2.0.0
      │   │   │   │   └── datadog-sidecar v0.0.1 (*)
      │   │   │   ├── (dev) libdd-telemetry v10.0.0
      │   │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   │   │   ├── libdd-crashtracker v3.0.0
      │   │   │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   │   │   │   └── libdd-crashtracker-ffi v46.0.0
      │   │   │   │   │       └── datadog-sidecar v0.0.1 (*)
      │   │   │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │   │   │   │   └── libdd-trace-stats v11.0.0
      │   │   │   │       ├── datadog-sidecar v0.0.1 (*)
      │   │   │   │       ├── libdd-data-pipeline v12.0.0 (*)
      │   │   │   │       └── libdd-ipc v2.0.0
      │   │   │   │           └── datadog-sidecar v0.0.1 (*)
      │   │   │   ├── (dev) libdd-trace-stats v11.0.0 (*)
      │   │   │   └── libdd-trace-utils v14.0.0
      │   │   │       ├── (dev) datadog-sidecar v0.0.1 (*)
      │   │   │       ├── libdd-data-pipeline v12.0.0 (*)
      │   │   │       ├── libdd-data-pipeline-core v3.0.0
      │   │   │       │   └── libdd-data-pipeline v12.0.0 (*)
      │   │   │       ├── libdd-trace-obfuscation v10.0.0
      │   │   │       │   ├── libdd-data-pipeline v12.0.0 (*)
      │   │   │       │   ├── libdd-data-pipeline-core v3.0.0 (*)
      │   │   │       │   └── libdd-trace-stats v11.0.0 (*)
      │   │   │       ├── libdd-trace-stats v11.0.0 (*)
      │   │   │       └── (dev) libdd-trace-utils v14.0.0 (*)
      │   │   ├── hyper-rustls v0.27.7
      │   │   │   └── libdd-common v8.0.0
      │   │   │       ├── datadog-sidecar v0.0.1 (*)
      │   │   │       ├── libdd-capabilities-impl v7.0.0
      │   │   │       │   ├── datadog-sidecar v0.0.1 (*)
      │   │   │       │   ├── libdd-crashtracker v3.0.0 (*)
      │   │   │       │   ├── libdd-data-pipeline v12.0.0 (*)
      │   │   │       │   ├── (dev) libdd-ffe v2.0.0 (*)
      │   │   │       │   ├── libdd-live-debugger v1.0.0 (*)
      │   │   │       │   ├── libdd-remote-config v7.0.0
      │   │   │       │   │   ├── (dev) datadog-sidecar v0.0.1 (*)
      │   │   │       │   │   ├── libdd-ffe v2.0.0 (*)
      │   │   │       │   │   ├── libdd-live-debugger v1.0.0 (*)
      │   │   │       │   │   └── (dev) libdd-remote-config v7.0.0 (*)
      │   │   │       │   ├── libdd-shared-runtime v6.0.0
      │   │   │       │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │   │   │       │   │   ├── libdd-dogstatsd-client v8.0.0
      │   │   │       │   │   │   ├── datadog-sidecar v0.0.1 (*)
      │   │   │       │   │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │   │   │       │   │   │   └── libdd-trace-stats v11.0.0 (*)
      │   │   │       │   │   ├── libdd-telemetry v10.0.0 (*)
      │   │   │       │   │   └── libdd-trace-stats v11.0.0 (*)
      │   │   │       │   ├── (dev) libdd-telemetry v10.0.0 (*)
      │   │   │       │   ├── libdd-trace-stats v11.0.0 (*)
      │   │   │       │   └── libdd-trace-utils v14.0.0 (*)
      │   │   │       ├── libdd-common-ffi v46.0.0
      │   │   │       │   ├── datadog-sidecar v0.0.1 (*)
      │   │   │       │   └── libdd-crashtracker-ffi v46.0.0 (*)
      │   │   │       ├── (build) libdd-crashtracker v3.0.0 (*)
      │   │   │       ├── libdd-crashtracker-ffi v46.0.0 (*)
      │   │   │       ├── libdd-data-pipeline v12.0.0 (*)
      │   │   │       ├── libdd-data-pipeline-core v3.0.0 (*)
      │   │   │       ├── libdd-dogstatsd-client v8.0.0 (*)
      │   │   │       ├── libdd-ffe v2.0.0 (*)
      │   │   │       ├── libdd-ipc v2.0.0 (*)
      │   │   │       ├── libdd-live-debugger v1.0.0 (*)
      │   │   │       ├── libdd-remote-config v7.0.0 (*)
      │   │   │       ├── libdd-shared-runtime v6.0.0 (*)
      │   │   │       ├── libdd-telemetry v10.0.0 (*)
      │   │   │       ├── libdd-trace-obfuscation v10.0.0 (*)
      │   │   │       ├── libdd-trace-stats v11.0.0 (*)
      │   │   │       └── libdd-trace-utils v14.0.0 (*)
      │   │   ├── hyper-util v0.1.17
      │   │   │   ├── httpmock v0.8.0-alpha.1 (*)
      │   │   │   ├── hyper-rustls v0.27.7 (*)
      │   │   │   ├── libdd-common v8.0.0 (*)
      │   │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │   │   │   └── libdd-remote-config v7.0.0 (*)
      │   │   ├── libdd-common v8.0.0 (*)
      │   │   ├── libdd-common-ffi v46.0.0 (*)
      │   │   ├── libdd-data-pipeline v12.0.0 (*)
      │   │   ├── libdd-remote-config v7.0.0 (*)
      │   │   └── libdd-trace-utils v14.0.0 (*)
      │   └── (dev) libdd-data-pipeline v12.0.0 (*)
      ├── httpmock v0.8.0-alpha.1 (*)
      ├── hyper v1.11.1 (*)
      ├── hyper-rustls v0.27.7 (*)
      ├── hyper-util v0.1.17 (*)
      ├── (dev) libdd-capabilities-impl v7.0.0 (*)
      ├── libdd-common v8.0.0 (*)
      ├── libdd-crashtracker v3.0.0 (*)
      ├── (dev) libdd-data-pipeline v12.0.0 (*)
      ├── (dev) libdd-dogstatsd-client v8.0.0 (*)
      ├── libdd-ffe v2.0.0 (*)
      ├── (dev) libdd-ipc v2.0.0 (*)
      ├── libdd-live-debugger v1.0.0 (*)
      ├── libdd-remote-config v7.0.0 (*)
      ├── libdd-shared-runtime v6.0.0 (*)
      ├── (dev) libdd-telemetry v10.0.0 (*)
      ├── (dev) libdd-trace-protobuf v5.1.0
      │   ├── libdd-data-pipeline v12.0.0 (*)
      │   ├── libdd-ffe v2.0.0 (*)
      │   ├── libdd-ipc v2.0.0 (*)
      │   ├── libdd-remote-config v7.0.0 (*)
      │   ├── libdd-trace-normalization v4.2.0
      │   │   └── libdd-trace-utils v14.0.0 (*)
      │   ├── libdd-trace-obfuscation v10.0.0 (*)
      │   ├── libdd-trace-stats v11.0.0 (*)
      │   └── libdd-trace-utils v14.0.0 (*)
      ├── (dev) libdd-trace-stats v11.0.0 (*)
      ├── libdd-trace-utils v14.0.0 (*)
      ├── tokio-rustls v0.26.0
      │   └── hyper-rustls v0.27.7 (*)
      ├── tokio-stream v0.1.16
      │   └── tonic v0.14.2
      │       └── libdd-data-pipeline v12.0.0 (*)
      └── tokio-util v0.7.12
          ├── datadog-sidecar v0.0.1 (*)
          ├── h2 v0.4.19 (*)
          ├── libdd-data-pipeline v12.0.0 (*)
          ├── libdd-remote-config v7.0.0 (*)
          ├── libdd-shared-runtime v6.0.0 (*)
          └── libdd-telemetry v10.0.0 (*)

error[vulnerability]: Data from an abandoned stream leaks into the next stream on a reused context
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:541:1
    │
541 │ zstd 0.13.3 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0391
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0391
    ├ The `with_context` constructors of the stream encoders and decoders used the
      borrowed context as it was. When a stream was abandoned on a context, for
      example an encoder dropped before `finish()` after an error, whatever it
      left there was carried into the next stream: the input buffered by the
      previous encoder (up to 128 KiB, or all of it with `zstdmt`) became the
      start of the next frame, and a decoder returned undelivered output of the
      previous stream.
      
      An application reusing one context for data that must stay separate, such
      as different users' requests, could disclose one user's plaintext to
      another. Whoever supplies the data can cause the abandonment with invalid
      input.
      
      The flaw was corrected by resetting the context's session in
      `with_context`.
    ├ Announcement: https://github.com/gyscos/zstd-rs/commit/74ace2dcdca62a2ce0f034895d6079458311e003
    ├ Solution: Upgrade to >=0.14.3 (try `cargo update -p zstd`)
    ├ zstd v0.13.3
      ├── (dev) libdd-data-pipeline v12.0.0
      │   ├── datadog-sidecar v0.0.1
      │   └── libdd-live-debugger v1.0.0
      │       └── datadog-sidecar v0.0.1 (*)
      └── (dev) libdd-data-pipeline-core v3.0.0
          └── libdd-data-pipeline v12.0.0 (*)

error[vulnerability]: `Seekable::decompress` sets a `Vec` length beyond its capacity for offsets past the end
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:542:1
    │
542 │ zstd-safe 7.2.3 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0398
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0398
    ├ `ZSTD_seekable_decompress` shortens the requested length to the end of the
      data without checking that the offset is before it. For an offset past the
      end, it returns a wrapped-around length without writing anything, and
      `Seekable::decompress` passed that length to `Vec::set_len`.
      
      With the `seekable` feature, whoever supplies the archive, or chooses the
      offset, can leave the caller's `Vec<u8>` with a length far beyond its
      capacity. Reading it then discloses neighbouring heap memory, and appending
      to it corrupts memory. Offsets near `u64::MAX` can also hang the call.
      
      The flaw was corrected by clamping requests to the end of the data, and by
      checking every count reported by the C library against the buffer capacity.
    ├ Announcement: https://github.com/gyscos/zstd-rs/commit/80506be743fae2ed0c2fe8b21c374c6a2eab0be7
    ├ Solution: Upgrade to >=8.2.0 (try `cargo update -p zstd-safe`)
    ├ zstd-safe v7.2.3
      └── zstd v0.13.3
          ├── (dev) libdd-data-pipeline v12.0.0
          │   ├── datadog-sidecar v0.0.1
          │   └── libdd-live-debugger v1.0.0
          │       └── datadog-sidecar v0.0.1 (*)
          └── (dev) libdd-data-pipeline-core v3.0.0
              └── libdd-data-pipeline v12.0.0 (*)

error[vulnerability]: Uninitialized memory exposed when streaming decompression of a legacy frame fails
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:542:1
    │
542 │ zstd-safe 7.2.3 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0403
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0403
    ├ When decompression fails inside a legacy (zstd v0.4 to v0.7) frame, the
      bundled zstd library reports the output buffer as fully written although
      nothing was written. `DCtx::decompress_stream` committed that position even
      on error, and for a `Vec<u8>` destination this extended the vector's length
      over uninitialized memory.
      
      Legacy support is enabled by default. A 5- or 6-byte corrupt legacy frame is
      enough: through `zstd::stream::write::Decoder`, up to 32 KiB of stale heap
      memory is then passed to the wrapped writer on the next `write()` or
      `flush()`, or when an `auto_flush()`/`on_flush()` decoder is dropped. Whether
      this reaches an attacker depends on where the application sends the
      decompressed output. `zstd::stream::read::Decoder`, `zstd::decode_all` and
      the bulk API are not affected.
      
      Before zstd-safe 4.0.0, output buffers could only be initialized slices.
      The zstd crate's own writer had the same flaw from 0.4.22 to 0.7.x, which is
      covered by a separate advisory.
      
      The flaw was corrected by only committing the buffer positions of a
      successful call.
    ├ Announcement: https://github.com/gyscos/zstd-rs/commit/006e1d1ad1eeaf6b5d4c28329e70217adabcec43
    ├ Solution: Upgrade to >=8.2.0 (try `cargo update -p zstd-safe`)
    ├ zstd-safe v7.2.3
      └── zstd v0.13.3
          ├── (dev) libdd-data-pipeline v12.0.0
          │   ├── datadog-sidecar v0.0.1
          │   └── libdd-live-debugger v1.0.0
          │       └── datadog-sidecar v0.0.1 (*)
          └── (dev) libdd-data-pipeline-core v3.0.0
              └── libdd-data-pipeline v12.0.0 (*)

error[vulnerability]: WebAssembly allocator shim corrupts memory on allocation failure
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:543:1
    │
543 │ zstd-sys 2.0.14+zstd.1.5.7 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0410
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0410
    ├ On wasm32, zstd-sys provides `malloc` and `free` to the C library through a
      shim over Rust's allocator. The shim did not check for allocation failure:
      it wrote its size header to address 0 and returned address 4, which the C
      library used as a valid buffer. `free(NULL)` also read below address 0.
      
      Whenever the instance cannot grow its memory by what a frame asks for, a
      small crafted frame (a 9-byte header declaring a 128 MiB window is enough)
      made decompression write decoded data over the bottom of the module's
      linear memory, instead of failing. The corruption stays within the wasm
      sandbox.
      
      The flaw was corrected by returning NULL on allocation failure or size
      overflow, and by making `free(NULL)` a no-op.
    ├ Announcement: https://github.com/gyscos/zstd-rs/commit/165d1625553c236b9700ca794b8a7c51f5d98314
    ├ Solution: Upgrade to >=2.1.2 (try `cargo update -p zstd-sys`)
    ├ zstd-sys v2.0.14+zstd.1.5.7
      └── zstd-safe v7.2.3
          └── zstd v0.13.3
              ├── (dev) libdd-data-pipeline v12.0.0
              │   ├── datadog-sidecar v0.0.1
              │   └── libdd-live-debugger v1.0.0
              │       └── datadog-sidecar v0.0.1 (*)
              └── (dev) libdd-data-pipeline-core v3.0.0
                  └── libdd-data-pipeline v12.0.0 (*)

advisories FAILED, bans ok, sources ok

📦 libdd-ipc - 6 error(s)

Show output
error[unmaintained]: Bincode is unmaintained
   ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:24:1
   │
24 │ bincode 1.3.3 registry+https://github.com/rust-lang/crates.io-index
   │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unmaintained advisory detected
   │
   ├ ID: RUSTSEC-2025-0141
   ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2025-0141
   ├ Due to a doxxing and harassment incident, the bincode team has taken the decision to cease development permanently.
     
     The team considers version 1.3.3 a complete version of bincode that is not in need of any updates.
     
     ## Alternatives to consider
     
     * [wincode](https://crates.io/crates/wincode)
     * [postcard](https://crates.io/crates/postcard)
     * [bitcode](https://crates.io/crates/bitcode)
     * [rkyv](https://crates.io/crates/rkyv)
   ├ Announcement: https://git.sr.ht/~stygianentity/bincode/tree/v3.0/item/README.md
   ├ Solution: No safe upgrade is available!
   ├ bincode v1.3.3
     └── libdd-ipc v2.0.0

error[vulnerability]: TLS 1.3 handshake messages incorrectly accepted across encryption level boundaries
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:230:1
    │
230 │ rustls 0.23.37 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0285
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0285
    ├ Rustls accepted TLS 1.3 handshake messages sent at the wrong encryption level
      when they followed a key-changing message in the same record. For example,
      a plaintext `EncryptedExtensions` message packed into the same record as the
      `ServerHello` was accepted.
      
      RFC 8446 section 5.1 requires that handshake messages do not span key changes,
      and that implementations terminate the connection with an "unexpected_message"
      alert if they do.
      
      The handshake transcript is still authenticated, so a network-position attacker
      cannot use this to alter or complete a handshake; the practical effect is that
      a peer could send handshake messages that should be encrypted in plaintext
      without rustls rejecting the connection.
      
      This is functionally the same bug as Go's
      [GO-2026-4340](https://pkg.go.dev/vuln/GO-2026-4340) (CVE-2025-61730).
    ├ Announcement: https://github.com/rustls/rustls/pull/3265
    ├ Solution: Upgrade to >=0.23.45 (try `cargo update -p rustls`)
    ├ rustls v0.23.37
      ├── hyper-rustls v0.27.7
      │   └── libdd-common v8.0.0
      │       ├── libdd-capabilities-impl v7.0.0
      │       │   ├── libdd-shared-runtime v6.0.0
      │       │   │   └── libdd-trace-stats v11.0.0
      │       │   │       └── libdd-ipc v2.0.0
      │       │   ├── libdd-trace-stats v11.0.0 (*)
      │       │   └── libdd-trace-utils v14.0.0
      │       │       ├── libdd-trace-obfuscation v10.0.0
      │       │       │   └── libdd-trace-stats v11.0.0 (*)
      │       │       ├── libdd-trace-stats v11.0.0 (*)
      │       │       └── (dev) libdd-trace-utils v14.0.0 (*)
      │       ├── libdd-ipc v2.0.0 (*)
      │       ├── libdd-shared-runtime v6.0.0 (*)
      │       ├── libdd-trace-obfuscation v10.0.0 (*)
      │       ├── libdd-trace-stats v11.0.0 (*)
      │       └── libdd-trace-utils v14.0.0 (*)
      ├── libdd-common v8.0.0 (*)
      ├── rustls-platform-verifier v0.6.2
      │   └── libdd-common v8.0.0 (*)
      └── tokio-rustls v0.26.0
          └── hyper-rustls v0.27.7 (*)

error[vulnerability]: `Debug` impls for client session values expose TLS secrets
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:230:1
    │
230 │ rustls 0.23.37 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0346
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0346
    ├ The `Debug` implementations of `Tls12ClientSessionValue` and
      `Tls13ClientSessionValue` were derived, and so included the TLS 1.2 master
      secret or TLS 1.3 resumption PSK in their output.
      
      Custom `ClientSessionStore` implementations that format these values with
      `Debug` (for example, when logging) could disclose these secrets to readers of
      the logs. This conflicts with rustls's
      [key-material redaction policy](https://github.com/rustls/rustls/blob/99f2358cae2954837dbb866faf6727de75489ab9/SECURITY.md#boundary-public-api).
      
      Ordinary connection and built-in session cache `Debug` output is redacted and
      is not affected.
    ├ Announcement: https://github.com/rustls/rustls/pull/3299
    ├ Solution: Upgrade to >=0.23.46 (try `cargo update -p rustls`)
    ├ rustls v0.23.37
      ├── hyper-rustls v0.27.7
      │   └── libdd-common v8.0.0
      │       ├── libdd-capabilities-impl v7.0.0
      │       │   ├── libdd-shared-runtime v6.0.0
      │       │   │   └── libdd-trace-stats v11.0.0
      │       │   │       └── libdd-ipc v2.0.0
      │       │   ├── libdd-trace-stats v11.0.0 (*)
      │       │   └── libdd-trace-utils v14.0.0
      │       │       ├── libdd-trace-obfuscation v10.0.0
      │       │       │   └── libdd-trace-stats v11.0.0 (*)
      │       │       ├── libdd-trace-stats v11.0.0 (*)
      │       │       └── (dev) libdd-trace-utils v14.0.0 (*)
      │       ├── libdd-ipc v2.0.0 (*)
      │       ├── libdd-shared-runtime v6.0.0 (*)
      │       ├── libdd-trace-obfuscation v10.0.0 (*)
      │       ├── libdd-trace-stats v11.0.0 (*)
      │       └── libdd-trace-utils v14.0.0 (*)
      ├── libdd-common v8.0.0 (*)
      ├── rustls-platform-verifier v0.6.2
      │   └── libdd-common v8.0.0 (*)
      └── tokio-rustls v0.26.0
          └── hyper-rustls v0.27.7 (*)

error[vulnerability]: Brotli certificate decompression can allocate up to 1 GiB before authentication
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:230:1
    │
230 │ rustls 0.23.37 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0348
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0348
    ├ The built-in Brotli certificate decompressor (enabled by the non-default
      `brotli` crate feature) bounded the size of the decompressed output, but
      accepted a peer-selected history window. Brotli's large-window extension was
      enabled, so a five-byte header could cause an allocation of 1 GiB. A peer can
      abort a process whose allocator cannot satisfy that request.
      
      No trusted certificate is required by the attacker. Affected configurations are:
      
      - clients that enable the `brotli` feature and connect to a malicious server, and
      - servers that enable the `brotli` feature and request client certificates.
      
      Applications that do not enable the `brotli` feature are not affected.
    ├ Announcement: https://github.com/rustls/rustls/pull/3297
    ├ Solution: Upgrade to >=0.23.46 (try `cargo update -p rustls`)
    ├ rustls v0.23.37
      ├── hyper-rustls v0.27.7
      │   └── libdd-common v8.0.0
      │       ├── libdd-capabilities-impl v7.0.0
      │       │   ├── libdd-shared-runtime v6.0.0
      │       │   │   └── libdd-trace-stats v11.0.0
      │       │   │       └── libdd-ipc v2.0.0
      │       │   ├── libdd-trace-stats v11.0.0 (*)
      │       │   └── libdd-trace-utils v14.0.0
      │       │       ├── libdd-trace-obfuscation v10.0.0
      │       │       │   └── libdd-trace-stats v11.0.0 (*)
      │       │       ├── libdd-trace-stats v11.0.0 (*)
      │       │       └── (dev) libdd-trace-utils v14.0.0 (*)
      │       ├── libdd-ipc v2.0.0 (*)
      │       ├── libdd-shared-runtime v6.0.0 (*)
      │       ├── libdd-trace-obfuscation v10.0.0 (*)
      │       ├── libdd-trace-stats v11.0.0 (*)
      │       └── libdd-trace-utils v14.0.0 (*)
      ├── libdd-common v8.0.0 (*)
      ├── rustls-platform-verifier v0.6.2
      │   └── libdd-common v8.0.0 (*)
      └── tokio-rustls v0.26.0
          └── hyper-rustls v0.27.7 (*)

error[vulnerability]: Unauthenticated ServerHello can downgrade later connections to classical key exchange
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:230:1
    │
230 │ rustls 0.23.37 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ security vulnerability detected
    │
    ├ ID: RUSTSEC-2026-0349
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0349
    ├ The client recorded the server-selected key exchange group for each server
      name when processing the ServerHello, before the server was authenticated.
      This record is used to predict which key share to send in future ClientHellos
      to that server name.
      
      A network attacker can answer one connection attempt with a ServerHello
      selecting X25519, and then close the connection. Later ClientHellos for that
      name carry only an X25519 key share, while `supported_groups` still lists
      X25519MLKEM768 first. If the genuine server accepts that share rather than
      sending a HelloRetryRequest for its preferred hybrid group, the handshake
      completes with classical-only key exchange and no error. This persists for as
      long as the entry stays in the client's session store.
      
      The impact is loss of post-quantum confidentiality for affected connections
      ("harvest now, decrypt later"). There is no key compromise and no
      authentication bypass.
      
      The following are not affected:
      
      - connections to servers which send a HelloRetryRequest for their preferred group,
      - clients with resumption disabled (as nothing is stored), and
      - other server names.
      
      This behaviour is discussed in
      [draft-ietf-tls-key-share-prediction](https://www.ietf.org/archive/id/draft-ietf-tls-key-share-prediction-01.html#name-security-considerations),
      so the practical impact depends largely on server policy.
    ├ Announcement: https://github.com/rustls/rustls/pull/3355
    ├ Solution: Upgrade to >=0.23.46 (try `cargo update -p rustls`)
    ├ rustls v0.23.37
      ├── hyper-rustls v0.27.7
      │   └── libdd-common v8.0.0
      │       ├── libdd-capabilities-impl v7.0.0
      │       │   ├── libdd-shared-runtime v6.0.0
      │       │   │   └── libdd-trace-stats v11.0.0
      │       │   │       └── libdd-ipc v2.0.0
      │       │   ├── libdd-trace-stats v11.0.0 (*)
      │       │   └── libdd-trace-utils v14.0.0
      │       │       ├── libdd-trace-obfuscation v10.0.0
      │       │       │   └── libdd-trace-stats v11.0.0 (*)
      │       │       ├── libdd-trace-stats v11.0.0 (*)
      │       │       └── (dev) libdd-trace-utils v14.0.0 (*)
      │       ├── libdd-ipc v2.0.0 (*)
      │       ├── libdd-shared-runtime v6.0.0 (*)
      │       ├── libdd-trace-obfuscation v10.0.0 (*)
      │       ├── libdd-trace-stats v11.0.0 (*)
      │       └── libdd-trace-utils v14.0.0 (*)
      ├── libdd-common v8.0.0 (*)
      ├── rustls-platform-verifier v0.6.2
      │   └── libdd-common v8.0.0 (*)
      └── tokio-rustls v0.26.0
          └── hyper-rustls v0.27.7 (*)

error[unsound]: `AsyncFd::new` and related constructors violate I/O safety
    ┌─ /home/runner/work/libdatadog/libdatadog/Cargo.lock:280:1
    │
280 │ tokio 1.49.0 registry+https://github.com/rust-lang/crates.io-index
    │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ unsound advisory detected
    │
    ├ ID: RUSTSEC-2026-0386
    ├ Advisory: https://rustsec.org/advisories/RUSTSEC-2026-0386
    ├ `tokio::io::unix::AsyncFd` provides safe constructors (`new`, `with_interest`, `try_new`, and `try_with_interest`) that accept any `T: AsRawFd` rather than requiring proof of ownership or validity of the file descriptor. Because `RawFd` implements `AsRawFd`, safe code can construct an `AsyncFd` from an arbitrary or closed file descriptor, or close/replace the underlying file descriptor while the `AsyncFd` is still alive.
      
      This violates I/O safety in two ways:
      
      1. `AsyncFd<T>` implements `AsFd` for all `T: AsRawFd` by calling `BorrowedFd::borrow_raw(self.as_raw_fd())`, allowing safe code to obtain an arbitrary `BorrowedFd<'_>` without owning the file descriptor.
      2. Tokio's I/O driver stores a pointer to an internal allocation in the `epoll`/`kqueue` user data for registered file descriptors. If the underlying file descriptor is duplicated and then closed while an `AsyncFd` is alive, and the OS reuses that file descriptor number for a another IO resource on the same runtime, dropping the first `AsyncFd` deregisters the reused file descriptor number and frees the first while the original file description remains registered in `epoll`, leading to a use-after-free when a readiness event fires.
      
      Starting in Tokio 1.51.6, 1.53.3, and 1.54.0, `AsyncFd::new`, `AsyncFd::with_interest`, `AsyncFd::try_new`, and `AsyncFd::try_with_interest` are deprecated in favor of the `unsafe` constructors `AsyncFd::register` and `AsyncFd::register_with_interest`. Callers must ensure that the file descriptor remains valid, open, and unchanged for the lifetime of the `AsyncFd`.
    ├ Announcement: https://github.com/tokio-rs/tokio/pull/8587
    ├ Solution: Upgrade to >=1.51.6, <1.52.0 OR >=1.53.3 (try `cargo update -p tokio`)
    ├ tokio v1.49.0
      ├── h2 v0.4.19
      │   └── hyper v1.11.1
      │       ├── httpmock v0.8.0-alpha.1
      │       │   ├── (dev) libdd-trace-stats v11.0.0
      │       │   │   └── libdd-ipc v2.0.0
      │       │   └── libdd-trace-utils v14.0.0
      │       │       ├── libdd-trace-obfuscation v10.0.0
      │       │       │   └── libdd-trace-stats v11.0.0 (*)
      │       │       ├── libdd-trace-stats v11.0.0 (*)
      │       │       └── (dev) libdd-trace-utils v14.0.0 (*)
      │       ├── hyper-rustls v0.27.7
      │       │   └── libdd-common v8.0.0
      │       │       ├── libdd-capabilities-impl v7.0.0
      │       │       │   ├── libdd-shared-runtime v6.0.0
      │       │       │   │   └── libdd-trace-stats v11.0.0 (*)
      │       │       │   ├── libdd-trace-stats v11.0.0 (*)
      │       │       │   └── libdd-trace-utils v14.0.0 (*)
      │       │       ├── libdd-ipc v2.0.0 (*)
      │       │       ├── libdd-shared-runtime v6.0.0 (*)
      │       │       ├── libdd-trace-obfuscation v10.0.0 (*)
      │       │       ├── libdd-trace-stats v11.0.0 (*)
      │       │       └── libdd-trace-utils v14.0.0 (*)
      │       ├── hyper-util v0.1.17
      │       │   ├── httpmock v0.8.0-alpha.1 (*)
      │       │   ├── hyper-rustls v0.27.7 (*)
      │       │   └── libdd-common v8.0.0 (*)
      │       ├── libdd-common v8.0.0 (*)
      │       └── libdd-trace-utils v14.0.0 (*)
      ├── httpmock v0.8.0-alpha.1 (*)
      ├── hyper v1.11.1 (*)
      ├── hyper-rustls v0.27.7 (*)
      ├── hyper-util v0.1.17 (*)
      ├── (dev) libdd-capabilities-impl v7.0.0 (*)
      ├── (dev) libdd-common v8.0.0 (*)
      ├── (dev) libdd-ipc v2.0.0 (*)
      ├── libdd-shared-runtime v6.0.0 (*)
      ├── (dev) libdd-trace-protobuf v5.1.0
      │   ├── libdd-ipc v2.0.0 (*)
      │   ├── libdd-trace-normalization v4.2.0
      │   │   └── libdd-trace-utils v14.0.0 (*)
      │   ├── libdd-trace-obfuscation v10.0.0 (*)
      │   ├── libdd-trace-stats v11.0.0 (*)
      │   └── libdd-trace-utils v14.0.0 (*)
      ├── (dev) libdd-trace-stats v11.0.0 (*)
      ├── libdd-trace-utils v14.0.0 (*)
      ├── tokio-rustls v0.26.0
      │   └── hyper-rustls v0.27.7 (*)
      └── tokio-util v0.7.12
          ├── h2 v0.4.19 (*)
          └── libdd-shared-runtime v6.0.0 (*)

advisories FAILED, bans ok, sources ok

Updated: 2026-10-27 16:05:44 UTC | Commit: 6df9524 | dependency-check job results

@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

📚 Documentation Check Results

⚠️ 4081 documentation warning(s) found

📦 datadog-sidecar - 3017 warning(s)

📦 libdd-ipc - 1064 warning(s)


Updated: 2026-10-27 16:07:06 UTC | Commit: 6df9524 | missing-docs job results

@pr-commenter

pr-commenter Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Benchmarks

Comparison

Benchmark execution time: 2026-10-27 16:27:04

Comparing candidate commit d47ba93 in PR branch arjun.guha/dsm2-450-php-tracer-complete-the-kafka-integration with baseline commit 0a19dc2 in branch arjun.guha/dsm-shm-table.

📊 Benchmarking dashboard

Found 1 performance improvements and 2 performance regressions! Performance is the same for 154 metrics, 2 unstable metrics.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

scenario:tags/replace_trace_tags

  • 🟥 execution_time [+139.619ns; +151.011ns] or [+5.390%; +5.830%]

scenario:tags/replace_trace_tags_v04

  • 🟥 execution_time [+182.641ns; +223.837ns] or [+6.577%; +8.061%]

scenario:vec_map/as_deduped_map/needs_dedup_1_in_10/64

  • 🟩 execution_time [-214.511ns; -212.523ns] or [-15.326%; -15.184%]

Unstable benchmarks

These benchmarks have a confidence interval too wide to call a change; treat them as noise rather than signal.

scenario:vec_map/get_mut/8

  • unstable execution_time [-12.714ns; -2.029ns] or [-13.962%; -2.228%]
  • unstable throughput [+1566291.002op/s; +13403751.574op/s] or [+1.692%; +14.476%]
Benchmark execution time: 2026-10-27 16:27:25

Comparing candidate commit d47ba93 in PR branch arjun.guha/dsm2-450-php-tracer-complete-the-kafka-integration with baseline commit 0a19dc2 in branch arjun.guha/dsm-shm-table.

📊 Benchmarking dashboard

Found 1 performance improvements and 3 performance regressions! Performance is the same for 91 metrics, 0 unstable metrics.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

scenario:normalization/normalize_service/normalize_service/[empty string]

  • 🟥 execution_time [+1.736µs; +1.763µs] or [+4.787%; +4.861%]
  • 🟥 throughput [-1278721.548op/s; -1259144.909op/s] or [-4.638%; -4.567%]

scenario:thread_cpu/alloc_free/system/4096

  • 🟩 execution_time [-13.023ns; -12.869ns] or [-13.872%; -13.707%]

scenario:thread_cpu/profiler_attached/slow_path_system/4096

  • 🟥 execution_time [+10.665ns; +10.785ns] or [+7.484%; +7.568%]

Benchmark execution time: 2026-10-27 16:32:07

Comparing candidate commit d47ba93 in PR branch arjun.guha/dsm2-450-php-tracer-complete-the-kafka-integration with baseline commit 0a19dc2 in branch arjun.guha/dsm-shm-table.

📊 Benchmarking dashboard

Found 2 performance improvements and 2 performance regressions! Performance is the same for 68 metrics, 24 unstable metrics.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

scenario:trace_buffer/1_senders/no_delay

  • 🟩 execution_time [-39.726µs; -39.477µs] or [-14.344%; -14.254%]
  • 🟩 throughput [+540511.870op/s; +543863.968op/s] or [+16.633%; +16.736%]

scenario:trace_buffer/4_senders/no_delay

  • 🟥 execution_time [+170.969µs; +178.156µs] or [+8.550%; +8.910%]
  • 🟥 throughput [-147420.920op/s; -141600.057op/s] or [-8.188%; -7.864%]

Unstable benchmarks

These benchmarks have a confidence interval too wide to call a change; treat them as noise rather than signal.

scenario:datadog_sample_span/complex_rule_matching/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+555.735%; -555.735%]

scenario:datadog_sample_span/complex_rule_partial_match/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+569.317%; -562.174%]

scenario:datadog_sample_span/many_attributes_tag_rule/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+559.678%; -557.595%]

scenario:datadog_sample_span/multiple_rules_first_match/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+554.071%; -554.952%]

scenario:datadog_sample_span/multiple_rules_last_match/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+555.735%; -555.735%]

scenario:datadog_sample_span/name_pattern_rule_matching/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+555.735%; -555.735%]

scenario:datadog_sample_span/name_pattern_rule_not_matching/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+552.939%; -554.421%]

scenario:datadog_sample_span/parent_not_sampled_short_circuit/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+568.169%; -561.626%]

scenario:datadog_sample_span/parent_sampled_short_circuit/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+558.147%; -556.872%]

scenario:datadog_sample_span/resource_pattern_rule_matching/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+555.735%; -555.735%]

scenario:datadog_sample_span/resource_pattern_rule_not_matching/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+558.558%; -557.066%]

scenario:datadog_sample_span/root_span_no_rules/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+557.779%; -556.698%]

scenario:datadog_sample_span/service_rule_matching/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+555.735%; -555.735%]

scenario:datadog_sample_span/service_rule_not_matching/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+553.474%; -554.672%]

scenario:datadog_sample_span/tag_rule_matching/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+559.306%; -557.419%]

scenario:datadog_sample_span/tag_rule_not_matching/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+565.469%; -560.340%]

scenario:glob_matcher/ascii_case_insensitive_match/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+575.259%; -565.019%]

scenario:glob_matcher/ascii_exact_match/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+552.863%; -554.385%]

scenario:glob_matcher/ascii_exact_miss/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+558.346%; -556.965%]

scenario:glob_matcher/ascii_wildcard_backtrack_match/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+557.310%; -556.477%]

scenario:glob_matcher/ascii_wildcard_heavy_backtrack/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+560.087%; -557.788%]

scenario:glob_matcher/ascii_wildcard_question_match/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+554.965%; -555.373%]

scenario:glob_matcher/ascii_wildcard_star_match/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+555.735%; -555.735%]

scenario:glob_matcher/star_short_circuit/allocated_bytes

  • unstable execution_time [-0.000ns; +0.000ns] or [+553.150%; -554.520%]

Candidate

Omitted due to size.

Baseline

Omitted due to size.

@dd-octo-sts

dd-octo-sts Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Artifact Size Benchmark Report

aarch64-alpine-linux-musl
Artifact Baseline Commit Change
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.a 96.56 MB 95.88 MB --.69% (-691.75 KB) 💪
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.so 9.08 MB 9.21 MB +1.37% (+128.23 KB) ⚠️
aarch64-unknown-linux-gnu
Artifact Baseline Commit Change
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.a 108.05 MB 107.00 MB --.97% (-1.05 MB) 💪
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.so 12.29 MB 12.31 MB +.17% (+21.73 KB) 🔍
libdatadog-x64-windows
Artifact Baseline Commit Change
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.dll 29.24 MB 29.56 MB +1.07% (+322.50 KB) ⚠️
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.lib 99.56 KB 99.02 KB --.54% (-556 B) 💪
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.pdb 193.18 MB 194.23 MB +.54% (+1.05 MB) 🔍
/libdatadog-x64-windows/debug/static/datadog_profiling_ffi.lib 822.80 MB 819.74 MB --.37% (-3.06 MB) 💪
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.dll 9.81 MB 9.69 MB --1.18% (-119.50 KB) 💪
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.lib 99.56 KB 99.02 KB --.54% (-556 B) 💪
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.pdb 27.60 MB 27.66 MB +.19% (+56.00 KB) 🔍
/libdatadog-x64-windows/release/static/datadog_profiling_ffi.lib 55.88 MB 55.67 MB --.37% (-214.62 KB) 💪
libdatadog-x86-windows
Artifact Baseline Commit Change
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.dll 25.68 MB 26.06 MB +1.49% (+394.00 KB) ⚠️
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.lib 101.12 KB 100.56 KB --.55% (-572 B) 💪
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.pdb 198.82 MB 199.82 MB +.50% (+1.00 MB) 🔍
/libdatadog-x86-windows/debug/static/datadog_profiling_ffi.lib 809.61 MB 806.36 MB --.40% (-3.24 MB) 💪
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.dll 7.60 MB 7.48 MB --1.52% (-118.50 KB) 💪
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.lib 101.12 KB 100.56 KB --.55% (-572 B) 💪
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.pdb 29.73 MB 29.71 MB --.07% (-24.00 KB) 💪
/libdatadog-x86-windows/release/static/datadog_profiling_ffi.lib 52.81 MB 52.54 MB --.51% (-279.85 KB) 💪
x86_64-alpine-linux-musl
Artifact Baseline Commit Change
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.a 86.56 MB 86.42 MB --.16% (-148.32 KB) 💪
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.so 10.12 MB 9.99 MB --1.27% (-131.74 KB) 💪
x86_64-unknown-linux-gnu
Artifact Baseline Commit Change
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.a 102.39 MB 101.97 MB --.40% (-421.86 KB) 💪
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.so 12.37 MB 12.22 MB --1.20% (-152.96 KB) 💪

@arjunguhaswe
arjunguhaswe marked this pull request as ready for review October 26, 2026 18:01
@arjunguhaswe
arjunguhaswe requested review from a team as code owners October 26, 2026 18:01
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-26T18:05:22.165052Z 52c0f49 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 52c0f49740

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

DEFAULT_DSM_CHECKPOINT_SLOT_COUNT,
DEFAULT_DSM_CHECKPOINT_STRING_POOL_BYTES,
)
.inspect_err(|_| backlogs.unlink())?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Signal the partial backlog table before unlinking

If checkpoint-table creation fails after another worker has opened the newly published backlog segment, unlink() removes only its name and leaves that worker's existing mapping marked ready. The worker therefore keeps accepting backlog writes as successful instead of falling back to IPC, while no sidecar state owns or drains the mapping, silently losing those offsets. Signal reload on backlogs before unlinking it on this error path.

Useful? React with 👍 / 👎.

arjunguhaswe and others added 2 commits October 27, 2026 10:43
…rjun.guha/dsm2-450-php-tracer-complete-the-kafka-integration
pool_string now returns None for a reference that does not resolve or
does not fit the flush budget. A backlog with such a value is dropped
rather than exported with that value blank, which would merge it with,
or pass it off as, another backlog. A present tag with an empty value is
still reported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Pipelines  Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
• Patch Coverage: 91.30%
• Overall Coverage: 79.26% (+1.09%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: d47ba93 | Docs | View more details | Give us feedback!

…rjun.guha/dsm2-450-php-tracer-complete-the-kafka-integration
…rjun.guha/dsm2-450-php-tracer-complete-the-kafka-integration

@yannham yannham left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Some questions, nothing blocking 👍

Comment on lines +31 to +35
/// Positions are durable. A new tag is appended at the end, after the last one; none is ever
/// reordered, removed or reused, so adding one leaves every existing backlog's `Tags` as they
/// were. (Appending one changes the slot, so it also bumps [`DataStreamsBacklogs`]'s version.)
/// The order of the first five is the Java tracer's (`DataStreamsTags`), so that a backlog is
/// reported with the same `Tags` whichever tracer sent it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: I'm not sure to understand this part at this point. BacklogTag is a simple enum, but we're talking about positions and re-ordering. Should this move to the code that actually append or do stuff with tags?

Partition = 4,
}

impl BacklogTag {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We tend to use strum_macros::EnumIter and AsRefStr to do that automatically instead of defining ALL etc. manually

h.write_u8(input.present());
for value in input.tags.iter().flatten() {
value.hash(&mut h);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same as in the previous PR: is this different from the Hash implementation of DsmBacklogInput?

///
/// `None` when the slot's key is not one this writer could have produced; the offset is
/// cleared either way, so that it is not left for whichever key next occupies the slot.
fn drain_entry(entry: &ShmEntry, pool: &Pool, budget: &mut usize) -> Option<DsmBacklog> {

@yannham yannham Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

My clanker relates that there might be a race with a concurrent writer:

  1. Writer find a slot with a matching hash. Has loaded it and checked for equality
  2. Drainer comes, nullify value, and stores SLOT_EMPTY in the hash
  3. A second writer comes, reclaim the empty slot, write the key and publish the hash
  4. The first writer resumes and stores an unrelated value in the slot

To be honest the whole shmem structure is kinda complex, so I don't have a precise enough mental model to know if 1. that's actually possible and 2. we should care, but reporting just in case.

drained: &Drained,
) -> anyhow::Result<Vec<u8>> {
// Both tables' buckets for an interval go out as one, ordered by start.
let mut buckets: BTreeMap<(u64, u64), StatsBucket<'_>> = BTreeMap::new();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not very important, but is there a reason to use a BTreeMap here over a hashmap?

This branch has not been deployed

No deployments
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.

2 participants