developer tip

LLDB (Swift) : 원시 주소를 사용 가능한 유형으로 캐스팅

copycodes 2020. 10. 13. 07:57
반응형

LLDB (Swift) : 원시 주소를 사용 가능한 유형으로 캐스팅


원시 주소를 사용 가능한 Swift 클래스로 캐스팅 할 수있는 LLDB 명령이 있습니까?

예를 들면 :

(lldb) po 0x7df67c50 as MKPinAnnotationView

이 주소가 MKPinAnnotationView를 가리키는 것을 알고 있지만 선택할 수있는 프레임이 아닙니다. 그러나 속성을 검사 할 수 있도록 원시 주소를 MKPinAnnotationView로 캐스팅하고 싶습니다. 이것이 가능한가?


Xcode 8.2.1 및 Swift 3에서 lldb 명령 po 또는 p 는 입력 된 변수와 함께 작동하지 않습니다. 유형이 지정된 개체 인스턴스의 속성을 검사하려면 빠른 명령 print 를 사용해야합니다 . ( cbowns의 답변에 감사드립니다 !) 예 :

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

Swift의 unsafeBitCast함수를 사용 하여 주소를 객체 인스턴스로 캐스팅 할 수 있습니다 .

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

그런 다음 $pin평소 같이 작업 할 수 있습니다. 속성 액세스, 메서드 호출 등.

자세한 내용은이 기사를 확인하십시오 : Swift Memory Dumping .


의 lldb 형식 expression은 Xcode 7.3에서 변경된 것 같습니다. 다음으로 시작했습니다.

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

Xcode 8 / Swift 3에서 저에게 효과적이었습니다. (이것은 @sfaxon의 답변을 기반으로합니다 .)

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

커스텀 클래스의 경우 프로젝트를 가져와야합니다.

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

위의 모든 답변 덕분에 unsafeBitCast 는 Xcode 8.3.2 / Swift 3 / macOS / Cocoa Application에서도 잘 작동합니다.

현재 인스턴스의 주소를 기억

(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 소스 코드의 스택 프레임 중 하나를 선택해야합니다.

일시 중지 버튼 을 클릭하여 응용 프로그램이 일시 중지 되었거나 예외로 인해 중지되었을 때 발생할 수 있습니다. 그에 따라 스택 프레임을 선택하여 lldb 가 적절한 프로그래밍 언어를 추론하도록합니다.


Objective-C 버전

po ((MKPinAnnotationView *)0x7df67c50).alpha

@Xi Chen의 대답은 LLDB 세션이 Swift 컨텍스트에서 시작되었을 때 완벽하게 작동합니다. 그러나 어떤 경우 에는 Swift 컨텍스트 외부중단 점에서 중지되었을 수 있습니다 . 예를 들어 Objective-C API에 대한 상징적 중단 점일 때입니다.

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

이 경우 Objective-C를 사용하여 이전 방식으로 수행해야합니다.

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

이제 원하는 $pin대로 사용할 수 있습니다 .


가장 쉬운 방법, 신속한 4

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

po무시할 수 있음을 의미하는 별칭입니다. poobjc를 사용하여 16 진수 주소를 처리하여 재정의 할 수 있습니다 .

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

To see what effect this has, you can tell lldb to expand these aliases:

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

Also I have created https://github.com/kastiglione/swift_po, which is a substitute po for Swift. It handles object addresses, and has a few other improvements too.


It took me longer to figure out that I'd like to admit. It's similar to @afinlayson answer, but with better explanation (I hope!) and fixed syntax

If you want to check properties of an objects using Xcode’s view hierarchy debugger then this will work: You’re in objc context by default so you’ll have to switch it to Swift context

  1. First import your project (if you want to use some of the classes defined there)

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

  1. Cast object using it’s memory address to whatever class you want

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

  1. Access any value you want from the object

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

Example:

expr -l Swift -- import Football

expr -l Swift -- let $vc = unsafeBitCast(0x7fb7c51cb270, to: Football.Ball.self)

expr -l Swift -- print($vc.velocity)

참고URL : https://stackoverflow.com/questions/29441418/lldb-swift-casting-raw-address-into-usable-type

반응형