Skip to content

feat: native socket I/O tracking via PLT hooks (PROF-10637)#488

Merged
jbachorik merged 31 commits into
mainfrom
muse/impl-20260416-133933
Jun 10, 2026
Merged

feat: native socket I/O tracking via PLT hooks (PROF-10637)#488
jbachorik merged 31 commits into
mainfrom
muse/impl-20260416-133933

Conversation

@jbachorik

@jbachorik jbachorik commented Apr 16, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Intercepts libc send, recv, write, read via PLT hooking and records
datadog.NativeSocketEvent JFR events with time-weighted inverse-transform
sampling (Poisson process, PID rate control, target ~83 events/s / ~5000/min).

Motivation

Track blocking TCP socket I/O at the libc function level to surface socket
latency and throughput in the Datadog profiler. Netty with Java NIO transport
(the primary use case) goes through libc send/recv/write/read, making
PLT patching the right interception point. Feature is explicitly opt-in via
the natsock profiler argument. Implements PROF-10637.

Configuration

Argument Effect
natsock Enable native socket tracking with the default 1 ms initial period
natsock=100us Enable with an explicit initial sampling period (any parseUnits unit: ns, us, ms, s)

The interval is the initial parameter of the time-weighted Poisson process;
the PID controller adapts it at runtime to hold the total event rate near
TARGET_EVENTS_PER_SECOND (= 83 events/s) across all four hooks combined.

Architecture

flowchart LR
    A["Java code<br/>OutputStream.write()"] --> B["JDK native<br/>libnio/libnet"]
    B --> C{"PLT entry<br/>for write()"}
    C -- patched --> D["NativeSocketSampler::write_hook"]
    D --> E{"fd is TCP<br/>socket?"}
    E -- no --> F["orig write()"]
    E -- yes --> G["orig write()"]
    G --> H{"shouldSample<br/>(duration, op)"}
    H -- no --> I["return"]
    H -- yes --> J["recordEvent"]
    J --> K["JFR buffer"]
    F --> I
Loading

Sampling pipeline

flowchart TD
    A["Hook fires with<br/>duration_ticks"] --> B["PoissonSampler<br/>(thread_local)"]
    B --> C{"interval budget<br/>consumed?"}
    C -- no --> D["reject"]
    C -- yes --> E["compute weight<br/>1 / (1 - exp(-d/interval))"]
    E --> F["RateLimiter::accept()"]
    F --> G{"PID budget<br/>for this epoch?"}
    G -- no --> D
    G -- yes --> H["record event<br/>operation / fd-addr / bytes / weight"]
    H --> I["RateLimiter<br/>maybeUpdateInterval<br/>(PID: P=31 I=511 D=3)"]
    I --> J["next epoch interval"]
Loading

Two thread_local PoissonSampler instances per thread: outbound (send+write)
and inbound (recv+read). Both share one RateLimiter so the ~83 events/s
target is a single budget across all directions.

Hook installation

flowchart TD
    A["NativeSocketSampler::start"] --> B["dlsym RTLD_NEXT<br/>(RTLD_DEFAULT fallback on musl)<br/>resolve _orig_send/recv/write/read"]
    B --> C["patch_socket_functions"]
    C --> D["walk every loaded CodeCache"]
    D --> E{"lib imports<br/>send/recv/write/read?"}
    E -- yes --> F["rewrite PLT entry<br/>to *_hook"]
    E -- no --> G["skip"]
    C --> H["also patch dlopen PLT"]
    H --> I["dlopen_hook wraps<br/>subsequent loads"]
    I --> J["updateSymbols +<br/>install_socket_hooks"]
    J --> E
Loading

Late-loaded libraries (e.g. HotSpot lazily loads libnet.so on the first
java.net.Socket use) are caught by the dlopen wrapper which re-runs
patch_socket_functions after each new library is registered.

JFR event fields (datadog.NativeSocketEvent)

