Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

デバッガと和解せよ

 デバッガと和解せよ

2022/08/28 Kernel/VM探検隊online part5 (https://kernelvm.connpass.com/event/256248/) の @nullpo_head (https://twitter.com/nullpo_head) の発表資料です。

ptraceを使って対象コマンドの全子プロセスにattachしてDwarfを見つつデバッグしたいプロセスを探し、最終的には他のデバッガに処理を流すような不思議なデバッガ(?)を作ることで、zero configurationでvscodeでブレークポイントを打ったプロセスのデバッグを始めてくれる dbgee (https://github.com/nullpo-head/dbgee) という便利ツールを作ったときの話をしました。

Takaya Saeki

May 03, 2023
Tweet

More Decks by Takaya Saeki

Other Decks in Technology

Transcript

  1. 3 デバッガーは少し面倒で気軽に使えない アタッチが 面倒 使い方を 忘れる その他 デバッガーを使うのが面倒な理由(発表者脳内調べ) GDBコマンド 忘れた

    - list? s? si? Gdb用のmake run ターゲットがない VSCodeの launch.json 書きたくない デ バ ッ ガ の ア タ ッ チ / 起 動 は 既存の開発フローと親和性が低い デバッガはいつもより一手間必要
  2. `Run`: ターゲットプログラムのパスと引数を指定してデバッグ `Set`: ターゲットプログラムのパスを指定すると、それをデバッガ起動コマンドでラップする • VSCodeのシェル内で叩けばVSCodeのデバッグセッションが始まる (with vscode plugin) •

    普通のターミナルで叩けば、tmux paneでgdb –tuiが起動する 19 Dbgee、まだ使いづらい・・・ ビルド方法によってはビルド後の パ ス を 指 定 す る の が 結 構 面 倒
  3. デバッグ対象をptraceにより起動直後に停止させて、VSCodeやgdbに明け渡す 1. Dbgee `fork()` 2. 親(dbgee) 3. 子を`waitpid()` 6. `SIGTRAP`を受信

    7. `ptrace(PTRACE_CONT, …, SIGSTOP)`で、子からデタッチしつつ子を停止 8. Gdbやそのほかのデバッガを起動し、Attach by PIDで子にアタッチさせる VSCodeなら、dbgeeプラグインとのfifoコネクションにアタッチリクエストを送信 2. 子 4. `ptrace(TRACE_ME, …)` 5. `execve(ターゲットPATH, …)` ここでSIGTRAPが発生 ← ptraceの仕様 22 現Dbgeeの仕組み兼Ptraceのおさらい
  4. 29 処理の流れ Ptraceですべての子孫プロセスにアタッチしつつ、DWARFをパースして目的のプロセスを探す 1. `ptrace(PTRACE_SETOPTIONS, …, PTRACE_O_TRACECLONE)` • すべてのcloneされたプロセスもptrace配下になる •

    ちなみにLinux専用機能になります(macOSでは同様の機能はない 2. 子孫プロセスがexecveするたびにSIGTRAPを受信 3. `/proc/PID/exe`を見て、DWARFがあればパース、ソースコードのリストを得る 4. ソースコードの中に、引数で与えられたソースがある? • If YES • そのプロセスを`ptrace(PTRACE_CONT, …, SIGSTOP)`でデタッチしつつ止める • 真のデバッガにそのプロセスを渡す • 全プロセスからデタッチ
  5. • Dockerへの対応 • Dockerで実行されると、子ではなくデーモンの方で実行されてしまうのでptraceできない • Minikubeやkindでの実行にも対応したい • ので、runcをptraceでラップしたOCIランタイムとして実装して対応したい • Pythonへの対応

    • 今回の新機能はいまのところC/C++/Rust/Goにだけ対応 • こっちは本当にseccomp-bpfいるかも? やる気がないやつ • macOS対応 • Ptraceが実質「無」で、macOSのAPIを学ばないと厳しいので 35 TODO(かつやる気があるやつ)