Gibt es einen LLDB-Befehl, der eine Rohadresse in eine verwendbare Swift-Klasse umwandeln kann?
Beispielsweise:
(lldb) po 0x7df67c50 as MKPinAnnotationView
Ich weiß, dass diese Adresse auf eine MKPinAnnotationView verweist, aber ich kann sie nicht in einem Frame auswählen. Ich möchte die Rohadresse jedoch in eine MKPinAnnotationView umwandeln, damit ich ihre Eigenschaften untersuchen kann. Ist das möglich?
(lldb)
in meine Konsole eingeben. Aber ohne das hat es nicht funktioniert.expr -l Swift --
..Mit der
unsafeBitCast
Funktion von Swift können Sie eine Adresse in eine Objektinstanz umwandeln:Dann können Sie
$pin
wie gewohnt arbeiten - Zugriffseigenschaften, Aufrufmethoden usw.Weitere Informationen finden Sie in diesem Artikel: Swift Memory Dumping .
quelle
(lldb) settings set target.language swift
. In einigen Fällen (z. B. wenn Sie außerhalb des Moduls Ihrer App brechen, während Sie einen Typ aus Ihrer App übertragen) müssen Sie dem möglicherweise mit eineme import MyApp
Das lldb-Format für
expression
scheint sich in Xcode 7.3 geändert zu haben. Folgendes hat mich dazu gebracht:quelle
Für benutzerdefinierte Klassen müssen Sie Ihr Projekt importieren
quelle
Ab Xcode 8 / Swift 3 hat Folgendes für mich funktioniert. (Dies basiert auf der Antwort von @ sfaxon .)
quelle
Dank all der obigen Antworten funktioniert unsafeBitCast auch gut mit Xcode 8.3.2 / Swift 3 / macOS / Cocoa Application.
Merken Sie sich eine Adresse der aktuellen Instanz
Untersuche sie später
Wenn so etwas passiert
Stellen Sie sicher, dass Sie einen der Stapelrahmen des Swift-Quellcodes anstelle eines Assemblers auswählen.
Dies ist wahrscheinlich der Fall, wenn die Anwendung durch Klicken auf die Schaltfläche Pause angehalten oder mit einer Ausnahme gestoppt wurde. Lassen Sie lldb durch entsprechende Auswahl eines Stapelrahmens auf eine geeignete Programmiersprache schließen.
quelle
Objective-C-Version
quelle
Debug View Hierarchy
Ansicht, habe mit der rechten Maustaste auf eine Ansicht geklickt und dann ausgewähltPrint description of...
. Das gab mir eine Speicheradresse und einen Typ, den ich in den obigen Code einfügen konnte. Gut zu wissen, dass der visuelle Debugger die Konsole in einen Obj-C-Frame versetzt.Ich habe länger gebraucht, um herauszufinden, dass ich zugeben möchte. Es ist ähnlich wie @afinlayson Antwort, aber mit besserer Erklärung (ich hoffe!) Und fester Syntax
Wenn Sie die Eigenschaften eines Objekts mit dem Debugger für die Ansichtshierarchie von Xcode überprüfen möchten, funktioniert dies wie folgt: Sie befinden sich standardmäßig im Objektkontext, sodass Sie ihn in den Swift-Kontext wechseln müssen
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>)
Beispiel:
expr -l Swift -- import Football
expr -l Swift -- let $vc = unsafeBitCast(0x7fb7c51cb270, to: Football.Ball.self)
expr -l Swift -- print($vc.velocity)
quelle
Die Antwort von @Xi Chen funktioniert perfekt, wenn Ihre LLDB-Sitzung in einem Swift-Kontext gestartet wurde. In einigen Fällen haben Sie jedoch möglicherweise an einem Haltepunkt außerhalb eines Swift-Kontexts angehalten . Zum Beispiel, wenn es sich um einen symbolischen Haltepunkt für die Objective-C-API handelt oder wenn Sie sich im Debug View Hierarchy-Modus befinden (mindestens ab Xcode 11.4).
In diesem Fall müssen Sie es mit Objective-C auf die alte Weise tun:
und jetzt können Sie verwenden,
$pin
wie Sie würden.quelle
po
ist ein Alias, was bedeutet, dass er überschrieben werden kann. Sie können überschreiben,po
indem Sie Hex-Adressen mit objc behandeln:Um zu sehen, welchen Effekt dies hat, können Sie lldb anweisen, diese Aliase zu erweitern:
Außerdem habe ich https://github.com/kastiglione/swift_po erstellt , das
po
Swift ersetzt. Es verarbeitet Objektadressen und weist einige weitere Verbesserungen auf.quelle
expression -l objc -O -- 0x76543210
ist nur die Antwort für mich, und es muss nicht die variable Klasse von der Adresse kennen!Der einfachste Weg, schnell 4
quelle