ニックスが私のデバッガーの半分を書いた

2026/10/09 16:29

ニックスが私のデバッガーの半分を書いた

RSS: https://news.ycombinator.com/rss

要約▶

Japanese Translation:

Rewind VM は、Nix ビルドをその入力(スレッドスケジューリングを含む)の純粋な関数として扱い、ローカルストアおよびバイナリキャッシュに対してハッシュベースのチェックによる正確な再現性を検証することで、仮想マシンデバッグを決定論的に行います。このシステムは、ハッシュ付きクロージャーを含む読み取り専用 erofs イメージ上で起動します。ビルド ID は cache.nixos.org または

debuginfod
を介してデバッグ情報(Linux カーネルソースを含む)を取得するために使用されます。分析を支援するために、Rewind はソースパネル、スタックフレーム、
.rwd
エクスポートファイルに保存されたブックマーク、「Compare」タブで並置表示され最初に異なるイベントをハイライトするトレース比較機能、ゲストカーネルが各ステップで CPU 所有権を報告できるようにして実行を正確に再プレイするためのツールを提供します。
rewind gdb
を使用すると、すべてのスレッドを維持したまま VM の任意のステップでフォークできます。「Compare」タブと
rewind compare
は別々の実行間の差異を表に出し、
rewind check --run
は複数のスケジューリング下で任意のステップから実行をフォークして競合条件のインターリーブ可能性を評価します。この無料のデバッグインフラストラクチャ(入力、シンボル、ソース、決定論的分析機能)を提供することで、Rewind は高価な独占ツールなしで並行性问题への調査の障壁を下げてソフトウェアの信頼性を向上させます。

本文

Nix 導出を基盤とした Rewind VM:Race Condition 検知のための超能力

概要

数日前に提唱した Rewind VM は、入力(スレッドスケジューリングを含む)のみを受け入れる純粋関数として動作する決定論的な仮想マシンです。 このツールを用いて、Nix ビルドにおける多数の**実行順序依存バグ(Race Condition)**を発見、再現し、解決しています。

  • 機能の急速な拡張: ソースパネル、スタックフレーム、ブックマーク、「Compare」タブ、GDB 機能への対応など。
  • 驚異的な実装: 「大量のコード改修が必要」と考えがちだったが、実装の困難な部分は既に Nix 自身が提供していた。
    • デバッガー動作に必要な入力・シンボル情報・ソースコード・ライブラリ・環境再現方法などがすべて「Derivation(導出)」としてシンプルに確保できるため。

なぜ Rewind は Race Condition を浮き彫りにするのか?

銀行口座の例:典型的な Race Condition

2 つのスレッドが 1 つの口座にお金を預ける場合、以下の手順で競合が発生します。

  1. 残高を読み込む(
    seen
    )。
  2. ログに書き込む。
  3. 残高を更新する(
    balance = seen + amount
    )。

片方のスレッドが他者の「読み込み」と「保存」の間に実行されると、陳腐化されたデータを書き込んでしまい、資金が消失します。

// bank.c:24 - 簡易的な deposit 関数
static void deposit(int teller, long amount) {
  long seen = balance;      // [読み込み]
  char line[64];
  int n = snprintf(...);    // ログ出力
  
  if (write(1, line, n) != n) return;
  
  balance = seen + amount;  // [保存]
}
  • 現実での失敗: 16 コア搭載のノート PC で 1,000 回試行した際、396 回で資金が失われました。
  • 単一コアでの検証:
    taskset
    を使って単一コアに固定すると、資金損失は発生しませんでした(スレッド切り替えが稀ため)。
  • Rewind の役割: 意図的にスケジュールを乱すことで、1 回でもデポジットの途中で干渉するケースを確実に浮き彫りにします。

再スケジュールによる問題特定

Rewind VM は単一 CPU しか持たないため最初の実行は成功しますが、

rewind check
コマンドが異なるスケジュールで再度実行し、失敗を特定のステップに絞り込みます。

$ rewind check --where github:fzakaria/rewindvm#bank
...
step 3237 decides it: a reschedule there makes the run fail

passing: run 12feb5f832205a72, schedule 0
failing: run c2f1cfac0c288f3e, schedule 1 over steps 3237..3238
the two are the same run until step 3237

このチェックは私のノート PC でわずか 11 秒で完了しました。ステップ 3237 まで完全同一であり、その時点で失敗例だけが再スケジュールの影響を受けます。


【無料機能】入力情報による完全な再現

rewind nix
は Derivation の入力を解決し、読み取り専用の EROFS イメージにパックして VM を起動します。

  • 実行 ID: 入力からのハッシュで生成(Store パスの生成方法と同様)。
  • 復元コマンド:
    rewind show
    でその入力を再現するコマンドを取得できます。
