2010-09-23 13 views
5

मैं [MethodImpl(MethodImplOptions.InternalCall)] बीसीएल विधि के कार्यान्वयन में डीबग करना चाहता हूं, जिसे संभवतः सी ++ में कार्यान्वित किया गया है। (इस विशेष मामले में, मैं System.String.nativeCompareOrdinal देख रहा हूं।) यह मुख्य रूप से इसलिए है क्योंकि मैं नुकीला हूं और जानना चाहता हूं कि यह कैसे कार्यान्वित किया गया है।मैं एक अप्रबंधित बीसीएल (InternalCall) विधि में कैसे डिबग कर सकता हूं?

हालांकि, विजुअल स्टूडियो डीबगर उस विधि में कदम उठाने से इनकार कर रहा है। मैं इस फोन पर एक ब्रेकपाइंट सेट कर सकते हैं:

"Hello".Equals("hello", StringComparison.OrdinalIgnoreCase); 

तो कदम डिबग> विंडोज> Disassembly को लाने, बराबर में कदम कहते हैं, और जब तक यह call x86 निर्देश के लिए हो जाता है। लेकिन जब मैं उस call पर "चरण में" का उपयोग करने का प्रयास करता हूं (जिसे मैं प्रतिबिंबक से जानता हूं वह देशी कॉम्पैयरऑर्डिनल कॉल है), यह देशी कॉम्पैयरऑर्डिनल के अंदर पहले निर्देश के लिए कदम नहीं उठाता है - यह इसके बजाय कदम उठाता है, और सीधे जाता है बराबर में अगला x86 निर्देश।

मैं x86 के रूप में निर्माण कर रहा हूं, क्योंकि मिश्रित मोड डिबगिंग x64 ऐप्स के लिए समर्थित नहीं है। मैंने टूल्स> विकल्प> डिबगिंग में "जस्ट माई कोड" अनचेक किया है, और मेरे पास प्रोजेक्ट गुणों में डिबग किए गए "अप्रबंधित कोड डिबगिंग सक्षम करें" है - डीबग टैब, लेकिन यह अभी भी call पर कदम उठाता है। मैंने प्रक्रिया शुरू करने और फिर डीबगर को जोड़ने की कोशिश की, और स्पष्ट रूप से प्रबंधित और देशी डिबगर्स दोनों को संलग्न किया, लेकिन यह अभी भी उस आंतरिक कॉल विधि में कदम नहीं उठाएगा।

मैं एक अप्रबंधित विधि में कदम उठाने के लिए विजुअल स्टूडियो डीबगर कैसे प्राप्त कर सकता हूं?

उत्तर

5

हाँ, यह मुश्किल है। कॉल निर्देश के लिए आप जो ऑफ़सेट देखते हैं वह फर्जी है। इसके अलावा यह एक प्रबंधित फ़ंक्शन पर वर्तमान फ़ोकस होने पर आपको एक अप्रबंधित कोड पते पर नेविगेट नहीं करने देगा।

अप्रबंधित कोड डीबगिंग सक्षम करने और कॉल पर ब्रेकपॉइंट सेट करके प्रारंभ करें। कोड चलाने के लिए और जब तोड़ने बिंदु हिट डीबग + विंडोज + Disassembly का उपयोग करें:

  "Hello".Equals("hello", StringComparison.OrdinalIgnoreCase); 
00000025 call  6E53D5D0 
0000002a nop    

डिबगर पूर्ण पते प्रदर्शित करने के लिए कोशिश करता है लेकिन यह गलत है क्योंकि यह फर्जी वृद्धिशील पते के बजाय का उपयोग करता है वास्तविक अनुदेश पते की हो जाता है। तो पहले सही सापेक्ष मूल्य पुनर्प्राप्त करें: 0x6E53D5D0 - 0x2A = 0x6E53D5A6।

अगला आपको वास्तविक कोड पता ढूंढना होगा। डीबग + विंडोज + रजिस्टर्स और ईआईपी रजिस्टर के मूल्य को देखें। मेरे मामले में 0x009A0095। एनओपी पर जाने के लिए 5 जोड़ें, फिर रिश्तेदार ऑफ़सेट जोड़ें: 0x9A0095 + 5 + 0x6E53D5A6 = 0x6EEDD640। समारोह का असली पता।

डीबग + विंडोज + कॉल स्टैक और एक अप्रबंधित स्टैक फ्रेम को डबल-क्लिक करें। अब आप Disassembly विंडो के पता बॉक्स में गणना की गई पता दर्ज कर सकते हैं, 0x के साथ उपसर्ग।

6EEDD640 push  ebp 
6EEDD641 mov   ebp,esp 
6EEDD643 push  edi 
6EEDD644 push  esi 
6EEDD645 push  ebx 
6EEDD646 sub   esp,18h 
etc... 

बिंगो, तुम्हें पता है कर रहे हैं आप अच्छा कर रहे हैं यदि आप स्टैक फ्रेम सेटअप कोड देखें। उस पर ब्रेकपॉइंट सेट करें और F5 दबाएं।


बेशक, आप कोई कोड कोड उपलब्ध नहीं होने के बाद से मशीन कोड कदम उठाएंगे। SSCLI20 स्रोत कोड को देखकर यह कोड क्या कर रहा है, इस बारे में आपको बेहतर जानकारी मिल जाएगी। कोई गारंटी नहीं है कि यह सीएलआर के आपके वर्तमान संस्करण में वास्तविक कोड के लिए एक मैच होगा, लेकिन मेरा अनुभव यह है कि 1.0 के आसपास के निम्न स्तर के कोड भाग अत्यधिक संरक्षित हैं। कार्यान्वयन clr \ src \ classlibnative \ nls में है, यह सुनिश्चित नहीं है कि कौन सी स्रोत कोड फ़ाइल है। इसे "देशी कॉम्पारेऑर्डिनल" नाम नहीं दिया जाएगा, यह ecall.cpp द्वारा उपयोग किया जाने वाला एक आंतरिक नाम है।

+0

मैं किसी विधि पर घायल नहीं हुआ, लेकिन एक थक्का - एक पीओपी ईएक्स के लिए एक जेएमपी को कॉल किया गया था (कॉल के वापसी मूल्य को स्टैक से वापस पॉप करने के लिए)। मुझे लगता है कि एक थंक के लिए व्यवहार्य शुरुआत। हां, जब मैंने कॉल ऑपोड पर ब्रेकपॉइंट सेट किया था, तो डीबगर हमेशा के लिए बैठा था, सीपीयू को हॉगिंग करता था लेकिन कभी नहीं तोड़ता था; और जब मैंने उस ब्रेकपॉइंट को हटा दिया और इसके बजाय जेएमपी और पीओपी पर ब्रेकपॉइंट्स सेट किए, तो यह उनके पीछे ठीक से चला गया, जिससे ऐप को कभी भी तोड़ने के बिना पूरा करने की अनुमति मिल गई। इसलिए मैं इस तरह x86 ऑपकोड देख सकता हूं, लेकिन स्पष्ट रूप से डीबग नहीं कर सकता उनके द्वारा। कुछ भी नहीं से काफी बेहतर है, लेकिन अभी भी थोड़ा निराशाजनक है। –

+0

कोई थंक नहीं है, मुझे नहीं लगता कि आपको सही कोड मिला है। –

संबंधित मुद्दे