web-dev-qa-db-ja.com

LLDB(Swift):生のアドレスを使用可能なタイプにキャスト

生のアドレスを使用可能なSwift=クラスにキャストできるLLDBコマンドはありますか?

例えば:

(lldb) po 0x7df67c50 as MKPinAnnotationView

このアドレスがMKPinAnnotationViewを指していることは知っていますが、選択できるのはフレーム内ではありません。しかし、未処理のアドレスをMKPinAnnotationViewにキャストして、そのプロパティを確認できるようにします。これは可能ですか?

75
jarrodparkes

Xcode 8.2.1およびSwift 3、lldbコマンドpoまたはpは型付き変数では機能しません。=を使用する必要がありますSwift commandprint型付きオブジェクトインスタンスのプロパティを調べる( cbowns's answer !に感謝)例:

(lldb) expr -l Swift -- import UIKit
(lldb) expr -l Swift -- let $pin = unsafeBitCast(0x7df67c50, to: MKPinAnnotationView.self)
(lldb) expr -l Swift -- print($pin.alpha)
112
Xi Chen

SwiftのunsafeBitCast関数を使用して、アドレスをオブジェクトインスタンスにキャストできます。

(lldb) e let $pin = unsafeBitCast(0x7df67c50, MKPinAnnotationView.self)
(lldb) po $pin

その後、$pin通常通り–プロパティへのアクセス、メソッドの呼び出しなど。

詳細については、この記事を参照してください: Swift Memory Dumping

43
gregheo

expressionのlldb形式は、Xcode 7.3で変更されたようです。以下は私を始めました:

(lldb) expr -l Swift -- import UIKit
(lldb) expr -l Swift -- let $view = unsafeBitCast(0x7fb75d8349c0, UIView.self)
25
sfaxon

Xcode 8/Swift 3の時点で、ここでうまくいきました。 (これは、 @ sfaxon's answer に基づいています。)

(lldb) expr -l Swift -- import UIKit
(lldb) expr -l Swift -- let $nav = unsafeBitCast(0x1030ff000, to: UINavigationController.self)
11
cbowns

カスタムクラスの場合、プロジェクトをインポートする必要があります

expr -l Swift -- import MyTestProject
expr -l Swift --  let $vc = unsafeBitCast(0x7fad22c066d0, ViewController.self)
expr -l Swift -- print($vc.view)
11
afinlayson

上記のすべての回答のおかげで、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ソースコードのスタックフレームのいずれかを選択してください。

Pauseボタンをクリックしてアプリケーションを一時停止したか、例外で停止したときに発生する可能性があります。それに応じてスタックフレームを選択することにより、lldbが適切なプログラミング言語を推測します。

9
Tora

Objective-Cバージョン

po ((MKPinAnnotationView *)0x7df67c50).alpha
6
rockhard

@Xi Chenの答えは、LLDBセッションがSwiftコンテキストで開始されたときに完全に機能します。ただし、場合によってはブレークポイントで停止した可能性があります外部 a Swift context;たとえば、Objective-C APIのシンボリックブレークポイントの場合。

error: unknown type name 'let'
error: use of undeclared identifier 'unsafeBitCast'

その場合、Objective-Cを使用して古い方法で行う必要があります。

e MKPinAnnotationView *$pin = (MKPinAnnotationView *)0x7df67c50

これで、$pinを使用できるようになりました。

4
Gobe

poはエイリアスです。つまり、オーバーライドできます。 objcを使用して16進アドレスを処理することにより、poをオーバーライドできます。

command regex po
s/(0x[[:xdigit:]]+)/expression -l objc -O -- %1/
s/(.+)/expression -O -- %1/

これがどのような効果があるかを確認するには、lldbにこれらのエイリアスを展開するように指示します。

(lldb) settings set interpreter.expand-regex-aliases true

また、私は https://github.com/kastiglione/Swift_po を作成しました。これはSwiftの代わりのpoです。オブジェクトのアドレスを処理し、他にもいくつかの改善点があります。

2
Dave Lee

最も簡単な方法、Swift 4

expr unsafeBitCast(0x7df67c50, to: MKPinAnnotationView.self)
2

認めたいと思うまでに時間がかかりました。 @afinlayson answerに似ていますが、より良い説明(私は願っています!)と固定構文

Xcodeのビュー階層デバッガーを使用してオブジェクトのプロパティを確認する場合、これは機能します。デフォルトではオブジェクトコンテキストになっているため、Swiftコンテキストに切り替える必要があります

  1. 最初にプロジェクトをインポートします(そこで定義されたクラスの一部を使用する場合)

_expr -l Swift -- import <YOUR PROJECT NAME>_

  1. メモリアドレスを使用してオブジェクトを任意のクラスにキャストします

expr -l Swift -- let $vc = unsafeBitCast(0x7fb7c51cb270, to: <YOUR PROJECT NAME>.<YOUR CUSTOM CLASS NAME>.self)

  1. オブジェクトから必要な値にアクセスします

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)

1
Bartosz Kunat