$ rewind show 12feb5f8
rewind nix /nix/store/cr8rl40rjb9cmmcd9sxn9mpdrhvp53jj-bank-0.1.0.drv --epoch 1791331200 --clock branches --name bank-0.1.0
  • 検証: VM 内のビルドがホスト上のビルドと同一であることを、
    .narinfo
    とバイナリキャッシュの比較で確認できます。

【無料機能】すべてのシンボルとソースコード

  • ソース表示: アプリパネルまたは
    rewind where
    コマンドで、プレイヘッド(カーソル)位置のソースコードとスタックフレームを表示。
  • Nix の恩恵:
    nixpkgs
    が
    separateDebugInfo
    でビルドされており、デバッグ情報はキャッシュされているため、**あらゆるバイナリ(Linux カーネル含む)**のソースとシンボル情報を無料で取得可能。
$ rewind where c2f1cfac 3250
process 139 (bank), thread 141, at step 3250
#4 deposit (bank.c:24)
      22  	int n = snprintf(line, sizeof line, "teller %d: %ld + %ld\n", teller, seen, amount);
      23
>     24  	if (write(1, line, n) != n)
      25  		return;
      26  	balance = seen + amount;
called from #5 teller (bank.c:34)
called from #6 start_thread (pthread_create.c:454)

GDB をステップ単位でフォークして利用する

ソースコードだけでは不十分な場合、Rewind GDB でプレイヘッドをフォークし、GDB を起動できます。

  • 機能: ブレークポイント・ウォッチポイントの設定、メモリー・レジスタ・変数の検査が可能。
  • 利点: GDB の操作は記録に影響せず、同じステップに戻って再度フォークするか、他のステップでフォークしても同じ状態が再現できます。
$ rewind gdb <run-id>
# 例:balance 変数を監視し、変更されるまで続行
step 3249 (teller 2 が CPU を得る直前) -> watch balance

より詳細なシステムコール追跡が必要な場合は、

strace
パッケージをパックしたシェルも起動可能です。


二つの実行を瞬時に比較する

「Compare」タブまたは

rewind compare
コマンドを使用すると、両方の実行の共有イベントと最初の違いが即座に表示されます。

  • 比較表示: 分岐直前のイベントを並列表示し、差異部分をマーク。
  • 例: 失敗実行(teller 2 は 150 から開始)vs 成功実行(200 から開始)。

CPU を保持したのは誰か?:ギャップ埋め機能

レース条件は「どのスレッドがいつ実行されたか」の順序問題です。 通常のトレースは「スレッドが何をしたか」しか記録せず、「隙間(CPU が誰に持たれたか)」は省略されます。

Rewind VM は新しい記録を追加せずに、これらのギャップを埋められます。

  • 原理: 各実行を完全リプレイし、任意のステップで「ゲストカーネルに確認」することで、その時点の CPU ホルダーを特定。
  • 検出例: ステップ 3238 で teller 1 が中断され、teller 2(スレッド 141)が単一ステップで CPU を得て長い間読み込みを行うことで問題が発覚。

ここからチェック(Check from here)

「ある特定の失敗が偶然か、再現性のあるバグか?」を検証します。

rewind check --run
フラグを使用すると、任意のステップからの分岐で、異なるスレッド順序を数多く試すことが可能です。

$ rewind check --run 12feb5f8 --schedule-from 3221 --schedules 16 --all --no-narrow
...
schedule   0: exited:0       4528 steps  dbf0df3de84b  run 12feb5f832205a72 # 成功
schedule   1: exited:2       3313 steps    run f6eb462913dce489 # 失敗
...
schedule  16: exited:2       3314 steps    run 63f7817972a90273 # 失敗

16 of 16 perturbed schedules ended differently

この結果により、すべてのスケジュールが異なる結果に終わり、「運が良い」場合ではなく確実なバグであることが証明されます。 Rewind アプリのコンテキストメニュー「Check from here」でも同様の操作が可能です。


ブックマーク機能

プレイヘッドのステップに注釈(

b
コマンド)を付与し、ブックマークできます。

  • 永続性: 実行とともに保存され、
    .rwd
    エクスポートファイルに含まれるため、他人に共有した際にも注釈が再現可能。

さらに試せるサンプルケース

各例は

flake
内の derivation であり、「バグ」と「修正」の両方を検証できます。

  • philosophers: デッドロック問題。
  • bank: 上記の更新損失問題。
  • waiter: フラグチェックと
    pause
    の間に
    SIGCHLD
    が到着し、親プロセスがスリープを続行してタイムアウトで殺害されるケース。
    $ rewind check github:fzakaria/rewindvm#waiter
    
  • config-reload: 1 つのプロセスが config ファイルを書き換えつつ、別のプロセスで再読み込みを行う例。複数コアではほぼ常に失敗するが、単一 CPU では特定のスケジュールのみで失敗(reader が truncate と最後の write の間に位置するため)。

Nix は超能力です

