LLDB (Swift): Ham Adresi Kullanılabilir Türe Dönüştürme


95

Kullanılabilir bir Swift sınıfına ham bir adres atabilen bir LLDB komutu var mı?

Örneğin:

(lldb) po 0x7df67c50 as MKPinAnnotationView

Bu adresin bir MKPinAnnotationView'a işaret ettiğini biliyorum, ancak seçebileceğim bir çerçeve içinde değil. Ancak, özelliklerini inceleyebilmem için ham adresi bir MKPinAnnotationView'a dönüştürmek istiyorum. Mümkün mü?

Yanıtlar:


155

Xcode 8.2.1 ve Swift 3 altında, lldb komutu po veya p , yazılan değişkenle çalışmaz. Sen hızlı komut kullanmanız gerekecektir baskı yazılan nesne örneğinin özelliklerini incelemek. ( Cbowns'ın cevabı sayesinde !) Örneğin:

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

43
Bu gerçekten o kadar zor olmamalı
Departamento B

Bu biraz sezgiseldi. Konsoluma yazmama gerek olmadığını düşündüm (lldb). Ama o olmadan işe yaramadı.
Honey

2
Bunu hedef-c'de yapmanın bir yolu var mı?
p0lAris

Buna geri dönüyorum. Muhtemelen bir lldb takma adı oluşturmalıyım expr -l Swift -- ..
Koen.

49

unsafeBitCastBir nesne örneğine bir adres atamak için Swift'in işlevini kullanabilirsiniz :

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

O zaman birlikte çalışabilirsin $pin her zamanki gibi - erişim özellikleri, çağrı yöntemleri vb.

Daha fazla bilgi için bu makaleye göz atın: Swift Memory Dumping .


İlk ifade için "ifade" yi veya "ifadeyi" unuttuğunuzu düşünüyorum. Aksi takdirde harika çalışıyor!
jarrodparkes

2
Xcode 7.2'de "hata: bildirilmemiş tanımlayıcı 'unsafeBitCast' kullanımı" mesajı alıyorum.
devios1

8
Bu hatanın yanında (@devios) 7.3.1'de gösterilen başka bir hata var: "hata: bilinmeyen tür adı 'let'"
carlos_ms

3
Bağlama bağlı olarak, önce lldb'yi Swift moduna geçirmeniz gerekebileceğini unutmayın (lldb) settings set target.language swift. Ayrıca, bazı durumlarda (örneğin, uygulamanızdan bir türe yayın yaparken uygulamanızın modülünün dışına çıkarken) bunu takip etmeniz gerekebilire import MyApp
Patrick Pijnappel

25

Lldb formatı expressionXcode 7.3'te değişmiş gibi görünüyor. Aşağıdakiler beni başlattı:

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

15

Özel Sınıflar için projenizi içe aktarmanız gerekir

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

1
Hata alıyorum: Böyle bir modül "MyProjectName" yok. Bunu nasıl düzelteceğine dair bir fikrin var mı?
Alexander Stepanishin

@AlexanderStepanishin iş parçacığı / yığın yolunu ayarlamayı deneyin, Örnek: "Uygulamam> İş Parçacığı 1> 12 ana"
Juanmi

12

Xcode 8 / Swift 3 itibariyle, işte benim için işe yarayan şey. (Bu, @ sfaxon'un cevabına dayanmaktadır .)

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

11

Objective-C versiyonu

po ((MKPinAnnotationView *)0x7df67c50).alpha

1
Bu benim için mükemmel çalıştı. Benim durumumda, Debug View Hierarchygörünümün içindeydim, bir görünüme sağ tıkladıktan sonra seçtim Print description of.... Bu bana bir hafıza adresi verdi ve yukarıdaki koda bırakabileceğimi yazdım. Görsel hata ayıklayıcının konsolu bir Obj-C çerçevesine yerleştirdiğini bilmek güzel.
Trev14

10

Yukarıdaki tüm cevaplar sayesinde, unsafeBitCast , Xcode 8.3.2 / Swift 3 / macOS / Cocoa Uygulaması ile de iyi çalışıyor.

Mevcut örneğin adresini ezberleyin

(lldb) p tabView.controlTint
(NSControlTint) $R10 = defaultControlTint

(lldb) p self
(LearningStoryboard.NSTabViewController) $R11 = 0x00006080000e2280 {
.....

Daha sonra onları inceleyin

(lldb) p unsafeBitCast(0x00006080000e2280, to: NSTabViewController.self).tabView.controlTint
(NSControlTint) $R20 = graphiteControlTint

(lldb) p $R11.tabView.controlTint
(NSControlTint) $R21 = graphiteControlTint

Böyle bir şey olursa

(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'

assembler biri yerine Swift kaynak kodunun yığın çerçevelerinden birini seçtiğinizden emin olun.

Bir Duraklat düğmesine tıklanarak uygulama duraklatıldığında veya bir istisna ile durdurulduğunda gerçekleşmesi muhtemeldir . Buna göre bir yığın çerçevesi seçerek, lldb'nin uygun bir programlama dili çıkarmasına izin verin .


6

Kabul etmek istediğimi anlamam daha uzun sürdü. @Afinlayson cevabına benzer, ancak daha iyi bir açıklama (umarım!) Ve sabit sözdizimi ile

Xcode'un görünüm hiyerarşisi hata ayıklayıcısını kullanarak bir nesnenin özelliklerini kontrol etmek istiyorsanız, bu çalışacaktır: Varsayılan olarak objc bağlamındasınız, bu yüzden onu Swift bağlamına geçirmeniz gerekecek

  1. Önce projenizi içe aktarın (orada tanımlanan bazı sınıfları kullanmak istiyorsanız)

expr -l Swift -- import <YOUR PROJECT NAME>

  1. Bellek adresini kullanarak istediğiniz sınıfa nesneyi yayınlayın

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

  1. Nesneden istediğiniz herhangi bir değere erişin

expr -l Swift -- print($vc.<PROPERTY NAME>)

Misal:

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'in cevabı , LLDB oturumunuz Swift bağlamında başlatıldığında mükemmel çalışıyor. Ancak, bazı durumlarda Swift bağlamının dışındaki bir kesme noktasında durmuş olabilirsiniz ; örneğin, Objective-C API için sembolik bir kesme noktası olduğunda veya Hata Ayıklama Görünümü Hiyerarşisi modundayken (en azından Xcode 11.4 itibariyle).

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

Bu durumda, Objective-C kullanarak bunu eski şekilde yapmanız gerekir:

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

ve şimdi istediğiniz gibi kullanabilirsiniz $pin.


3

pobir takma addır, yani geçersiz kılınabilir. poObjc kullanarak onaltılık adresleri işleyerek geçersiz kılabilirsiniz :

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

Bunun nasıl bir etkiye sahip olduğunu görmek için lldb'ye bu takma adları genişletmesini söyleyebilirsiniz:

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

Ayrıca Swift'in yerini alacak olan https://github.com/kastiglione/swift_po'yu da oluşturdum po. Nesne adreslerini işler ve birkaç başka iyileştirme de vardır.


bağlantınızdan, expression -l objc -O -- 0x76543210sadece benim için bir cevap ve adresten değişken sınıfını bilmesine gerek yok!
tontonCD

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.