2009-05-20 21 views
11

प्रतिबिंब का उपयोग करते समय कॉल स्टैक प्राप्त करना संभव है (इसके अलावा यह जेआईटी ऑप्टिमाइज़ेशन के कारण कच्चे सन्निकटन हो सकता है) सिस्टम.डिग्नोस्टिक्स.स्टैकट्रेस का उपयोग करके और स्टैकफ्रेम ऑब्जेक्ट्स की जांच करें।मैं स्टैकफ्रेम के लिए निष्पादन ऑब्जेक्ट कैसे प्राप्त करूं?

मैं कैसे वस्तु (इस-सूचक), जिस पर एक ढेर फ्रेम में एक विधि को क्रियान्वित कर रहा है के लिए एक संदर्भ मिल सकता है?

मुझे पता है कि मैं स्टैक फ्रेम ऑब्जेक्ट पर GetMethod() को कॉल करके विधिबेस प्राप्त कर सकता हूं, लेकिन जो मैं खोज रहा हूं वह GetObject() की रेखाओं के साथ कुछ है (जो स्वाभाविक रूप से शून्य हो जाता है यदि विधि स्थैतिक है)। ऐसा लगता है कि स्टैक फ्रेम ऑब्जेक्ट को केवल विधिवत निर्धारित जानकारी जैसे विधि जानकारी, मूल फ़ाइल इत्यादि के लिए पूछताछ की जा सकती है।

वीएस डीबगर जानता है (हालांकि यह शायद कॉल स्टैक ट्रेस प्राप्त करने की दूसरी विधि का उपयोग करता है), जैसा कि कोई भी कर सकता है कॉल स्टैक विंडो में किसी भी स्टैक फ्रेम को डबल क्लिक करें और स्थानीय और कक्षा फ़ील्ड के मानों को देखें।

संपादित करें: स्पष्ट करने के लिए: मैं वस्तु उदाहरण जिस पर विधि बुलाया गया था चाहते हैं। I.e: यदि विधि फू() को ऑब्जेक्ट इंस्टेंस पर कॉल कहा जाता है तो कॉल स्टैक पर कहीं भी, और यह उस विधि को कैस्केड करता है जो मैं स्टैक ट्रेस करता हूं, मैं ए से एक संदर्भ प्राप्त करना चाहता हूं जहां से मैं स्टैक ट्रेस करता हूं। (विधि आधार का घोषित प्रकार नहीं)

उत्तर

6