Field Type Description
startTime long Event start (ticks)
eventThread Thread Calling Java thread (constant pool)
stackTrace StackTrace Captured stack (constant pool)
duration long Syscall duration (ticks)
operation string SEND or RECV
remoteAddress string ip:port (IPv4 or [ipv6]:port); empty if unknown
bytesTransferred long Bytes actually transferred
weight float Inverse sampling probability (1 / P)
spanId long Datadog span id from active context
localRootSpanId long Datadog local root span id
context attrs strings User context attributes

sum(weight × duration) is an unbiased estimator of total socket I/O time;
sum(weight × bytesTransferred) estimates total bytes.

Key design notes

  • Scope: TCP blocking send/recv/write/read only. UDP (sendto/recvfrom)
    and Netty's native epoll / io_uring transports are explicitly out of scope.
  • Fast path: write/read hooks short-circuit on non-socket fds via a
    lock-free std::atomic<uint8_t> _fd_type_cache[65536] — one relaxed atomic
    load per call on the non-socket path.
  • Thread context: hook bodies run on the calling Java thread (not a signal
    handler), so malloc and std::mutex are safe.
  • PLT re-patching on dlopen: install_socket_hooks() (called from
    dlopen_hook after updateSymbols) re-runs patch_socket_functions so
    lazily-loaded libraries (libnet.so, libnio.so, native Netty transports)
    are patched the moment they appear.
  • fd-to-address cache: intentionally not cleared on JFR chunk boundaries;
    stale addresses for reused fds are a known, accepted trade-off to avoid
    racing with in-flight recordings.
  • Original function pointer lifecycle: _orig_send/recv/write/read are
    assigned once (when _socket_size == 0) and are intentionally not nulled in
    unpatch_socket_functions to avoid a memory-ordering race with in-flight
    hook invocations that may still be executing.
  • Platform scope: #if defined(__linux__) — compiled as no-op stubs on
    macOS. Runs on both glibc and musl Linux; on musl RTLD_NEXT returns NULL
    (libc precedes the profiler DSO in the link map), so RTLD_DEFAULT is used
    as fallback to locate the real libc symbols. Feature is additionally disabled
    in Java tests on J9/Zing via Platform.isJ9() / Platform.isZing() guards.
  • NativeSocketEvent lives in nativeSocketSampler.h (not the shared
    event.h) since it is only used by NativeSocketSampler.

How to test the change?

  • C++ unit testsNativeSocketSamplerHookTest in
    ddprof-lib/src/test/cpp/nativeSocketSampler_ut.cpp — verifies that
    send_hook/recv_hook/write_hook/read_hook each delegate to the
    installed _orig_* pointer and return its value.

  • JUnit integration tests in
    ddprof-test/src/test/java/com/datadoghq/profiler/nativesocket/:

    Test What it verifies
    NativeSocketEnabledTest Events produced when feature is enabled
    NativeSocketDisabledTest No events when feature is not enabled
    NativeSocketEventFieldsTest All required JFR fields present and valid
    NativeSocketEventThreadTest eventThread populated with the calling thread
    NativeSocketStackTraceTest Stack trace captured on events
    NativeSocketRemoteAddressTest remoteAddress in ip:port format
    NativeSocketSendRecvSeparateTest SEND and RECV tracked independently
    NativeSocketBytesAccuracyTest sum(weight × duration) unbiased estimator within tolerance
    NativeSocketRateLimitTest Event count ≪ operation count (PID rate control active); weight > 1 on sampled events
    NativeSocketRestartTest Events produced after profiler stop/restart cycle
    NativeSocketUdpExcludedTest UDP (sendto/recvfrom) produces zero events
    NativeSocketMacOsNoOpTest No events on macOS (no-op stub)

Spec: #487

For Datadog employees

  • If this PR touches code that signs or publishes builds or packages, or handles
    credentials of any kind, I've requested a review from @DataDog/security-design-and-guidance.
  • This PR doesn't touch any of that.
  • JIRA: PROF-10637

@dd-octo-sts

dd-octo-sts Bot commented Apr 16, 2026

Copy link
Copy Markdown
Contributor

CI Test Results

Run: #27286948682 | Commit: c878bb6 | Duration: 12m 20s (longest job)

