はじめに
MacOS X Sierraでgdbを使う方法をまとめた。
どうもMacはOSのバージョンごとにgdbを利用可能にする手続きがわりと違うようですごく困る。ほとんどOS XでGDBを使う(ためにコード署名をする)で紹介されている内容でいいんだけど、コメント欄によればYosemiteではsecurity add-trust
が必要だったようだが、僕の環境では不要だった。また、StackOverFlowとかではSierraでgdbがクラッシュするのはRuntime Integrity Protectionが悪さしているからなので無効にしろとか書いてあるが、これも少なくとも僕の環境では不要だった。要するに、 Mavericks、Yosemite、Sierraでそれぞれ微妙にgdbの入れ方が違うっぽい。
で、先にSierraに入れる方法をまとめると、手元の環境(macOS Sierra 10.12.3、gdbは7.12.1)では
- キーチェーンアクセスで証明書を作成
- brewでgdbをインストール
- gdbにcodesignする
- .gdbinitに
set startup-with-shell off
と記述する - taskgated(もしくはシステム全体)を再起動する
でいけた。
コードサインされているか確認
まず、gdbがコード署名されているかどうか確認する。そのためにはcodesign -vv
にgdbのフルパスを渡す。
$ codesign -vv `which gdb`
/usr/local/bin/gdb: code object is not signed at all
In architecture: x86_64
上記のような表示がされていたらコード署名されていない。
証明書の作成。
まず証明書を作成する。
$ open -a "Keychain Access.app"
としてキーチェーンアクセスを起動。メニューの「キーチェーンアクセス」「証明書アシスタント」「証明書を作成」。以下、特に記述がなければデフォルトのままとした。
まず、名前はgdb-certにしておく。証明書のタイプは「コード署名」。デフォルトを無効化。
有効期間。とりあえず10年くらいにしてみる。
証明書の場所はシステム。
作成完了。「キーチェーンアクセス」の「システム」に「gdb-cert」という証明書ができているのでそれをダブルクリックして、「常に信頼」する。
gdbのインストール
brewでgdbをインストールする。
$ brew install gdb
(snip)
On 10.12 (Sierra) or later with SIP, you need to run this:
echo "set startup-with-shell off" >> ~/.gdbinit
すると、「Sierraを使う場合には、.gdbinitにset startup-with-shell off
と書いておけ」と言われるのでそうする。
$ echo "set startup-with-shell off" >> ~/.gdbinit
この状態のままではまだ使えない。実行してみると「コードにサインしろ」と言われる。
$ gdb ./a.out
(snip)
Unable to find Mach task port for process-id 947: (os/kern) failure (0x5).
(please check gdb is codesigned - see taskgated(8))
gdbにcodesign
gdbにcodesignする1。
$ sudo codesign -s gdb-cert /usr/local/bin/gdb
無事にコード署名されたかどうかは、codesign -vv
で調べることができる。
$ codesign -vv `which gdb`
/usr/local/bin/gdb: valid on disk
/usr/local/bin/gdb: satisfies its Designated Requirement
上記のような表示がされたらコード署名されている。
taskgatedを再起動する。psでプロセス番号を調べてkillすると、勝手に再起動する。
$ ps aux | grep taskgated
$ sudo kill XXX
もしくは単にシステムを再起動しても良い。
以上でgdbが使えるようになったはず。
$ gdb ./a.out
$ (gdb) r
Starting program: /Users/hogehoge/a.out
[New Thread 0x1403 of process 1042]
warning: unhandled dyld version (15)
[Inferior 1 (process 1042) exited normally]
まとめ
しばらくlldb使ってたんだけど、我慢できなくなってgdbにした。細かいところでいろいろ違うのと、lldbのguiモードに慣れなかったんだよね。gdb --tuiがわりと好きなので。とりあえずこれでgdbが使えるようになったからいいんだけど、 またOSのバージョンが変わったら方法が変わりそうで嫌だなぁ。
参考
-
なお、既にcodesign済みで、しかもその元の証明書を消しちゃったとかそういう場合、コードにつけたサインを消す手段もあるようだが、素直に
brew uninstall gdb; brew install gdb
するのが早かった。 ↩