potatotips #1 で LT した内容が好評(?)だったのでもう少し紹介してみようかなと思います。
発表した内容は「Debugger の Tips」です。
当日のまとめは「クックパッドのLT会に参加してきたのでiOSのtipsをまとめる」がおすすめです。
さてさて LLDB がデフォルトの Debugger となり久しいですね。
しかし Xcode から LLDB を扱う情報をあまりみかけません。かなしいですね。
というわけで今回は LLDB にフォーカスをあてて少し紹介してみようと思います。
(決して GDB もあわせて書くのが面倒くさかったというわけではありませんw)
設定ファイル
shell での .~rc ファイルみたいなものですね。
Xcode から起動した LLDB だと以下の2つのファイルのどちらかが読み込まれます。
- ~/.lldbinit-Xcode
- ~/.lldbinit
注意しないといけないのは ~/.lldbinit-Xcode
があると ~/.lldbinit
が読み込まれません。
CLI から起動すると ~/.lldbinit
のみが読み込まれます。
ということで以下のようにしておく事で奇麗に分けられます。
# ここに Xcode の console で使用する特有の設定を記述
# command regex ps 's/^[[:space:]]*$/po [NSThread callStackSymbols]/' 等々
command source ~/.lldbinit
# ここに共通の設定を記述
# breakpoint や jump の alias 等々
# prompt の表示や format を変更したりもできます。
できること
さてここからが本題ですね。
alias に関しては前の LT でふれているのでそれ以外のことを挙げてみます。
- Python を実行
- 独自コマンドの定義
- Inspector のカスタマイズ
1. Python を実行
(lldb) script import os
(lldb) script print os.getcwd()
/
2. 独自コマンドの定義
LLDB で独自コマンドを定義することができます。
Python で書けるので汎用性は高いと思います。
例えば動的に生成した UIImage をファイルに出力するコマンドとかは便利そうですね。
試しに lssim
というコマンドを作ってみました。
Simulator の直下の起動している Application のディレクトリを ls
するコマンドです。
#!/user/bin/python
import lldb
import commands
import os
def ls_simulator_cmd(debugger, command, result, dict):
app_dir = commands.getoutput('find "%s/Library/Application Support/iPhone Simulator" -type d -name *.app -print0 | xargs -0 ls -td | head -1' % os.environ.get('HOME'))
shell_cmd = '/bin/ls -alF "%s/%s"' % (app_dir, command)
shell_result = commands.getoutput(shell_cmd)
result.PutCString(shell_result)
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand("command script add -f ls_simulator.ls_simulator_cmd lssim")
print "lssim installed."
(lldb) command script import ~/.lldb/ls_simulator.py
(lldb) lssim
total 240
drwxr-xr-x 9 dealforest 1469690100 306 Dec 6 04:06 ./
drwxr-xr-x@ 6 dealforest 1469690100 204 Dec 6 04:06 ../
-rw-r--r-- 1 dealforest 1469690100 75320 Dec 6 04:06 Assets.car
drwxr-xr-x 3 dealforest 1469690100 102 Dec 6 04:06 Base.lproj/
-rw-r--r-- 1 dealforest 1469690100 1006 Dec 6 04:06 Info.plist
-rw-r--r-- 1 dealforest 1469690100 14929 Dec 6 04:06 LaunchImage-700-568h@2x.png
-rw-r--r-- 1 dealforest 1469690100 8 Dec 6 04:06 PkgInfo
drwxr-xr-x 3 dealforest 1469690100 102 Dec 6 04:06 en.lproj/
-rwxr-xr-x 1 dealforest 1469690100 17280 Dec 6 04:06 hoge*
起動した際に import しておきたい場合は ~/.lldbinit-Xcode
に command script import ~/.lldb/ls_simulator.py
をかいておけばいいです。
3. Inspector のカスタマイズ
「Advanced Issues: Creating custom LLDB object summaries」が分かりやすいです。
Beer のインスタンスが複数入った NSArray を Inspetor で確認すると、Beer のインスタンスの summary
にはのアドレスが表示されているのですが、そこに自分がみたい情報を定義して視認性をあげれるので便利ですね。
できないこと
- Application の起動時に環境変数の設定
- ホームディレクトリ以外の設定ファイルの読み込み
1. Application の起動時に環境変数の設定
設定ファイルから LLDB の環境変数を設定することはできます。
env NSZombieEnabled=YES
(lldb)settings show target.env-vars
target.env-vars (dictionary of strings) =
NSZombieEnabled=YES
あくまで LLDB の環境変数の設定のみなので、アプリの起動時に環境変数を設定することはできないので上記のように NSZombieEnabled=YES
と定義しても期待する挙動にはならないので Xcode の GUI 上で設定しましょう。
2. ホームディレクトリ以外の設定ファイルの読み込み
個人で設定して営む分には便利に使えてますけど、チーム開発で使う場合には個別に設定しないといけないのでとても不便です。
とはいえ Inspector のカスタマイズ
はプロジェクトに固有したりするので、プロジェクト毎に管理できればいいなと思うものの、どうすればいいのかまだよくわかっていません。
できそうなんですけどね。この辺りはおいおい調べておきます。
総括
作業効率は確実にあがるので、騙されたと思って設定してみてはいかがでしょうか。
他にもこういうのあるよ!もしくはつっこみ等あればよろしくです。
ではでは。
おまけ
僕が使っている設定を晒してみます
command regex pv 's/^[[:space:]]*$/po [[[UIApplication sharedApplication] keyWindow] recursiveDescription]/' 's/^(.+)$/po [%1 recursiveDescription]/'
command regex pe 's/^[[:space:]]*$/po [[NSProcessInfo processInfo] environment]/'
command regex ps 's/^[[:space:]]*$/po [NSThread callStackSymbols]/'
command regex pd 's/^(.+)$/po [[NSString alloc] initWithData:%1 encoding:4]/'
command script import ~/.lldb/ls_simulator.py
command source ~/.lldbinit
script import os, sys
command alias sp script print
# breakpoint shortcuts
# break on function/method/selector: b -n name
# break on C/C++ method: b -M method
# break on selector: b -S selector:here:
# break on address: b -a 0xfeedface
command alias b breakpoint set
command alias bd breakpoint disable
command alias be breakpoint enable
command alias bdel breakpoint delete
command alias bcommand breakpoint command add
command alias commands breakpoint command list
# jump aliases
# jump 0xfeedface
command alias jump register write pc
command alias jmp register write pc
command alias j register write pc