procinsh - Linux の中を攻殻機動隊のように眺める

攻殻機動隊は好きですか? 最近、新しいアニメシリーズも展開されています。 何度も映像化されていますが、僕は1995年版のアニメ映画が一番好きです。
数ある攻殻機動隊の魅力の中で、最も気に入っているのはサイバー空間の描写です。 3D 空間に円形の物体がいろいろ浮かんでいる様子にはロマンがあります。 昔から、こうした一つ一つのオブジェクトが、実際のコンピュータ上では何に対応するんだろう、と考えていました。

出典:士郎正宗『攻殻機動隊2 MANMACHINE INTERFACE』講談社、2001年6月28日初版発行より引用。
普段、自分は tmux + zsh + vim で生活していて、システム全体の様子を見るときは dmesg、htop、dstat などを使っています。 一方で、以前から攻殻機動隊のようなインターフェイスでコンピュータを触りたいとも考えていました。 そこで今回は、そのようなインターフェイスを実装しました。
現実的な実装方針
攻殻機動隊のようなインターフェイスといっても、自分は電脳化していない生身の人間です。 また、せっかく作るのであれば、実際に使えるインターフェイスでもあってほしいと考えました。 そのため、攻殻機動隊に出てくるものをそのまま再現するのではなく、以下の二つを実装方針としました。
一つ目は、攻殻機動隊のようなサイバーパンクなユーザーインターフェイスであることです。 具体的には、3D で表示し、コンピュータ上の活動に応じてリアルタイムに光ることを目指しました。 また、3D 空間内を自由に動き回れることも重視しました。
二つ目は、実際のコンピュータ上での挙動を反映した、意味のある情報を表示することです。 単なるかっこいい 3D グラフィックではなく、仕事の道具として使えるものを目指しました。 仕事では Linux を主に使っているので、Linux をきれいに可視化しつつ、既存のコマンドラインツールでは得にくい大域的な情報を俯瞰できるようにしました。
procinsh
こうして実際に作ったのが procinsh です。 procinsh demo にデモ動画があります。 『攻殻機動隊』の英語タイトル “Ghost in the Shell” の Ghost を Process に置き換え、”Process in the Shell” を縮めて procinsh としました。

procinsh は Linux 上で動作し、そのホスト上のプロセスをすべて監視します。 プロセスは直方体として描画され、アクティブなプロセスでは底面が発光します。 プロセス間を結ぶ線は Unix domain socket などに対応しており、データが送受信されると白い球体が移動します。

各直方体の z 軸方向は、そのプロセスのアドレス空間に対応しています。 直方体の内部に表示される領域は、実際のプロセスの仮想アドレス空間にマッピングされている領域に対応しており、マウスホバーするとその名前が表示されます。 例えば、共有ライブラリがアドレス空間のどこにロードされているのかを視覚的に確認できます。
また、プロセスがファイルを読み書きしている場合は、対応するファイルが下側に表示されます。 ソケットを通じて外部と通信している場合は、上側に IP アドレスが表示されます。 いずれの場合も、実際にデータが流れているときには白い球体が表示されます。
上の画面で “Open process details” リンクをクリックすると、各プロセスの詳細画面に移動します。 この画面では CPU やメモリ使用量だけでなく、シグナルの状態などを表示しています。 また、レジスタの値や現在のコールスタック、実行位置付近のディスアセンブルも確認できます。 これらは業務でも確認したいことがあるため、表示するようにしました。 レジスタやコールスタック、ディスアセンブルに使う命令列は、対象プロセスの全スレッドを一時停止してスナップショットとして取得します。 取得後は全スレッドを再開します。スナップショットは手動で取得でき、自動取得を有効にすると 1 秒ごとに繰り返します。

タスクマネージャーのように、プロセスを一覧するための画面もあります。 3D 表示はシステム全体を俯瞰するのに向いていますが、特定のプロセスを探したい場合には一覧表示の方が便利です。

使い方
cargo でインストールできます。
ただし、eBPF を利用している都合で cargo install の前にいくつかのパッケージをインストールする必要があります。
Ubuntu 26.04 の場合は、以下のコマンドでインストールできます。
それ以外のディストリビューションを使っている場合は、適宜読み替えてください。
また、eBPF や ptrace など、強い権限を必要とする機能を利用しているため、root 権限で起動する必要があります。
起動後に http://127.0.0.1:9090/ にアクセスするとプロセス一覧の画面に、http://127.0.0.1:9090/space にアクセスすると 3D 表示の画面が表示されます。
sudo apt-get install --yes --no-install-recommends \
build-essential clang llvm pkg-config libelf-dev zlib1g-dev python3 \
linux-tools-common linux-tools-generic
cargo install procinsh --locked
sudo "$HOME/.cargo/bin/procinsh" --listen 127.0.0.1:9090
仕組み
procinsh は TypeScript で書かれた Web フロントエンドと Rust で書かれたバックエンドサーバから構成されています。
フロントエンドは Three.js を使って、バックエンドサーバから送られてきた情報を可視化しています。
今回はフロントエンド側については解説しません。
バックエンドサーバは 3 種類の方法で Linux 上で動くプロセスの情報を収集し、フロントエンドに送信しています。
procfs
各プロセスの基本的な情報は、Linux の /proc ファイルシステム(procfs)から取得しています。
例えば、
- プロセスの基本情報
- 開いているファイルディスクリプタ
- 環境変数
- シグナルの状態
- メモリマップ
などです。
ptrace / process_vm_readv
レジスタの値は ptrace を使って取得しています。
また、プロセスのメモリ内容を読む場合には process_vm_readv を利用しています。
これらを使うことで、特定のプロセスについてより低レベルな情報を取得できます。
eBPF
一方で、特定のプロセスをあらかじめ指定せず、システム全体で発生するイベントとして収集している情報もあります。
例えば、
- CPU 上で実行されているプロセス
- ソケットなどを通じた通信
- ファイル I/O
です。 これらは eBPF を使って収集し、バックエンドからフロントエンドに送信しています。
procfs や ptrace から取得する「現在の状態」と、eBPF で取得する「今起きたイベント」を組み合わせることで、Linux の中で起きていることをリアルタイムに 3D 空間へ反映しています。
おわりに
攻殻機動隊っぽく Linux の中を眺められる procinsh を作りました。 Linux の中を眺めて楽しい電脳ライフを送りましょう。 あと GitHub にスターください。 励みになります。