एलएलडीबी (स्विफ्ट): कच्चा पता का उपयोग करने योग्य प्रकार में कास्टिंग


92

क्या कोई एलएलडीबी कमांड है जो कच्चे पते को एक उपयोगी स्विफ्ट क्लास में डाल सकता है?

उदाहरण के लिए:

(lldb) po 0x7df67c50 as MKPinAnnotationView

मुझे पता है कि यह पता MKPinAnnotationView की ओर इशारा करता है, लेकिन यह एक फ्रेम में नहीं है जिसे मैं चुन सकता हूं। लेकिन, मैं कच्चे पते को MKPinAnnotationView में डालना चाहता हूं ताकि मैं इसके गुणों की जांच कर सकूं। क्या यह संभव है?

जवाबों:


152

Xcode 8.2.1 और स्विफ्ट 3 के तहत, lldb कमांड पीओ या p टाइप किए गए वैरिएबल के साथ काम नहीं करेगा। टाइप किए गए ऑब्जेक्ट उदाहरण के गुणों की जांच करने के लिए आपको स्विफ्ट कमांड प्रिंट का उपयोग करना होगा । ( Cbowns के जवाब के लिए धन्यवाद !) जैसे:

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

37
यह वास्तव में इतना कठिन नहीं होना चाहिए
डिपार्टमेन्ट B

यह थोड़ा काउंटर सहज था। मुझे लगा कि मुझे (lldb)अपने कंसोल में टाइप करने की आवश्यकता नहीं है। लेकिन इसके बिना काम नहीं किया।
हनी

2
क्या ऑब्जेक्टिव-सी में ऐसा करने का कोई तरीका है?
p0lAris

मैं इस पर वापस आती रहती हूं। मैं शायद expr -l Swift -- .. के लिए एक बड़ा उपनाम बनाना चाहिए
Koen।

49

आप unsafeBitCastएक वस्तु उदाहरण के लिए एक पता लगाने के लिए स्विफ्ट के फ़ंक्शन का उपयोग कर सकते हैं :

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

फिर आप $pinहमेशा की तरह काम कर सकते हैं - उपयोग के गुण, कॉल के तरीके, आदि।

अधिक जानकारी के लिए इस लेख को देखें: स्विफ्ट मेमोरी डंपिंग


पहले कथन के लिए मुझे लगता है कि आप 'एक्सप' या 'एक्सप्रेशन' को भूल गए हैं। अन्यथा यह महान काम कर रहा है!
जारोडपार्केस

2
मुझे Xcode 7.2 में "त्रुटि: अघोषित पहचानकर्ता 'असुरक्षित कैफे" का उपयोग मिल रहा है।
devios1

8
उस त्रुटि के अलावा (@devios) 7.3.1 में एक और त्रुटि दिखाई देती है: "त्रुटि: अज्ञात प्रकार का नाम 'लेट'"
carlos_ms

3
ध्यान दें कि संदर्भ के आधार पर आपको पहले प्रयोग करके स्विफ्ट मोड में lldb स्विच करना पड़ सकता है (lldb) settings set target.language swift। इसके अलावा, कुछ मामलों में (जैसे आपके ऐप से टाइप करते समय आपके ऐप के मॉड्यूल के बाहर तोड़ने पर) आपको इसके लिए अनुसरण करने की आवश्यकता हो सकती हैe import MyApp
पैट्रिक पिजनपेल

25

expressionलगता है कि Xcode 7.3 में lldb प्रारूप बदल गया है। निम्नलिखित मुझे शुरू कर दिया:

(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" नहीं। किसी भी विचार यह कैसे तय करने के लिए?
अलेक्जेंडर स्टीफेनिन

@AlexanderStepanishin थ्रेड / स्टैक पथ सेट करने का प्रयास करें, उदाहरण: "MyApp> थ्रेड 1> 12 मुख्य"
जुआनमी

12

Xcode 8 / स्विफ्ट 3 के रूप में, यहाँ मेरे लिए क्या काम किया गया है। (यह @ sfaxon के उत्तर पर आधारित है ।)

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

10

उपरोक्त सभी उत्तरों के लिए धन्यवाद, असुरक्षित बिटकॉस्ट भी Xcode 8.3.2 / स्विफ्ट 3 / macOS / कोकोआ एप्लीकेशन के साथ अच्छी तरह से काम करता है।

वर्तमान उदाहरण का एक पता याद रखें

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

सुनिश्चित करें कि कोडांतरक एक के बजाय स्विफ्ट स्रोत कोड के स्टैक फ़्रेम में से एक चुनें।

ऐसा तब होने की संभावना है जब एक ठहराव बटन पर क्लिक करके एप्लिकेशन को रोक दिया गया था या एक अपवाद के साथ बंद कर दिया गया था। तदनुसार एक स्टैक फ्रेम का चयन करके, lldb को एक उचित प्रोग्रामिंग भाषा का अनुमान लगाने दें ।


10

उद्देश्य-सी संस्करण

po ((MKPinAnnotationView *)0x7df67c50).alpha

1
इसने मेरे लिए पूरी तरह से काम किया। मेरे मामले में मैं Debug View Hierarchyदृश्य में था , एक दृश्य पर राइट क्लिक किया गया, फिर चुना गया Print description of...। इससे मुझे एक मेमोरी एड्रेस मिला और मैं ऊपर दिए गए कोड में टाइप कर सकता था। यह जानकर अच्छा लगा कि विज़ुअल डीबगर कंसोल को ओबज-सी फ्रेम में डाल देता है।
ट्रेव 14

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 चेन का जवाब पूरी तरह से काम करता है जब आपका एलएलडीबी सत्र स्विफ्ट संदर्भ में शुरू किया गया था। हालांकि, कुछ मामलों आप एक ब्रेकप्वाइंट में बंद कर दिया हो सकता है में बाहर एक स्विफ्ट संदर्भ; उदाहरण के लिए, जब यह ऑब्जेक्टिव-सी एपीआई के लिए एक प्रतीकात्मक विराम बिंदु है, या जब डिबग व्यू हायरार्की मोड में (कम से कम Xcode 11.4 के रूप में)।

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

उस स्थिति में, आपको ऑब्जेक्ट-सी का उपयोग करके इसे पुराने तरीके से करना होगा:

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

और अब आप $pinजैसा चाहें वैसा उपयोग कर सकते हैं ।


3

poएक उपनाम है, जिसका अर्थ है कि इसे ओवरराइड किया जा सकता है। आप poobjc का उपयोग करके हेक्स पतों को संभालकर ओवरराइड कर सकते हैं :

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

यह देखने के लिए कि इसका क्या प्रभाव है, आप एलडीबी को इन उपनामों का विस्तार करने के लिए कह सकते हैं:

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

इसके अलावा मैंने https://github.com/kastiglione/swift_po बनाया है , जो poस्विफ्ट का विकल्प है। यह ऑब्जेक्ट एड्रेस को हैंडल करता है, और इसमें कुछ अन्य सुधार भी हैं।


आपके लिंक से, expression -l objc -O -- 0x76543210मेरे लिए बस प्रतिक्रिया है, और इसे एड्रेस से परिवर्तनशील वर्ग को जानने की आवश्यकता नहीं है!
टनटन

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.