---
title: Go でデバッガを自作する
tags:  #golang  
author: [HireRoo](https://www.docswell.com/user/hireroo)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/2JV3QRZPEQ.jpg?width=480
description: デバッガの仕組みや、Go でどのように実装するのかを簡単に説明します。
published: September 26, 24
canonical: https://www.docswell.com/s/hireroo/KMX7WL-go-debugger-lt
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/2JV3QRZPEQ.jpg)

Go でデバッガを自作する
okarin
1


# Page. 2

![Page Image](https://bcdn.docswell.com/page/5EG3WM4Q7L.jpg)

Go でデバッガを自作する
自己紹介
okarin (Kyota Okabe)
所属
● 株式会社ハイヤールー
エンジニアリング領域
● バックエンド
● 認証・認可
● （少しだけ）機械学習
Activities
● community: Ehime.go
● X: @okarin_dev
好きなもの
● ブロッコリー
● ランニング
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/4JQ53RGW7P.jpg)

Go でデバッガを自作する
今回話すこと
●
プログラムを追跡可能にする仕組み
●
ブレークポイントの仕組み
●
Go で実装するには？
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/K7491851E1.jpg)

Go でデバッガを自作する
プログラムを追跡可能にする仕組み
ptrace によって子プロセスを追跡できる （※ Linux の場合）
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/LJ1KG2W57G.jpg)

Go でデバッガを自作する
ブレークポイントの仕組み
命令の書き換え（※ x86-64 アーキテクチャの場合）
0x ** ** ** **
0x ** ** ** **
0x 48 83 ec 78 48 c7 44 24
0x cc 83 ec 78 48 c7 44 24
0x ** ** ** **
0x ** ** ** **
命令の先頭１バイトを 0xcc (INT3) に書き換えると、
その命令に達したタイミングで子プロセスは停止、それを親プロセスが検知できる
ブレークポイント
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/GJWDKR6W72.jpg)

Go でデバッガを自作する
Go で実装するには？
使いやすいパッケージが
すでに用意されている！
●
●
●
sys/unix
debug/dwarf
debug/elf
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/4EZGZRY2J3.jpg)

Go でデバッガを自作する
コードの一例
breakpoint を設定するコード
●
（準）標準パッケージのおかげで書きやすい！
func (bp *Breakpoint) Enable() error {
_, err := sys.PtracePeekData(bp.pid, bp.addr, bp.originalInstruction)
if err != nil {
return err
}
data := binary.LittleEndian.Uint64(bp.originalInstruction)
// data &amp; ^0xff =&gt; data &amp; 11111111 … 11111111 00000000
newData := (data &amp; ^uint64(0xff)) | Int3Instruction
newInstruction := make([]byte, 8)
binary.LittleEndian.PutUint64(newInstruction, newData)
_, err = sys.PtracePokeData(bp.pid, bp.addr, newInstruction)
if err != nil {
return err
}
}
bp.isEnabled = true
return nil
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/Y76YZRR6EV.jpg)

Go でデバッガを自作する
まとめ
●
ptrace でプログラムを追跡する
●
ブレークポイントは 0xcc (INT3) で設定
●
Go は便利な（準）標準パッケージがあるのでデバッガを作りやすい
参考資料
●
●
Writing a Linux Debugger
ptrace(2) - Linux manual page
8