デバッガーにおける多くの困難な作業は、Nix によって既に解決されています。 Rewind はこれに加えて「意図的な乱す」機能を提供するだけで、以下のようなインフラストラクチャを無料で提供しています:

  1. 完全な入力情報: ソースコード・コンパイラ・ライブラリ・環境構成。
  2. シンボル情報: カーネルを含むすべてのバイナリのデバッグ情報。
  3. 再現性: 他者が自分のマシンで環境を完全に再現するための導出。

つまり、Nix Derivation のように閉鎖されたものから始めれば、完全なデバッガー環境は「無料」で得られます。

$ nix run github:fzakaria/rewindvm -- check github:fzakaria/rewindvm#bank

同じ日のほかのニュース

一覧に戻る →

2026/10/11 7:50

独自の意思決定モデルを構築する

## Japanese Translation: 本研究の核心となる洞察は、言語モデルは単一パスの意思決定システムを模倣することは可能であるが、特定のカリブレーションが行われる限りでは、しばしば危険な過剰な自信を示すという点にある。標準的なモデルが複数のパスを通じて順次テキストを生成するのに対し、システムワンアプローチは制約付きデコーディング(例えば、選択肢 A〜E の語彙をマスキングする)を用いて、AI に固定されたオプションを 1 パスで選択させる。この手法は推論速度を向上させるが、信頼スコアの膨張というリスクをもたらす;具体的には、ネイティブ出力トークンの確率は次のトークンに対する自信を反映しており、正しい答えの真なる確率を反映していない。CommonsenseQA の保持サンプルでの評価では、ファインチューニングの後であっても未カリーブレーテッドなモデルは、明確な単一の答えが存在しない困難な Commonsense 問題に対して高い不確かさ(例:99.78%)を割り当てることができ、マクロ F1 精度は約 58%に留まり、高自信ビンに至っては単なる 70%に過ぎなかった。本研究では、LLM 模倣(Qwen/Qwen3-1.7B)における温度スケイリングを用いてこの問題を成功裏に解決し、モデルの報告された自信を実際の性能と数学的に整合させ、結果として適合温度が約 3.8 となった。したがって、制約付きデコーディングは標準化テストのような多選択タスクに対して効率的を提供するものの、その後のカリブレーションなしで展開することは、過剰な自信による誤りを招き、ユーザーを欺くことになる。今後、事前に定義された答えへの厳格な遵守が求められる適用においては、信頼性指標が真に信頼性を反映するように、事後処理ステップ(例えば温度スケイリング)の優先を確保する必要がある。

2026/10/07 21:30

2D 車両

## Japanese Translation: 「Motion Lab」は、1996 年に GFA BASIC で書かれた先駆的な物理エンジンが GTA の車体システムを動力源としていたのを記念し、同エンジンの 30 周年を祝うためのモダンな Web ベースの再現作品です。当時の一般的なシンプルな「ポインタ・フィジックス」と異なり、この JavaScript インプリメンテーションは、リアルなトルクおよび力の相互作用を含む高度な古典的な 2 次元剛体動力学を正確にシミュレートします。本プロジェクトは、教育的目的のためにレガシースタイルを維持しつつ、オリジナルのソフトウェアが後に摩擦に関する推測に基づいた近似的かつ技術的に不正確な車体シミュレーション層を追加したことを認める一方で、「リマスター」された、より美しいバージョンの元のワイヤフレーム美学を提供しています。ユーザーは「Car(カー)」「Spaceship(スペースシップ/通称:Ship)」「Brick(ブリック)」という 3 つの異なるモードを体験でき、これらのモードは歴史的に「Brick モデル」から始まり、「Ship 要素」を含むよう進化し、最終的に「Car 要素」を取り入れた経緯を持っています。体験には、重力やバリアーの有効/無効化に加え、キーボードまたはタッチ入力により制御される GTA スタイルのカメラズームが含まれています。重要なのは、この非公式なプロジェクトが Rockstar Games および Take-Two から独立しており、オフィシャル製品ではなくトリビュートであることです。2026 年の発表を予定している本再現作品は、ユーザーが外部プラグインに依存せず、数十年にわたる技術開発を直接体験することを呼びかけています。

2026/10/11 5:31

あなたは存在したくても、街自体がそれを好まない街建設ゲーム

## Japanese Translation: サンフランシスコ当局は、特定の住宅シミュレーターに関する自由裁量審査を正式に開始し、都市の規制環境におけるその影響を検討するための重要な手続き的段階を示しています。この措置は、政府機関が該ツールを積極的に調査していることを示しており、同時に具体的な欠陥や直ちに懸念すべき事項がまだ特定されていないことも指摘しています。当面の次の段階では、審査プロセスを継続してシミュレーターの法的地位および運用可能性を決定することとなり、これが将来的にサンフランシスコにおける同様の住宅シミュレーターの開発と規制方法に影響を与える可能性があります。