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


92

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

例えば:

(lldb) po 0x7df67c50 as MKPinAnnotationView

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

回答:


151

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)

37
これはそれほど難しいことではありません
Departamento B

これは少し直観に反するものでした。(lldb)コンソールにを入力する必要はないと思いました。しかし、それなしではうまくいきませんでした。
ハニー

2
これをobjective-cで行う方法はありますか?
p0lAris 2018年

私はこれに戻り続けます。私はおそらくのためlldbエイリアスを作成する必要がありますexpr -l Swift -- ...
公園。

49

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

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

その後$pin、通常どおりに操作できます–プロパティへのアクセス、メソッドの呼び出しなど。

詳しくは、こちらの記事をご覧ください:Swift Memory Dumping


最初のステートメントでは、「expr」または「式」を忘れたと思います。そうでなければそれは素晴らしい働きをしています!
jarrodparkes

2
Xcode 7.2で「エラー:宣言されていない識別子の使用 'unsafeBitCast'」が発生します。
devios1 2016年

8
そのエラー(@devios)のほかに、7.3.1に表示される別のエラーがあります: "error:unknown type name 'let'"
carlos_ms

3
コンテキストによっては、最初にを使用してlldbをSwiftモードに切り替える必要がある場合があることに注意してください(lldb) settings set target.language swift。また、場合によっては(たとえば、アプリから型にキャストしているときにアプリのモジュールの外側でブレークする場合)、次のようにする必要がありますe import MyApp
Patrick Pijnappel

25

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

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

14

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

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

1
エラーが発生します。そのようなモジュール「MyProjectName」はありません。これを修正する方法についての考えはありますか?
Alexander Stepanishin

@AlexanderStepanishinスレッド/スタックパスを設定してみてください。例:「MyApp>スレッド1> 12メイン」
Juanmi

12

Xcode 8 / Swift 3の時点で、私にとってはうまくいきました。(これは@sfaxonの回答に基づいています。)

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

10

上記のすべての回答のおかげで、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に適切なプログラミング言語を推測させます。


10

Objective-Cバージョン

po ((MKPinAnnotationView *)0x7df67c50).alpha

1
これは私にとっては完璧に機能しました。私の場合、私はDebug View Hierarchyビューにいて、ビューを右クリックしてから選択しましたPrint description of...。これにより、上記のコードにドロップできるメモリアドレスとタイプが得られました。ビジュアルデバッガーがコンソールをObj-Cフレームに配置することを知ってうれしいです。
Trev14

5

認めたいことを理解するのにもっと時間がかかった。これは@afinlaysonの回答に似ていますが、より良い説明(私は願っています!)と固定構文

Xcodeのビュー階層デバッガーを使用してオブジェクトのプロパティを確認する場合、これは機能します。デフォルトではobjcコンテキストにいるため、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)


5

@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ように使うことができます。


3

poエイリアスです。つまり、オーバーライドできます。poobjcを使用して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私にとっては単なる応答であり、アドレスから変数クラスを知る必要はありません!
tontonCD

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.