Intermittent JVM SIGBUS (BUS_ADRERR) from DogStatsD-over-UDS: java-dogstatsd-client → jnr-unixsocket → jffi stub truncation (jnr/jffi#194)
メンテナーはふだん 2 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 35/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 静か
- 技術スタック
- java
調査の方向性
datadog.metrics.impl.statsd.DDAgentStatsDConnection.doConnect と、UnixSocketAddress を作成する bundled java-dogstatsd-client パスから始め、その後 jnr.jffi.internal.StubLoader.unpackLibrary と jnr/jffi#194 を読みます。決定論的な再現手順は提供されていないため、報告された hs_err スタックとロード条件を検証に使用します。DogStatsD-over-UDS パスで説明されている JVM SIGBUS が発生しなくなれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Tracer Version(s)
1.62.0
Java Version(s)
21.0.6 (Azul Zulu 21.40+17-CA)
JVM Vendor
Azul Systems (Zulu OpenJDK)
Bug Report
Short-lived JVMs configured to reach the Agent over a UDS intermittently die with a JVM-level SIGBUS (si_code 2 BUS_ADRERR) — a native crash, not an application error — while the tracer's metrics subsystem brings up its DogStatsD connection.
The root cause is upstream in jnr/jffi (filed as jnr/jffi#194): when DogStatsD is sent over a Unix socket, the bundled com.datadoghq:java-dogstatsd-client constructs a jnr.unixsocket.UnixSocketAddress, which initializes jnr-ffi → jffi. jffi's StubLoader.unpackLibrary extracts its native stub with an InputStream.available()-guarded copy loop that silently truncates the .so (it does no length/digest check on a fresh extraction). System.load() of the short stub then faults in ld.so past EOF → SIGBUS/BUS_ADRERR.
hs_err excerpt:
# SIGBUS (0x7) ...
# Problematic frame: # C [ld-linux-x86-64.so.2+0x26b4a] (dlopen)
siginfo: si_signo: 7 (SIGBUS), si_code: 2 (BUS_ADRERR)
Current thread: JavaThread "dd-task-scheduler"
C [ld-linux-x86-64.so.2 ...] (dlopen)
V [libjvm.so ...] JVM_LoadLibrary
j com.kenai.jffi.internal.StubLoader.loadFromJar / <clinit>
j jnr.ffi.Runtime.getSystemRuntime
j jnr.unixsocket.UnixSocketAddress.<init>
j com.timgroup.statsd.NonBlockingStatsDClientBuilder.build
j datadog.metrics.impl.statsd.DDAgentStatsDConnection.doConnect
j datadog.trace.util.AgentTaskScheduler$PeriodicTask.run
The extracted …/jffi<rand>.so was truncated at a 4 KiB boundary; the dynamic linker's relocation write into the missing final page hit EOF → BUS_ADRERR.
Scope / notes:
- Only the DogStatsD path is affected. The Agent's own trace/EVP transport over UDS uses the JDK-native socket (
dd.jdk.socket.enabled, defaulttrue) and does not load jffi — consistent with jffi initializing ~20s in, inside the DogStatsD connect task, never at startup. The bundledjava-dogstatsd-clientis the sole remaining jnr/jffi consumer. - Tracer metrics are on by default, so this can fire in any UDS-configured JVM that lives long enough to run the periodic StatsD connect.
- It is a timing race in jffi's copy loop — rare per-extraction, but frequent across a high-volume / CPU-saturated CI fleet (many thousands of short-lived JVMs). Long-lived production processes (one extraction at controlled startup) effectively never hit it.
- The crash kills the JVM before data is flushed, so it is invisible in APM / CI Visibility and only recoverable from captured
hs_errfiles.
Expected Behavior
Configuring the Agent connection as a UDS (and the tracer emitting its own metrics) must not be able to crash the host JVM. DogStatsD over UDS should not pull in a native FFI stub whose extraction can fail unsafely.
Reproduction Code
No deterministic repro — it is a timing race in jffi's stub extraction (see jnr/jffi#194). It reproduces statistically under load with:
dd-java-agent1.62.0 attached, JDK 21DD_TRACE_AGENT_URL=unix:///var/run/datadog/apm.socket(so DogStatsD also resolves to a UDS)- default tracer metrics (health metrics on)
- many short-lived JVMs on CPU-saturated hosts
Diagnosed from captured -XX:ErrorFile hs_err logs showing the stack above and a truncated jffi*.so.
Suggested fixes
- Upstream: the actual defect is jffi's
unpackLibrary(jnr/jffi#194) — pick up the fix / bump jffi once available. - Decouple DogStatsD-over-UDS from jnr/jffi: have the bundled
java-dogstatsd-clientuse the JDK-nativejava.net.UnixDomainSocketAddress(JDK 16+) for UDS, as the Agent transport already does viadd.jdk.socket.enabled. This removes jffi from the metrics path entirely (cf. DataDog/java-dogstatsd-client#68, #85). - Or pin / pre-extract the jffi stub (
-Djffi.boot.library.path=…) in the agent so the buggyunpackLibrarycopy is never exercised.
Related: jnr/jffi#194, jnr/jffi#46, jnr/jffi#158, DataDog/java-dogstatsd-client#68 / #85 / #258, #7643, #7165.
- 主要言語
- Java
- スター
- 737
- フォーク
- 361
- 平均マージ
- 3日 13時間
- マージ済み PR(30日)
- 171
環境構築
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
DataDog/dd-trace-java のほかの issue
-
type: feature request
難易度 1/5 1〜3時間 初心者へのやさしさ 70/100
DataDog/dd-trace-java#10245 · コメント 1 件 ·
メンテナーはふだん 2 日以内に返信
-
gRPC server instrumentations (grpc-1.5, armeria-grpc) don't make extracted W3C baggage current in the handler対応中かも @mcculls が今日担当しました。 オープンcomp: context propagation inst: grpc type: feature request
難易度 3/5 1〜2日 初心者へのやさしさ 78/100
DataDog/dd-trace-java#12654 · 担当者 1 名 ·
メンテナーはふだん 2 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 62/100
DataDog/dd-trace-java#12608 ·
メンテナーはふだん 2 日以内に返信
-
type: bug report
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
DataDog/dd-trace-java#12597 ·
メンテナーはふだん 2 日以内に返信
-
Queueing-time profiler aborts the whole instrumentation install under a JDK 24+ AOT cache (zero spans); disabling that one feature is enough対応中かも @mcculls が 7 日前に担当しました。 オープン
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
DataDog/dd-trace-java#12540 · コメント 5 件 · 担当者 1 名 ·
メンテナーはふだん 2 日以内に返信
DataDog/dd-trace-java の issue をすべて見る
似ている issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
-
component/zeebe kind/bug
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
UniversalMediaServer/UniversalMediaServer#6356 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
refinedmods/refinedstorage2#1414 · コメント 1 件 ·
-
難易度 1/5 1〜3時間 初心者へのやさしさ 88/100
yegor256/rultor-image#76 · コメント 1 件 ·