Apakah ada perintah LLDB yang dapat mentransmisikan alamat mentah ke dalam kelas Swift yang dapat digunakan?
Sebagai contoh:
(lldb) po 0x7df67c50 as MKPinAnnotationView
Saya tahu bahwa alamat ini menunjuk ke MKPinAnnotationView, tetapi tidak dalam bingkai yang dapat saya pilih. Tapi, saya ingin mentransmisikan alamat mentah ke dalam MKPinAnnotationView sehingga saya bisa memeriksa propertinya. Apakah ini mungkin?
(lldb)
di konsol saya. Tapi itu tidak akan berhasil tanpa itu.expr -l Swift --
..Anda dapat menggunakan
unsafeBitCast
fungsi Swift untuk mentransmisikan alamat ke instance objek:(lldb) e let $pin = unsafeBitCast(0x7df67c50, MKPinAnnotationView.self) (lldb) po $pin
Kemudian Anda bisa bekerja dengan
$pin
seperti biasa - mengakses properti, metode panggilan, dll.Lihat artikel ini untuk informasi lebih lanjut: Swift Memory Dumping .
sumber
(lldb) settings set target.language swift
. Selain itu, dalam beberapa kasus (misalnya saat keluar dari modul aplikasi Anda saat mentransmisikan ke suatu jenis dari aplikasi Anda), Anda mungkin perlu mengikutinya dengane import MyApp
Format lldb
expression
tampaknya telah berubah di Xcode 7.3. Hal berikut ini membuat saya mulai:(lldb) expr -l Swift -- import UIKit (lldb) expr -l Swift -- let $view = unsafeBitCast(0x7fb75d8349c0, UIView.self)
sumber
Untuk Kelas Kustom, Anda perlu mengimpor proyek Anda
expr -l Swift -- import MyTestProject expr -l Swift -- let $vc = unsafeBitCast(0x7fad22c066d0, ViewController.self) expr -l Swift -- print($vc.view)
sumber
Pada Xcode 8 / Swift 3, inilah yang berhasil untuk saya. (Ini didasarkan pada jawaban @ sfaxon .)
(lldb) expr -l Swift -- import UIKit (lldb) expr -l Swift -- let $nav = unsafeBitCast(0x1030ff000, to: UINavigationController.self)
sumber
Berkat semua jawaban di atas, unsafeBitCast juga berfungsi dengan baik dengan Aplikasi Xcode 8.3.2 / Swift 3 / macOS / Cocoa.
Hafalkan alamat contoh saat ini
(lldb) p tabView.controlTint (NSControlTint) $R10 = defaultControlTint (lldb) p self (LearningStoryboard.NSTabViewController) $R11 = 0x00006080000e2280 { .....
Nanti, periksalah
(lldb) p unsafeBitCast(0x00006080000e2280, to: NSTabViewController.self).tabView.controlTint (NSControlTint) $R20 = graphiteControlTint (lldb) p $R11.tabView.controlTint (NSControlTint) $R21 = graphiteControlTint
Jika hal seperti ini terjadi
(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'
pastikan bahwa memilih salah satu bingkai tumpukan kode sumber Swift daripada yang assembler.
Ini mungkin terjadi ketika aplikasi dijeda dengan mengklik tombol Jeda atau dihentikan dengan pengecualian. Dengan memilih frame stack yang sesuai, biarkan lldb menyimpulkan bahasa pemrograman yang tepat.
sumber
Versi Objective-C
po ((MKPinAnnotationView *)0x7df67c50).alpha
sumber
Debug View Hierarchy
tampilan, mengklik kanan pada tampilan, lalu dipilihPrint description of...
. Itu memberi saya alamat memori dan jenis yang bisa saya masukkan ke kode di atas. Senang mengetahui bahwa debugger visual menempatkan konsol ke dalam bingkai Obj-C.Butuh waktu lebih lama bagi saya untuk menyadari bahwa saya ingin mengakuinya. Ini mirip dengan jawaban @afinlayson, tetapi dengan penjelasan yang lebih baik (saya harap!) Dan sintaks yang tetap
Jika Anda ingin memeriksa properti suatu objek menggunakan debugger hierarki tampilan Xcode, ini akan berfungsi: Anda berada dalam konteks objek secara default sehingga Anda harus mengalihkannya ke konteks 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>)
Contoh:
expr -l Swift -- import Football
expr -l Swift -- let $vc = unsafeBitCast(0x7fb7c51cb270, to: Football.Ball.self)
expr -l Swift -- print($vc.velocity)
sumber
Jawaban @Xi Chen berfungsi sempurna saat sesi LLDB Anda dimulai dalam konteks Swift. Namun, dalam beberapa kasus Anda mungkin berhenti di breakpoint di luar konteks Swift; misalnya, saat breakpoint simbolis ke Objective-C API, atau saat dalam mode Debug View Hierarchy (setidaknya pada Xcode 11.4).
error: unknown type name 'let' error: use of undeclared identifier 'unsafeBitCast'
Dalam hal ini, Anda harus melakukannya dengan cara lama menggunakan Objective-C:
e MKPinAnnotationView *$pin = (MKPinAnnotationView *)0x7df67c50
dan sekarang Anda dapat menggunakan
$pin
seperti yang Anda inginkan.sumber
po
adalah alias, yang artinya dapat diganti. Anda dapat menggantipo
dengan menangani alamat hex menggunakan objc:command regex po s/(0x[[:xdigit:]]+)/expression -l objc -O -- %1/ s/(.+)/expression -O -- %1/
Untuk melihat efeknya, Anda dapat memberi tahu lldb untuk memperluas alias ini:
(lldb) settings set interpreter.expand-regex-aliases true
Saya juga telah membuat https://github.com/kastiglione/swift_po , yang merupakan pengganti
po
Swift. Ini menangani alamat objek, dan memiliki beberapa perbaikan lainnya juga.sumber
expression -l objc -O -- 0x76543210
hanya tanggapan untuk saya, dan tidak perlu mengetahui kelas variabel dari alamat!Cara termudah, cepat 4
expr unsafeBitCast(0x7df67c50, to: MKPinAnnotationView.self)
sumber