生のアドレスを使用可能なSwiftクラスにキャストできるLLDBコマンドはありますか?
例えば:
(lldb) po 0x7df67c50 as MKPinAnnotationView
このアドレスがMKPinAnnotationViewを指していることは知っていますが、選択できるのはフレーム内ではありません。しかし、プロパティを確認できるように、生のアドレスをMKPinAnnotationViewにキャストしたいと思います。これは可能ですか?
生のアドレスを使用可能なSwiftクラスにキャストできるLLDBコマンドはありますか?
例えば:
(lldb) po 0x7df67c50 as MKPinAnnotationView
このアドレスがMKPinAnnotationViewを指していることは知っていますが、選択できるのはフレーム内ではありません。しかし、プロパティを確認できるように、生のアドレスをMKPinAnnotationViewにキャストしたいと思います。これは可能ですか?
回答:
Xcode 8.2.1およびSwift 3では、lldbコマンドpoまたはpは型付き変数では機能しません。型指定されたオブジェクトインスタンスのプロパティを調べるには、swiftコマンドのprintを使用する必要があります。(cbownsの回答に感謝!)例:
expr -l Swift -- import UIKit
expr -l Swift -- let $pin = unsafeBitCast(0x7df67c50, to: MKPinAnnotationView.self)
expr -l Swift -- print($pin.alpha)
(lldb)
コンソールにを入力する必要はないと思いました。しかし、それなしではうまくいきませんでした。
expr -l Swift --
...
SwiftのunsafeBitCast
関数を使用して、アドレスをオブジェクトインスタンスにキャストできます。
(lldb) e let $pin = unsafeBitCast(0x7df67c50, MKPinAnnotationView.self)
(lldb) po $pin
その後$pin
、通常どおりに操作できます–プロパティへのアクセス、メソッドの呼び出しなど。
詳しくは、こちらの記事をご覧ください:Swift Memory Dumping。
(lldb) settings set target.language swift
。また、場合によっては(たとえば、アプリから型にキャストしているときにアプリのモジュールの外側でブレークする場合)、次のようにする必要がありますe import MyApp
カスタムクラスの場合、プロジェクトをインポートする必要があります
expr -l Swift -- import MyTestProject
expr -l Swift -- let $vc = unsafeBitCast(0x7fad22c066d0, ViewController.self)
expr -l Swift -- print($vc.view)
Xcode 8 / Swift 3の時点で、私にとってはうまくいきました。(これは@sfaxonの回答に基づいています。)
(lldb) expr -l Swift -- import UIKit
(lldb) expr -l Swift -- let $nav = unsafeBitCast(0x1030ff000, to: UINavigationController.self)
上記のすべての回答のおかげで、unsafeBitCastはXcode 8.3.2 / Swift 3 / macOS / Cocoaアプリケーションでもうまく機能します。
現在のインスタンスのアドレスを記憶する
(lldb) p tabView.controlTint
(NSControlTint) $R10 = defaultControlTint
(lldb) p self
(LearningStoryboard.NSTabViewController) $R11 = 0x00006080000e2280 {
.....
後で、それらを調べます
(lldb) p unsafeBitCast(0x00006080000e2280, to: NSTabViewController.self).tabView.controlTint
(NSControlTint) $R20 = graphiteControlTint
(lldb) p $R11.tabView.controlTint
(NSControlTint) $R21 = graphiteControlTint
このようなことが起こった場合
(lldb) p unsafeBitCast(0x00006080000e2280, to: NSTabViewController.self).tabView.controlTint
error: use of undeclared identifier 'to'
(lldb) p $R11.tabView.controlTint
error: use of undeclared identifier '$R11'
アセンブラーではなく、Swiftソースコードのスタックフレームの1つを選択してください。
これは、アプリケーションが[ 一時停止 ]ボタンをクリックして一時停止したか、例外を伴って停止した場合に発生する可能性があります。それに応じてスタックフレームを選択することで、lldbに適切なプログラミング言語を推測させます。
認めたいことを理解するのにもっと時間がかかった。これは@afinlaysonの回答に似ていますが、より良い説明(私は願っています!)と固定構文
Xcodeのビュー階層デバッガーを使用してオブジェクトのプロパティを確認する場合、これは機能します。デフォルトではobjcコンテキストにいるため、Swiftコンテキストに切り替える必要があります。
expr -l Swift -- import <YOUR PROJECT NAME>
expr -l Swift -- let $vc = unsafeBitCast(0x7fb7c51cb270, to: <YOUR PROJECT NAME>.<YOUR CUSTOM CLASS NAME>.self)
expr -l Swift -- print($vc.<PROPERTY NAME>)
例:
expr -l Swift -- import Football
expr -l Swift -- let $vc = unsafeBitCast(0x7fb7c51cb270, to: Football.Ball.self)
expr -l Swift -- print($vc.velocity)
@Xi Chenの回答は、LLDBセッションがSwiftコンテキストで開始されたときに完全に機能します。ただし、場合によっては、Swiftコンテキスト外のブレークポイントで停止した可能性があります。たとえば、それがObjective-C APIのシンボリックブレークポイントである場合、またはデバッグビュー階層モードの場合(少なくともXcode 11.4以降)。
error: unknown type name 'let'
error: use of undeclared identifier 'unsafeBitCast'
その場合、Objective-Cを使用して古い方法で行う必要があります。
e MKPinAnnotationView *$pin = (MKPinAnnotationView *)0x7df67c50
そして今、あなたはあなたがそうする$pin
ように使うことができます。
po
エイリアスです。つまり、オーバーライドできます。po
objcを使用して16進アドレスを処理することにより、オーバーライドできます。
command regex po
s/(0x[[:xdigit:]]+)/expression -l objc -O -- %1/
s/(.+)/expression -O -- %1/
これがどのような影響を与えるかを確認するには、lldbにこれらのエイリアスを展開するように指示できます。
(lldb) settings set interpreter.expand-regex-aliases true
また、Swiftの代わりとなるhttps://github.com/kastiglione/swift_poを作成しましたpo
。オブジェクトアドレスを処理し、他にもいくつかの改善点があります。
expression -l objc -O -- 0x76543210
私にとっては単なる応答であり、アドレスから変数クラスを知る必要はありません!
最も簡単な方法、Swift 4
expr unsafeBitCast(0x7df67c50, to: MKPinAnnotationView.self)