मुझे पूरा यकीन है कि यह संभव नहीं है। किसी को भी एक फ्रेम देखने कर सकते हैं के बाद से, चाहे वस्तु मिल जो AppDomain \ थ्रेड के वे पर क्रियान्वित करने या अनुमति वे कर रहे हैं,

  1. इस प्रकार का सुरक्षा को तोड़ सकते थे: यहां इसका कारण बताया।

  2. 'this' (सी #) पहचानकर्ता वास्तव में केवल उदाहरण विधि (पहला) के लिए एक तर्क है, इसलिए वास्तव में स्थिर विधियों और उदाहरण विधियों के बीच कोई अंतर नहीं है, संकलक अपने जादू को दाएं पास करने के लिए करता है this एक आवृत्ति विधि के लिए, जिसका अर्थ है कि आपको this ऑब्जेक्ट प्राप्त करने के लिए सभी विधि तर्कों तक पहुंच की आवश्यकता होगी। (जो StackFrame का समर्थन नहीं करता)

यह संभव हो सकता है unsafe कोड का उपयोग कर एक उदाहरण विधि के लिए पहला तर्क का सूचक प्राप्त करने के लिए और फिर सही प्रकार के लिए यह कास्टिंग द्वारा, लेकिन मैं कैसे का ज्ञान नहीं है ऐसा करने के लिए, बस एक विचार है।

बीटीडब्ल्यू आप सी # 3.0 एक्सटेंशन विधियों की तरह संकलित होने के बाद उदाहरण विधियों की कल्पना कर सकते हैं, उन्हें this पॉइंटर को उनके पहले तर्क के रूप में मिलता है।

+0

मुझे पता है कि इस सूचक को पारित कर दिया है फोन करने वाले है, जिसके कारण अस्तित्वहीन GetObject() अशक्त वापसी होगी तो वह एक स्थिर विधि थी, और एक उदाहरण विधि में विहित 'इस' सूचक की एक प्रति द्वारा कॉल स्टैक पर विधि कहा जाता है। हालांकि, मैं आपके # 1 तर्क से सहमत हूं, सिवाय इसके कि ऑब्जेक्ट तक पहुंच आसानी से डिज़ाइन द्वारा उचित अनुमति की आवश्यकता हो सकती है। –

+0

वास्तविक समस्या यह है कि एक स्टैकफ्रेम आपके कोड के बारे में कुछ मेटाडेटा है, यह आपके कोड का लाइव संस्करण नहीं है। – Yona

+0

जैसा कि मुझे डर था। लेकिन मुझे उम्मीद थी कि कुछ अन्य वर्गों का लाभ उठाने के लिए। –

-1

मुझे यकीन नहीं है कि मैं पूरी तरह से समझता हूं कि आप क्या चाहते हैं, लेकिन यदि आप उस प्रकार को जानना चाहते हैं जिसमें एक निश्चित स्टैक फ्रेम की विधि घोषित की गई है, तो मुझे लगता है कि यह कोड रिटर्न कि:

StackTrace trace = new StackTrace();  
Type methodOwner = trace.GetFrame(0).GetMethod().DeclaringType; 

आप निश्चित रूप से फ्रेम है कि आप में रुचि रखते हैं के लिए सूचकांक पारित करने के लिए की आवश्यकता होगी (मैं उदाहरण के रूप में 0 का उपयोग करें)।

+2

मुझे लगता है कि उसका मतलब उदाहरण है, प्रकार नहीं। –

+0

हाँ, 'वस्तु' एक प्रकार का उदाहरण का मतलब है,) –

+0

हाँ, मुझे एहसास हुआ कि (यह वास्तव में अपने प्रश्न में नहीं बल्कि स्पष्ट है; मैं थोड़ा थक गया मुझे लगता है कि था ...) –

3

यह thiscall वस्तु के संदर्भ में प्राप्त करने के लिए संभव है, लेकिन केवल नेट कोड के साथ नहीं। मूल कोड शामिल होना चाहिए। गतिशील वर्गों और सिस्टम का उपयोग करने के साथ भी। चयन। नामस्थान दर्ज करें .NET में अन्य विधियों के मूल्यांकन स्टैक और तर्कों तक पहुंचने के लिए उपकरण नहीं हैं।

दूसरी तरफ यदि आप अपनी .NET विधि को अलग करते हैं तो आप देख सकते हैं कि यह संदर्भ भौतिक ढेर पर नहीं पारित होता है। Thiscall संदर्भ ECX (RCX x64 के लिए) में संग्रहीत है, इसके बजाय पंजीकरण करें। तो यह संभव है कि आप अपनी विधि से स्टैक पर चढ़ाई करें जिस तरीके से आप thiscall ऑब्जेक्ट प्राप्त करना चाहते हैं। और फिर अनुदेश जो बचाने के रजिस्टर ECX (RCX) ढेर में के लिए है कि विधि की मशीन कोड के अंदर देखने, और कहा कि शिक्षा से रिश्तेदार पता नहीं है जहां कि संदर्भ झूठ मिलता है।

बेशक, चढ़ाई की विधि x32 और x64 एप्लिकेशन में गंभीर रूप से भिन्न है। इस तरह के फ़ंक्शन का उत्पादन करने के लिए आपको न केवल सी # लेकिन असेंबली कोड का उपयोग करना चाहिए, और ध्यान रखें कि इनलाइन असेंबलर को x64 के तहत अनुमति नहीं है; यह एक पूर्ण असेंबलर मॉड्यूल होना चाहिए।

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

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