2015年11月18日水曜日

Mac OS X El Capitan で gdb を使う Setting up gdb on Mac OS X El Capitan

OS のアップデート後に動作しなくなった GNU gdb (mac ports) を再び使えるようにする.
コード署名,/System ディレクトリの plist ファイルの書き換えなど,個別の作業はていねいに解説されたウェブページがあるので,キーワードで検索し参考にする. Stack Overflow に taskgated.plist の編集のため SIP 機能を解除する手順について言及する投稿がでた.

症状:
Yosemite で使っていたバイナリーのままで ggdb コマンドを実行すると,起動するが,run コマンドは taskgated, codesign についてのエラーを出して機能しない.
Unable to find Mach task port for process-id 673: (os/kern) failure (0x5).
(please check gdb is codesigned - see taskgated(8))

環境,目標:
Mac OS X 10.11.1
X code 7.1.1, Command Line Tools (Mac OS X 10.11) for Xcode 7.1
Apple LLVM (/usr/bin/gcc) 7.0.0
GNU gdb (/opt/local/bin/ggdb) 7.7.1

1. (念のため)mac ports のバイナリを,10.11 (El Capitan) 対応のものにアップグレードする.
Update gdb binary for Mac OS X 10.11.

(0) (OS のアップグレードでなくなった) x-code のコマンドラインツールをインストールする.先に Xcode は 7.1.x にアップデートしておく.
(1) https://www.macports.org/install.php からダウンロードして mac ports をインストール.
(2) port selfupdate, port upgrade outdated を実行(sudo).

2. gdb のコマンドバイナリにコード署名する.
Code sign gdb binary.

GNAT User's Guide, gcc.gnu.org
(1) 証明書を作成する.open -a "Keychain Access.app"
(2) コード署名する.sudo codesign -f -s gdb-cert /opt/local/bin/gdb
(3) taskgated の起動オプションが変更済みの場合,taskgated を再起動する.OS を再起動するか,launchctl load /System/Library/LaunchDaemons/com.apple.taskgated.plist を実行.

3. OS の taskgated の起動オプションに -p オプションを追加する.
Temporarily disable SCR function on file systems and add -p command line option to the taskgated start-up script.

/System/Library/LaunchDaemons/com.apple.taskgated.plist ファイルの起動オプション -s が書かれた行 (array タグ) を探し, -sp に変更する.
ただし 10.11 では /System が書き換え不可となっている(System Integrity Protection (rootless) 機能)ため,一時的にファイルシステムを書き換え可能にし,編集したのち,元に戻す.
(1) リカバリーモードで起動する.再起動し,アップルマークが表示されるまで command+R を入力する.
(2) ユーティリティーメニューでターミナル Terminal をを選び,csrutil disable コマンドを実行,通常モードで再起動.
(3) 起動パラメータファイルを編集する./usr/bin/emacs, /usr/bin/nano 等をが使える.
(4) リカバリーモードで起動する.csrutil enable コマンドを実行して元にもどし,通常モードで再起動する.

4. ggdb の root 実行権限をもつグループ(mac ports では procmod)に使用するユーザーを追加する.
Add the user to "procmod" group.

(1) 確認する.dscl . read /Groups/procmod
の GroupMembership の値を確認.
(2) ない場合,グループにユーザー ID を追加する.
sudo dscl . append /Groups/procmod GroupMembership %username%