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


93

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

예를 들면 :

(lldb) po 0x7df67c50 as MKPinAnnotationView

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

답변:


152

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)

38
이것은 정말 그렇게 어렵지 않습니다
Departamento B

이것은 약간 직관적이지 않았습니다. (lldb)콘솔 에 입력 할 필요가 없다고 생각했습니다 . 하지만 그것 없이는 작동하지 않았습니다.

2
Objective-c에서 이것을 수행하는 방법이 있습니까?
p0lAris

나는 이것에 계속해서 돌아 간다. expr -l Swift -- ..
Koen에

49

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

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

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

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


첫 번째 진술에서는 'expr'또는 'expression'을 잊은 것 같습니다. 그렇지 않으면 잘 작동합니다!
jarrodparkes

2
Xcode 7.2에서 "오류 : 선언되지 않은 식별자 'unsafeBitCast'사용"이 표시됩니다.
devios1

8
"알 수없는 유형 이름 '하자'오류 :"그 오류 외에 (@devios은)는 7.3.1에서 보여 또 다른 오류가있다
carlos_ms

3
컨텍스트에 따라 먼저을 사용하여 lldb를 Swift 모드로 전환해야 할 수도 있습니다 (lldb) settings set target.language swift. 또한 경우에 따라 (예 : 앱에서 유형으로 캐스팅하는 동안 앱 모듈에서 벗어나는 경우) 다음과 같이해야 할 수도 있습니다.e import MyApp
Patrick Pijnappel

25

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

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

14

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

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

1
오류가 발생합니다. "MyProjectName"모듈이 없습니다. 이 문제를 해결하는 방법에 대한 의견이 있으십니까?
Alexander Stepanishin

@AlexanderStepanishin은 스레드 / 스택 경로를 설정해보십시오. 예 : "MyApp> Thread 1> 12 main"
Juanmi

12

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

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

10

위의 모든 답변 덕분에 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 가 적절한 프로그래밍 언어를 추론하도록합니다.


10

Objective-C 버전

po ((MKPinAnnotationView *)0x7df67c50).alpha

1
이것은 나를 위해 완벽하게 작동했습니다. 제 경우에는 Debug View Hierarchy뷰에 있었고 뷰를 마우스 오른쪽 버튼으로 클릭 한 다음을 선택했습니다 Print description of.... 그것은 저에게 메모리 주소와 유형을주었습니다. 비주얼 디버거가 콘솔을 Obj-C 프레임에 배치한다는 사실을 알게되어 기쁩니다.
Trev14

6

인정하고 싶다는 것을 알아내는 데 시간이 더 걸렸습니다. @afinlayson 답변과 비슷하지만 더 나은 설명 (희망!)과 고정 구문이 있습니다.

Xcode의 뷰 계층 디버거를 사용하여 객체의 속성을 확인하려면 다음이 작동합니다. 기본적으로 objc 컨텍스트에 있으므로 Swift 컨텍스트로 전환해야합니다.

  1. 먼저 프로젝트를 가져옵니다 (여기에 정의 된 일부 클래스를 사용하려는 경우)

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

  1. 메모리 주소를 사용하여 객체를 원하는 클래스로 캐스팅하십시오.

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

  1. 개체에서 원하는 값에 액세스

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)


5

@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대로 사용할 수 있습니다 .


3

po무시할 수 있음을 의미하는 별칭입니다. poobjc를 사용하여 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나에게 응답이며 주소에서 변수 클래스를 알 필요가 없습니다!
tontonCD

2

가장 쉬운 방법, 신속한 4

expr unsafeBitCast(0x7df67c50, to: MKPinAnnotationView.self)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.