원시 주소를 사용 가능한 Swift 클래스로 캐스팅 할 수있는 LLDB 명령이 있습니까?
예를 들면 :
(lldb) po 0x7df67c50 as MKPinAnnotationView
이 주소가 MKPinAnnotationView를 가리키는 것을 알고 있지만 선택할 수있는 프레임이 아닙니다. 그러나 속성을 검사 할 수 있도록 원시 주소를 MKPinAnnotationView로 캐스팅하고 싶습니다. 이게 가능해?
원시 주소를 사용 가능한 Swift 클래스로 캐스팅 할 수있는 LLDB 명령이 있습니까?
예를 들면 :
(lldb) po 0x7df67c50 as MKPinAnnotationView
이 주소가 MKPinAnnotationView를 가리키는 것을 알고 있지만 선택할 수있는 프레임이 아닙니다. 그러나 속성을 검사 할 수 있도록 원시 주소를 MKPinAnnotationView로 캐스팅하고 싶습니다. 이게 가능해?
답변:
Xcode 8.2.1 및 Swift 3에서 lldb 명령 po 또는 p 는 입력 된 변수와 함께 작동하지 않습니다. 유형이 지정된 개체 인스턴스의 속성을 검사하려면 빠른 명령 print 를 사용해야합니다 . ( cbowns의 답변에 감사드립니다 !) 예 :
expr -l Swift -- import UIKit
expr -l Swift -- let $pin = unsafeBitCast(0x7df67c50, to: MKPinAnnotationView.self)
expr -l Swift -- print($pin.alpha)
(lldb)
콘솔 에 입력 할 필요가 없다고 생각했습니다 . 하지만 그것 없이는 작동하지 않았습니다.
expr -l Swift --
..
Swift의 unsafeBitCast
함수를 사용 하여 주소를 객체 인스턴스로 캐스팅 할 수 있습니다 .
(lldb) e let $pin = unsafeBitCast(0x7df67c50, MKPinAnnotationView.self)
(lldb) po $pin
그런 다음 $pin
평소 와 같이 작업 할 수 있습니다. 속성 액세스, 메서드 호출 등.
자세한 내용은이 기사를 확인하십시오 : Swift Memory Dumping .
(lldb) settings set target.language swift
. 또한 경우에 따라 (예 : 앱에서 유형으로 캐스팅하는 동안 앱 모듈에서 벗어나는 경우) 다음과 같이해야 할 수도 있습니다.e import MyApp
커스텀 클래스의 경우 프로젝트를 가져와야합니다.
expr -l Swift -- import MyTestProject
expr -l Swift -- let $vc = unsafeBitCast(0x7fad22c066d0, ViewController.self)
expr -l Swift -- print($vc.view)
Xcode 8 / Swift 3에서 저에게 효과적이었습니다. (이것은 @sfaxon의 답변을 기반으로합니다 .)
(lldb) expr -l Swift -- import UIKit
(lldb) expr -l Swift -- let $nav = unsafeBitCast(0x1030ff000, to: UINavigationController.self)
위의 모든 답변 덕분에 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 가 적절한 프로그래밍 언어를 추론하도록합니다.
인정하고 싶다는 것을 알아내는 데 시간이 더 걸렸습니다. @afinlayson 답변과 비슷하지만 더 나은 설명 (희망!)과 고정 구문이 있습니다.
Xcode의 뷰 계층 디버거를 사용하여 객체의 속성을 확인하려면 다음이 작동합니다. 기본적으로 objc 컨텍스트에 있으므로 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>)
예:
expr -l Swift -- import Football
expr -l Swift -- let $vc = unsafeBitCast(0x7fb7c51cb270, to: Football.Ball.self)
expr -l Swift -- print($vc.velocity)
@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
대로 사용할 수 있습니다 .
po
무시할 수 있음을 의미하는 별칭입니다. po
objc를 사용하여 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
나에게 응답이며 주소에서 변수 클래스를 알 필요가 없습니다!