# uprobe ## 定義 uprobe(userspace probe)は、Linux カーネルが提供する動的計装機構であり、ユーザ空間プログラムの関数入口や出口にブレークポイントを設置して、引数・戻り値・実行時コンテキストを観測する仕組みである。[[eBPF]] プログラムを uprobe にアタッチすることで、対象プロセスのソース改変や再起動を伴わずに計装できる。(Source: [[@2021__yuuk.io__Linux eBPF Tracing Technology]]) ### perf(1) での実務操作(13章) [[perf]](1) は `perf probe -x <binary> --add <func>` で uprobe を作成する。たとえば libc の `fopen(3)` に対して `perf probe -x /lib/x86_64-linux-gnu/libc.so.6 --add fopen` を実行すると `probe_libc:fopen` というイベント名が作られ、`perf record -e probe_libc:fopen` で記録できる。`%return` を付ければ uretprobe になる。引数取得は debuginfo があれば `--vars` で変数リストを取得できるが、debuginfo がない場合は ABI 知識に基づくレジスタ指定構文(例: `filename=+0(%di):string mode=%si:u8`。別名定義・レジスタ指定・`+0(...)` によるオフセット間接参照・`:string`/`:u8` などの型指定を組み合わせる)で引数を読み取れる。ただし uprobe はソフトウェアのバージョンが変わると変化しうるバイナリを直接インストルメンテーションするため不安定なインターフェイスであり、USDT プローブが使えるならそちらを優先すべきとされる。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 13 perf]] §13.7.2, §13.7.2.1) ### Ftrace tracefs での実務操作(14章) [[Ftrace]] は uprobe を `uprobe_events` ファイルへの `p[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS]`(プローブ設定)・`r[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS]`(リターンプローブ/uretprobe)・`-:[GRP/]EVENT`(クリア)という構文で直接操作する。カーネルはユーザー空間ソフトウェアのシンボル情報を持たないため、`readelf -s <binary> | grep -w <func>` などでシンボルオフセットを事前に調べてカーネルに渡す必要がある。誤って命令途中のオフセットを指定するとターゲットプロセス(共有テキストの場合は共有する全プロセス)を壊す危険があり、ASLR + PIE でコンパイルされたバイナリではオフセット探索テクニックが機能しないことがある。著者はこの理由から、シンボルマッピングを行ってくれる BCC や bpftrace など高水準トレーサーの利用を推奨している。有効化された uprobe のヒット数は `uprobe_profile` ファイルに集計される。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 14 Ftrace]] §14.7〜§14.7.4) ## 横断的知見 - **13章の「不安定インターフェイス」評価は、eBPF系ソースが示す実装依存の脆さと同じ懸念を指している**: 『詳解 システム・パフォーマンス 第2版』13章は、uprobe がバイナリを直接インストルメンテーションするため「ソフトウェアのバージョンが変わると変化しうる」不安定なインターフェイスだと明言し、USDT が使えるならそちらを優先すべきだとする。これは、ランタイムライブラリのシンボル名・ABI がバージョンで変化した場合に uprobe ベースのツールがどこまで自動適応できるか、という本ページの既存の未解決の問い(eunomia.dev 由来)に対して、書籍側から「そもそも不安定性は設計上織り込み済みであり、安定 API があれば使うべき」という規範的な回答を与えている。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 13 perf]] §13.7.2.1, [[@2026__eunomia.dev__CUDA Events - eBPF-based CUDA API Tracing]]) - **debuginfo がない場合の引数取得手順は、kprobe と uprobe で同じ「参照システム+ABI 知識」パターンを共有する**: 13章は kprobe([[kprobe]])・uprobe いずれも、debuginfo がない本番環境では同一 ABI・カーネルの参照システムでレジスタ割り当てを一度調べてから対象システムに適用するという同じ回避策を提示する。これはカーネル空間・ユーザ空間という実装の違いを超えて、perf(1) の動的プローブ全体に共通する運用パターンであることを示す。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 13 perf]] §13.7.1.1, §13.7.2.1) - **uprobe はライブラリ境界の関数呼び出しを非侵襲に観測する**: CUDA ランタイムライブラリ `libcudart.so` の `cudaMalloc` や `cudaLaunchKernel` といった関数に uprobe を当てることで、アプリケーションのソースを変更せずに GPU 利用の入口をモニタリングできる。(Source: [[@2026__eunomia.dev__CUDA Events - eBPF-based CUDA API Tracing]]) - **return probe(uretprobe)と組み合わせると関数の入出力を両方捉えられる**: enter プローブで引数(サイズ・方向など)、return プローブで戻り値(エラーコードなど)を取得する。これにより API 呼び出しの成否とリソース操作の対応関係を追跡できる。(Source: [[@2026__eunomia.dev__CUDA Events - eBPF-based CUDA API Tracing]]) - **uprobe の粒度は関数レベルに制限される**: 関数内部の基本ブロックやメモリアクセスまでは直接観測できない。より細かい粒度が必要な場合は、コンパイル時計装や実行時バイナリ書き換え(PTX/SASS 注入)、ハードウェアカウンタなど他の計装層を併用する。(Source: [[@2026__eunomia.dev__CUDA Events - eBPF-based CUDA API Tracing]], [[@2025__HCDS__eGPU - Extending eBPF Programmability and Observability to GPUs]]) - **uprobe のオーバーヘッドは実行場所(カーネル vs ユーザ空間)で桁違いに変わる**: Linux カーネル uprobe はブレークポイントでカーネルトラップを発生させ、1 呼び出しあたり約 2,500-3,000 ns のオーバーヘッドを持つ。対して [[bpftime]] のようなユーザ空間 eBPF ランタイムは、同一プロセス内で拡張を実行し、uprobe/uretprobe をそれぞれ 190/187 ns に短縮する。これはソース改変なしの非侵襲計装が「カーネルで実行するか」「ユーザ空間で実行するか」という実装選択で、オーバーヘッドの桁が変わることを示す。ただし syscall tracepoint や hash_map_lookup など一部操作ではカーネル eBPF の方が有利なため、観測対象と操作の組み合わせで使い分ける必要がある。(Source: [[@2025__OSDI__Extending Applications Safely and Efficiently]], [[@2026__eunomia.dev__CUDA Events - eBPF-based CUDA API Tracing]]) - **kprobe/uprobe/kretprobe/uretprobeのCPUオーバーヘッド最小値は、kprobe→kretprobe→uprobe→uretprobeの順に段階的に増加する**: 『詳解 システム・パフォーマンス 第2版』4章は、実測値としてkprobe最小76ns、kretprobe最小212ns、uprobe最小1,287ns、uretprobe最小1,931nsを報告する(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 4 可観測性ツール]])。uprobeがkprobeより一桁高コストなのは、現在のuprobe実装がトラップでカーネルに入り込んで動作するためと説明されており、この定性的な順序(uprobe/uretprobe > kprobe/kretprobe)は [[@2025__OSDI__Extending Applications Safely and Efficiently]] が報告するカーネルuprobeオーバーヘッド(約2,500-3,000ns)と整合する。ただし絶対値は測定条件(カーネルバージョン・CPU・呼び出しパターン)により1桁近く異なりうるため、比較には注意が要る。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 4 可観測性ツール]], [[@2025__OSDI__Extending Applications Safely and Efficiently]]) - **13章の「不安定インターフェイス」評価と14章の「オフセット直接指定は危険」という警告は、同じ脆さを異なる抽象度から見た記述である**: 13章は perf(1) の `perf probe -x` を通じて uprobe が「ソフトウェアのバージョンが変わると変化しうる」不安定な API だと評価するが、14章は Ftrace の `uprobe_events` を通じてさらに具体的な危険を示す。すなわち `readelf -s` で調べたシンボルオフセットが ASLR + PIE 環境では機能しないことがあり、命令途中を指すオフセットを誤って指定するとターゲットプロセス(共有テキストなら共有する全プロセス)を破壊しうる。両章とも到達する結論は同じで、生の uprobe インターフェイス(perf probe のレジスタ直接指定、Ftrace の readelf 手動オフセット探索)は本番投入を避け、シンボルマッピングを自動化する BCC・bpftrace のような高水準トレーサーを使うべきだとする。(Source: [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 13 perf]] §13.7.2.1, [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 14 Ftrace]] §14.7.1) ## 未解決の問い - uprobe のオーバーヘッドは関数呼び出し頻度に依存するが、高頻度なユーザ空間関数(例: 推論エンジンの内部ループ)を常時トレースした際の許容限界はどう定量化できるか。 - ランタイムライブラリのシンボル名や ABI がバージョンで変化した場合、uprobe ベースのツールはどの程度自動的に適応できるか。 - ユーザ空間 uprobe 実行([[bpftime]])とカーネル uprobe 実行は、観測対象の関数種別(計算密集型 vs システムコール密集型)とデータ共有範囲(プロセス内 vs カーネル全体)でどう使い分けるか。 - カーネルuprobeオーバーヘッドの実測値(1,287ns 対 2,500-3,000ns)の差は、測定手法・カーネルバージョン・呼び出しパターンのどれに起因するか。両者を同一環境で再測定すると一致するか。 - USDT プローブがそもそも存在しないバイナリ(自社開発の内部サービスなど)では、13章が示す「USDT を優先せよ」という指針は適用できない。そのような場合、uprobe の不安定性(ABI 依存)をどこまで緩和する運用プラクティスがあるか。 ## 関連 - 概念: [[eBPF]] / [[動的計装]] / [[CUDA API トレース]] / [[GPU観測性]] / [[kprobe]] / [[Extension Interface Model]] - エンティティ: [[libbpf]] / [[bpftrace]] / [[BCC]] / [[bpftime]] / [[Brendan Gregg]] / [[perf]] / [[Ftrace]] - ソース: [[@2021__yuuk.io__Linux eBPF Tracing Technology]] / [[@2026__eunomia.dev__CUDA Events - eBPF-based CUDA API Tracing]] / [[@2025__OSDI__Extending Applications Safely and Efficiently]] / [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 4 可観測性ツール]] / [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 13 perf]] / [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 14 Ftrace]] ## 出典 - [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 13 perf]](§13.7.2 perf probe -x による uprobe 作成、§13.7.2.1 引数取得構文とレジスタ指定) - [[@2023__OReillyJapan__詳解 システム・パフォーマンス 第2版 - Chapter 14 Ftrace]](§14.7 uprobe_eventsテキストインターフェース、ASLR/PIEでのオフセット探索の危険性、uprobe_profile)