macOS 標準のデバッガーは、
LLVM 由来の lldb というものだそうだ
(標準のコンパイラーが LLVM になったのだから当然だろう)。
GCC を使うので、gdb を使おう、と考えた。
調べて何とか使えるように出来たが、
「コード署名」などが必要になったり、結構面倒であった。
今後も複数の Mac にインストールすることになるだろうし、
記録を残して置く。
(以下の記録はあらく、ミスが多いと思われるが、順次訂正していくつもり。)
対象とする Mac の OS は macOS 10.13 (High Sierra) である
(自分が使っている Mac では大体このバージョンに統一できたので)。
まず MacPorts で gdb をインストールする。
(現在 gdb は version 8.1 が最新であるが、8.0 がインストールされる。
実は 8.1 では動かないそうである。)
インストールが終了すると、次のようなメッセージが出る。
You will need to codesign /opt/local/bin/ggdb
See
https://sourceware.org/gdb/wiki/BuildingOnDarwin#Giving_gdb_permission_to_control_other_processes
for more information.
|
割りと詳しい。はまったとき一読すべきかも。
ここからコード署名というのをする。証明書を作る作業が結構長い。
- (1)
- キーチェーンアクセスを起動する。
open -a "Keychain Access.app"
|
- (2)
-
[キーチェーンアクセス] → [証明書アシスタント] → [証明書を作成]
として[証明書アシスタント]というウィンドウを出す。
- (3)
- 「以下の証明書情報を入力してください:」に対して、
名前は “gdb-cert” にでもして、
(固有名のタイプは[自己署名ルート]のまま)
証明書のタイプは [コード署名] を選択し,
[デフォルトを無効化] をチェックする。
[続ける] ボタンを何度か(6回くらい)クリックする。
- (4)
-
[拡張鍵用途選択領域] の「許可される操作」
で [コード署名] にチェックを入れる。[続ける]を(3回)押す。
- (5)
- 「証明書の場所を指定」に対して、
とりあえず証明書の場所は [ログイン] にしておく
([システム] にしてもエラーになってしまう)。
[作成] ボタンを押す。[完了] を押す。
- (6)
-
「キーチェーンアクセス」ウィンドウの分類で、「証明書」を選択する。
[ログイン] キーチェーンに “gdb-cert” という証明書が出来ているはず。
これを [システム] までドラッグ&ドロップする。
キーチェーン・パスワードというのを要求されたりするが、
デフォールトではログイン・パスワードと一致しているので、
ログイン・パスワードを入力すれば多分大丈夫。
- (7)
- gdb-cert 証明書をダブル・クリックして開き、
「信頼」の「この証明書を使用するとき」で「常に信頼」を選択して閉じる。
パスワード入力を要求される。
- (8)
- taskgated を再起動する (どうやる? kill すれば自動的に
再起動されるように書いている人がいるが、
試したところそうならず、結局は Mac を再起動した)。
(2018/9/14 追記 必要になった時点で再起動される、
ということらしく OS の再起動は不要みたいだ。
ps auxw | grep taskgated
sudo kill -9 taskgatedのプロセスID
(プロセスIDというのは、2列目にある整数)
|
実例 |
[katsurada-no-MacBook-Air-3:~/work] mk% ps aux | grep taskgated
root 754 4.4 0.1 4296220 2468 ?? Ss 木03PM 2:53.56 /usr/libexec/taskgated -s
mk 64481 0.0 0.0 4267752 1012 s004 S+ 12:05PM 0:00.00 grep taskgated
[katsurada-no-MacBook-Air-3:~/work] mk% sudo kill -9 754
Password:
[katsurada-no-MacBook-Air-3:~/work] mk%
|
)
- (9)
sudo codesign -fs gdb-cert /opt/local/bin/ggdb
|
確認するには codesign -vd /opt/local/bin/ggdb とすれば良い。
security find-identity -p codesigning -v
~/.gdbinit に set startup-with-shell off
と書き足す。
echo "set startup-with-shell off" >> ~/.gdbinit
|
ggdb という名前にする理由はないと思うので
としておく。emacs の中で実行するときエイリアスは見てくれないので、
エイリアスよりはリンクするのが良いかも。そのためには
pushd /opt/local/bin
sudo ln -s ggdb gdb
popd
|
以上の設定について、色々な資料を参考にしたが、主なものは次の2つ
(大筋は 1 の通りだが、macOS 10.13 ではそのままでは通用しなくなった)。
- 「OS XでGDBを使う(ためにコード署名をする)」
(2013/11/30)
- mac OS 10.13(High Sierra) で gdb を使う
(2018/9/14)
上に書いたようにしてうまく動くMacと、そうでないMacがある。
違いの理由はわからない。
(2018/9/14)
1台だけ残っていた El Capitan の Mac に試しにインストール&設定してみたら
無事に動作した。
(2018/9/17)
動かない Mac があると書いたけれど、remote login すると動かない、だった。
その Mac のキーボードから操作すれば使えた。
remote login した場合も
のように sudo をすれば動いた。
(2018/9/18)
学生の MacBook に上の手順でインストールしてみた。
OS が Sierra だったけれど無事に動作した。
gdb は久しぶりなのでコマンドがうろ覚えだ…
(この5年ほぼ Mac オンリーだったので 5 年のブランク?)
とりあえず。
なかなか充実しているように感じた。
emacs の中で M-x gdb とするのが良いかも
(ずっと以前に試したときよりも改善されている感じ)。
メモ
- コンパイルするとき -g オプションをつける。最適化は控えめに。
- ggdb 実行ファイル名 として起動する。
- run で実行開始。
1文字の r でも良い。以下 run (r) と書くことにする。
引数があるときは、run の後に指定する
(例えば myprog arg1 two 3 → run arg1 two 3)
- quit (q) で終了
- next (n) で1ステップ進める。関数呼び出しのとき、関数の中には入らない。
- step (s) で1ステップ進める。関数呼び出しのとき、関数の中に入る。
- list (l) 10行ほどソースコードを表示する。
一度表示すると “前に進んでしまう。”
- list 行番号
list - とすると前の10行を表示する。
- break (b) 場所の指定 ブレークポイントの設定
場所の指定としては、関数名, 行番号, ファイル名:行番号
例えば break main, break 14, break test1.c:23 とか。
- break (b) 場所の指定 if 条件 条件が成り立つ時だけ止まる
- info breakpoints (i b) でブレークポイントを全て表示する。番号が見える。
- ブレークポイントを削除するには
- delete 番号 指定した番号のブレークポイントを削除する
- delete 全てのブレークポイントを削除する
- clear 関数名
- clear 行番号
- clear ファイル名:行番号
(clear, delete の後の数の解釈が違うのに注意。
delete は表から除くみたいな感じで、指定するのは番号。
clear は行番号。)
- 一時的に無効にしたり有効にもどしたりも出来る。
disable 番号, enable 番号
- (ブレークポイントで止まったとき) continue (c) で続ける
(次のブレークポイントまで走る)。
- watch (w) 変数名 変数を見張って、書き込まれたら止まる。
ポインターを多用する C では必要だな。
- rwatch (w) 変数名 変数を見張って、読み出されたら止まる。
- print (p) 変数名 変数の値を表示する。
print 式 (例えば p 2*i+3 とか)
print *ポインタ変数名 というのもOK.
- display 変数名 変数の値をつねに表示する。
扱い方はブレークポイントと同様
info display (i di) で表示する変数の一覧を表示する。
delete display 番号 (d d 番号) で表示をやめる。
enable|disable display 番号
- set 変数名=値 変数に値を代入する。
名前の衝突があると “Ambiguous set command” と言われる。
set variable 変数名=値 とする。
variable は va でも可。
世の中には print 変数名=値 としている人が多い。
- whatis 変数名 変数の型を表示する
- finish 関数の最後まで実行する
- until ループを抜けるまで実行する
- emacs の中で M-x gdb とするのが (ちょっと試して見たところすごく) 便利。
(Mac に付属の emacs は古いし、
学生にそのために emacs をインストールさせるというのは変かなあ。)
ライブラリィのデバッグをどうするのかな…やってみたら普通に出来た。
桂田 祐史
2020-04-05