All 32 test jobs passed

Status Overview

JDK glibc-aarch64/debug glibc-amd64/debug musl-aarch64/debug musl-amd64/debug
8 - - -
8-ibm - - -
8-j9 - -
8-librca - -
8-orcl - - -
11 - - -
11-j9 - -
11-librca - -
17 - -
17-graal - -
17-j9 - -
17-librca - -
21 - -
21-graal - -
21-librca - -
25 - -
25-graal - -
25-librca - -

Legend: ✅ passed | ❌ failed | ⚪ skipped | 🚫 cancelled

Summary: Total: 32 | Passed: 32 | Failed: 0


Updated: 2026-06-10 15:43:02 UTC

@jbachorik jbachorik force-pushed the muse/impl-20260416-133933 branch from d4feae7 to 7c6488b Compare April 20, 2026 13:17
@jbachorik jbachorik added AI and removed AI labels Apr 20, 2026
@jbachorik jbachorik marked this pull request as ready for review April 20, 2026 13:43
@jbachorik jbachorik requested a review from a team as a code owner April 20, 2026 13:43
@jbachorik jbachorik changed the base branch from main to jb/native_allocs April 20, 2026 13:45
@jbachorik jbachorik force-pushed the muse/impl-20260416-133933 branch from 6bec1dd to ddc2292 Compare April 20, 2026 15:47
@jbachorik jbachorik force-pushed the jb/native_allocs branch 4 times, most recently from a12cc1e to 44be5c7 Compare April 22, 2026 07:35
@jbachorik jbachorik force-pushed the muse/impl-20260416-133933 branch from 9955e7d to 17dd7e0 Compare April 22, 2026 08:20
Base automatically changed from jb/native_allocs to main April 23, 2026 20:03
@jbachorik jbachorik marked this pull request as draft April 27, 2026 20:13
@jbachorik jbachorik force-pushed the muse/impl-20260416-133933 branch from 17dd7e0 to cecb1bd Compare April 27, 2026 20:50
@jbachorik

Copy link
Copy Markdown
Collaborator Author

Could not apply automatically — The reviewer comment (ID 4261434558) is an automated CI test-results report showing all 32 jobs passed with no failures. There is no code concern, requested change, or actionable finding to address with a patch.. Manual attention needed.

jbachorik and others added 11 commits June 9, 2026 15:28
Ports native socket sampling on top of MallocTracer's native_allocs pattern.

Key design alignments with MallocTracer:
- recordEvent passes NULL ucontext to recordSample (was: synthesized via
  getcontext, which confused walkVM's signal-context invariants)
- Uses OS::threadId() instead of ProfiledThread::currentTid()
- profiler.cpp recordSample BCI_NATIVE_SOCKET routes through walkVM with
  NULL ucontext (DWARF/FP + JavaFrameAnchor fallback)
- Dlopen chain uses Profiler::dlopen_hook -> LibraryPatcher::install_socket_hooks
  (removes our custom dlopen_hook that previously clobbered Profiler::dlopen_hook)

Removed:
- Custom dlopen_hook and dlopen PLT patching in libraryPatcher_linux.cpp
- recordEvent ucontext synthesis via getcontext()

Kept:
- PoissonSampler + RateLimiter (time-weighted sampling with PID)
- Four hooks (send/recv/write/read) with per-thread Poisson state
- fd-type cache, fd->addr cache

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Tests assert the accessor for 'bytesTransferred' but I had renamed it
to 'bytes' during the native_allocs rebase. Restore original field
name and category/description to match existing tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rebase onto the merged-main base replaced Contexts::get()/writeContext
with the writeCurrentContext helper used by sibling event writers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Allow BCI_NATIVE_SOCKET in J9/Zing walkJavaStack assert; skip cpu/wall
config check when those intervals are not requested; drop Enabled/
EventFields iteration count from 5000 to 128.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Accept optional time unit on 'natsock' (e.g. natsock=100us); converted
to TSC ticks at start. NativeSocketSendRecvSeparateTest uses 100us to
avoid Poisson-sampling variance at the default 1ms period.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Short-lived 64KB transfers at the default 1ms Poisson period yield too
few samples to reliably match the server port.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Apply the natsock=100us override consistently to positive event tests
and UdpExcluded (stronger negative). RateLimitTest and Disabled keep
the 1ms default on purpose: rate-limiter PID stress and feature-off.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jbachorik and others added 3 commits June 9, 2026 15:28
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
cached_send (send_fn) and cached_recv (recv_fn) differ in their second
parameter (const void* vs void*); chaining the assignment forced an
implicit recv_fn -> send_fn conversion that clang rejects. Split into
two statements to match the line below.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jbachorik jbachorik force-pushed the muse/impl-20260416-133933 branch from 80d35d8 to ce1f2f6 Compare June 9, 2026 13:30
@datadog-prod-us1-3

This comment has been minimized.

jbachorik and others added 3 commits June 9, 2026 17:05
- profiler.cpp: stopRefresher() before NativeSocketSampler::stop() to
  prevent refresher from re-installing PLT hooks after unpatch
- libraryPatcher_linux.cpp: protect dlsym statics with std::call_once;
  set _socket_active=false before restoring PLT slots in unpatch;
  re-check _socket_active under lock in patch_socket_functions
- poissonSampler.h: cap double before u64 cast in nextExp() to avoid
  UB when interval=LONG_MAX; fix inaccurate U_min comment
- arguments.cpp: add errno=0/ERANGE check and multiplication overflow
  guard in parseUnits
- nativeSocketSampler.cpp: fix secs*tsc_freq u64 overflow before clamp;
  move _fd_cache_gen bump inside clearFdCache() under mutex; fix
  write_hook/read_hook double-counted debug counters; fix shouldSample
  op=2 routing to _send_sampler; call clearFdCache() in start()
- nativeSocketSampler.h: update shouldSample op comment (0/1/2/3)
- rateLimiter.h: clamp PID signal before long cast to avoid UB
- NativeSocketEventFieldsTest: guard ip:port check for AF_UNIX events
- NativeSocketRestartTest: createDirectories before createTempFile
- nativeSocketSampler_ut.cpp: fix EmptyValueRejected→BareNatsockEnables

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
patch_socket_functions() returned false on first call because the
_socket_active guard fired before any patching occurred (_socket_active
is only set at the end of the function). Guard now requires _socket_size>0
so the initial call from NativeSocketSampler::start() proceeds.

recordEvent() lacked an isRunning() guard: with _rate_limiter._interval
defaulting to 1, shouldSample() fires immediately in gtests, leading to
Profiler::recordSample() with _calltrace_buffer==NULL -> SIGSEGV.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jbachorik jbachorik requested a review from Copilot June 10, 2026 10:16
@jbachorik

Copy link
Copy Markdown
Collaborator Author

@codex review

@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: cb894e92c0

ℹ️ 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".

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

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ddprof-lib/src/main/cpp/nativeSocketSampler.cpp
Comment thread ddprof-lib/src/main/cpp/poissonSampler.h Outdated

Copilot AI 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.

Pull request overview

Adds an opt-in native socket I/O profiling feature on Linux by PLT-hooking libc send/recv/write/read and emitting a new datadog.NativeSocketEvent JFR event type with time-weighted Poisson sampling and PID-based global rate control.

Changes:

  • Introduces NativeSocketSampler (Poisson sampler + PID RateLimiter) and integrates it into the profiler start/stop lifecycle and JFR writer/metadata.
  • Extends Linux LibraryPatcher/CodeCache import scanning to patch GOT/PLT slots for send/recv/write/read, including repatching on library refresh.
  • Adds C++ unit tests plus Java integration tests and a JMH benchmark for coverage and overhead evaluation.

Reviewed changes

Copilot reviewed 36 out of 36 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
ddprof-test/src/test/java/com/datadoghq/profiler/nativesocket/NativeSocketUdpExcludedTest.java Adds UDP negative test for zero NativeSocketEvent emission.
ddprof-test/src/test/java/com/datadoghq/profiler/nativesocket/NativeSocketTestBase.java Shared TCP workload helper for nativesocket tests.
ddprof-test/src/test/java/com/datadoghq/profiler/nativesocket/NativeSocketStackTraceTest.java Validates stack traces are present on socket events across cstack modes.
ddprof-test/src/test/java/com/datadoghq/profiler/nativesocket/NativeSocketSendRecvSeparateTest.java Validates SEND/RECV directionality is tracked independently.
ddprof-test/src/test/java/com/datadoghq/profiler/nativesocket/NativeSocketRestartTest.java Validates stop/restart lifecycle continues to produce events.
ddprof-test/src/test/java/com/datadoghq/profiler/nativesocket/NativeSocketRemoteAddressTest.java Validates remoteAddress formatting and matching server port.
ddprof-test/src/test/java/com/datadoghq/profiler/nativesocket/NativeSocketRateLimitTest.java Validates subsampling/rate limiting and weight behavior.
ddprof-test/src/test/java/com/datadoghq/profiler/nativesocket/NativeSocketMacOsNoOpTest.java Validates macOS no-op behavior produces no events.
ddprof-test/src/test/java/com/datadoghq/profiler/nativesocket/NativeSocketEventThreadTest.java Validates eventThread population.
ddprof-test/src/test/java/com/datadoghq/profiler/nativesocket/NativeSocketEventFieldsTest.java Validates required event fields exist and are valid.
ddprof-test/src/test/java/com/datadoghq/profiler/nativesocket/NativeSocketEnabledTest.java Smoke test: events emitted when enabled.
ddprof-test/src/test/java/com/datadoghq/profiler/nativesocket/NativeSocketDisabledTest.java Smoke test: no events when not enabled.
ddprof-test/src/test/java/com/datadoghq/profiler/nativesocket/NativeSocketBytesAccuracyTest.java Validates sum(weight × duration) is within reasonable bounds.
ddprof-stresstest/src/jmh/java/com/datadoghq/profiler/stresstest/scenarios/throughput/NativeSocketOverheadBenchmark.java Adds JMH benchmark to quantify hook overhead for file/socket/NIO writes.
ddprof-lib/src/test/cpp/nativeSocketSampler_ut.cpp Adds gtest coverage for hooks, PoissonSampler, and args parsing.
ddprof-lib/src/main/cpp/vmEntry.h Adds BCI_NATIVE_SOCKET frame type.
ddprof-lib/src/main/cpp/rateLimiter.h Adds shared PID-based rate limiter used by socket sampler.
ddprof-lib/src/main/cpp/profiler.cpp Integrates nativesocket engine into start/stop/check and refresher ordering.
ddprof-lib/src/main/cpp/poissonSampler.h Adds thread-local Poisson-process sampler with inverse-probability weights.
ddprof-lib/src/main/cpp/nativeSocketSampler.h Declares sampler engine, caches, and hook entry points.
ddprof-lib/src/main/cpp/nativeSocketSampler.cpp Implements hooks, fd classification/address caching, sampling, and event recording.
ddprof-lib/src/main/cpp/livenessTracker.cpp Fixes _record_heap_usage initialization on reused singleton.
ddprof-lib/src/main/cpp/libraryPatcher.h Adds socket patching APIs and _socket_active state.
ddprof-lib/src/main/cpp/libraryPatcher_linux.cpp Implements GOT/PLT patch/unpatch for send/recv/write/read with dlopen refresh support.
ddprof-lib/src/main/cpp/libraries.cpp Triggers socket hook installation during library refresh.
ddprof-lib/src/main/cpp/jvmSupport.cpp Allows OpenJ9/Zing stack walking for BCI_NATIVE_SOCKET.
ddprof-lib/src/main/cpp/jfrMetadata.h Adds new JFR type id for native socket event.
ddprof-lib/src/main/cpp/jfrMetadata.cpp Registers datadog.NativeSocketEvent fields in metadata.
ddprof-lib/src/main/cpp/hotspot/hotspotSupport.cpp Extends stack walking logic to handle BCI_NATIVE_SOCKET.
ddprof-lib/src/main/cpp/flightRecorder.h Adds recording API for native socket samples.
ddprof-lib/src/main/cpp/flightRecorder.cpp Serializes native socket event payload into JFR buffers.
ddprof-lib/src/main/cpp/event.h Adds NativeSocketEvent struct used by recorder.
ddprof-lib/src/main/cpp/codeCache.h Adds import IDs for send/recv/write/read.
ddprof-lib/src/main/cpp/codeCache.cpp Detects and stores GOT imports for send/recv/write/read.
ddprof-lib/src/main/cpp/arguments.h Adds _nativesocket + _nativesocket_interval and event mask bit.
ddprof-lib/src/main/cpp/arguments.cpp Parses natsock[=<duration>] and hardens parseUnits overflow handling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ddprof-lib/src/main/cpp/nativeSocketSampler.h
Comment thread ddprof-lib/src/main/cpp/nativeSocketSampler.cpp

@rkennke rkennke 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.

This is a nice feature! I have a few requests.

Comment thread ddprof-lib/src/main/cpp/flightRecorder.cpp Outdated
Comment thread ddprof-lib/src/main/cpp/livenessTracker.cpp Outdated
Comment thread ddprof-lib/src/main/cpp/nativeSocketSampler.h Outdated
Comment thread ddprof-lib/src/main/cpp/nativeSocketSampler.h
Comment thread ddprof-lib/src/main/cpp/nativeSocketSampler.h Outdated
jbachorik and others added 5 commits June 10, 2026 16:21
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
- Revalidate cached SOCKET fd-type verdicts to prevent reused-fd misclassification
- Drain crossed Poisson thresholds (rebase on _used) to avoid burst-sampling bias
- Clamp TSC duration subtraction for socket/lock/park events on core migration
- Declare _orig_* libc pointers std::atomic with acquire/release
- Log when the fd->addr cache latches full
- Remove redundant second clearFdCache() in start()
- Revert stray _record_heap_usage assignment pulled in by rebase
- Fix benchmark profiler arg natsock; drop unused imports; correct time-weighted wording

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jbachorik jbachorik marked this pull request as ready for review June 10, 2026 15:08
@jbachorik jbachorik requested a review from rkennke June 10, 2026 15:08

@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: c2a04e9ea9

ℹ️ 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".

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

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ddprof-lib/src/main/cpp/nativeSocketSampler.cpp Outdated
Comment thread ddprof-lib/src/main/cpp/nativeSocketSampler.cpp
- Clamp TSC inversion in shouldSample() (pass 0 on t1<t0)
- Defer getsockopt revalidation to sampled write/read events only
- Extract insertFdAddrLocked(); add LRU unit tests + test seams
- Add RateLimiter upper clamp (1L<<40, mirrors MallocTracer)
- Deduplicate doTcpTransfer via NativeSocketTestBase
- Tighten rate-limit assertion: operations/5 instead of operations/2

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jbachorik jbachorik force-pushed the muse/impl-20260416-133933 branch from 0287441 to 57b4dfa Compare June 10, 2026 15:16
…d/recv

- Always call resolveAddr() for sampled events so fd reuse is detected
  within one sampling interval (was: stale address persisted until restart)
- Add isSocket() guard to send_hook/recv_hook; connected UDP sockets
  (SOCK_DGRAM using send/recv) were emitting NativeSocketEvent
- Move MAX_FD_CACHE to public (needed by LRU unit tests)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@rkennke rkennke 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.

Thanks for addressing the issues. Looks good now!

@jbachorik

Copy link
Copy Markdown
Collaborator Author

@rkennke Thanks for the patient review :)

@jbachorik jbachorik merged commit 6828873 into main Jun 10, 2026
103 checks passed
@jbachorik jbachorik deleted the muse/impl-20260416-133933 branch June 10, 2026 15:51
@github-actions github-actions Bot added this to the 1.45.0 milestone Jun 10, 2026
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.

3 participants