2011-07-07 2 views
11

मान लें कि मेरे पास कुछ बेस क्लास ए है और दो व्युत्पन्न कक्षाएं बी और सी क्लास ए में कुछ विधि है जिसे f() कहा जाता है।क्या मैं बेस क्लास विधि में एक सशर्त ब्रेकपॉइंट सेट कर सकता हूं जो केवल तभी ट्रिगर करता है जब यह विशिष्ट व्युत्पन्न वर्ग का उदाहरण हो?

क्या विजुअल स्टूडियो में ए :: एफ() में सशर्त ब्रेकपॉइंट सेट करने का कोई तरीका है जो केवल तब ही हिट होगा जब मेरा 'यह' वास्तव में कक्षा सी का उदाहरण है?

उदाहरण


    void A::f() 
    { 
    some code and a breakpoint 
    } 

    void foo(A* a) 
    { 
     a->f(); 
    } 

    void bar() 
    { 
     A a; 
     B b; 
     C c; 
     foo(&a); // breakpoint isn't hit 
     foo(&b); // breakpoint isn't hit 
     foo(&c); // breakpoint is hit 
    }

के लिए मैं ब्रेकपाइंट की हालत में आभासी तालिका सूचक परीक्षण लेकिन वहाँ एक बेहतर (अधिक आसान) तरीका हो गया है द्वारा इसे प्राप्त करने में कामयाब रहे है।

अग्रिम धन्यवाद।

संपादित करें: टिप्पणियों में सुझाए गए स्रोत कोड को संशोधित करना एक ऐसा समाधान नहीं है जिसे मैं ढूंढ रहा हूं। इसे केवल वीसी ++ डीबगर के माध्यम से किया जाना है।

+1

व्युत्पन्न कक्षा में विधि को ओवरराइड करने के लिए बस बेस क्लास को कॉल करें और अपना ब्रेकपॉइंट रखें? – AJG85

+0

@ AJG85 - हाँ, लेकिन यह संभव है कि बाइनरी को संशोधित नहीं किया जा सके। fwiw मुझे नहीं लगता कि सशर्त बीपी इसे करने की अनुमति देते हैं। –

+0

आह उस मामले में उत्तर "नहीं" – AJG85

उत्तर

0

कॉल साइट पर (यानी जहां foo कॉल किया जा रहा है), ऐसा करना लगभग असंभव है। फ़ंक्शन में, आप वर्चुअल फ़ंक्शन करके ऐसा कर सकते हैं, उनमें से एक true लौटाएगा। अन्य सभी false वापस आ जाएंगे। यदि फ़ंक्शन true देता है, तो आप DebugBreak फ़ंक्शन स्वयं ही कॉल कर सकते हैं। या इसके वापसी मूल्य को bool चर में डाल दें, और सशर्त ब्रेकपॉइंट सेट करें। हां, ज़ाहिर है, इसके लिए सभी वर्गों (या कुछ) में वर्चुअल फ़ंक्शन को जोड़ा जाना आवश्यक है। इसके अतिरिक्त आप बेस क्लास में एक साधारण bool वैरिएबल रख सकते हैं, जिसे व्युत्पन्न कक्षा द्वारा असाइन किया जाएगा। उचित व्युत्पन्न वर्ग (C आपके मामले में) इसे true के रूप में असाइन कर सकता है। आप केवल _DEBUG मैक्रो का उपयोग करके डीबग मोड में यह वर्चुअल/वेरिएबल सामान कर सकते हैं।

एक और समाधान मैक्रो होना है, जो foo फ़ंक्शन को कॉल करेगा। कार्यान्वयन के लिए ऊपर वर्णित अनुसार बेस क्लास में वर्चुअल-फ़ंक्शन/सदस्य-चर की आवश्यकता होती है, लेकिन foo संशोधित नहीं किया जाएगा।

#define CALL_FOO(obj) \ 
    if(obj->member_variable_test) DebugBreak(); \ 
    foo(&obj); 

और फोन CALL_FOOfoo के स्थान पर:

CALL_FOO(&c); // breakpoint is hit 

हालांकि, इस शायद अस्वीकार्य है, लेकिन काम करता है। और ब्रेकपॉइंट बिल्कुल ठीक है जहां आपको चाहिए! आप इस मैक्रो काम को केवल डीबग-बिल्ड में बना सकते हैं।

1

This post seems to hint at the possibility of programmatic debugging in Visual Studio.

वैकल्पिक रूप से, अगर आप या जीसीसी में स्रोत संकलन किसी भी तरह gdb उपयोग करने में सक्षम हैं, तो आप लाभ अजगर पटकथा कार्यक्षमता के जटिल सशर्त breakpoints बनाने के लिए लग सकता है।

Here are some gdb python tutorials. Here is the relevant gdb documentation.

+0

हां, मुझे पता है कि यह जीडीबी के साथ संभव है। दुर्भाग्य से मैं विजुअल स्टूडियो के साथ ढेर हूँ। – Serge

2

यह वही है dynamic_cast के लिए है।

void A::f() { 
    ... 
    if (dynamic_cast<C*>(this)) { 
     __debugbreak(); 
    } 
    ... 
} 

आप डिबगर द्वारा यह करने के लिए है, तो आप, को तोड़ने के प्रकार तत्काल विंडो में dynamic_cast का उपयोग कर की जांच करें और यदि नहीं जारी रखने के लिए होगा।

+0

नहीं करेगा, कोड को संशोधित नहीं कर सकता है। – Serge

4

आप कर सकते हैं।सबसे पहले, उस प्रकार की आभासी तालिका का पता निर्धारित करें जिसके विरुद्ध आप जांच करना चाहते हैं। फिर (arg) जैसी स्थिति के साथ ब्रेकपॉइंट सेट करें .__ vfptr! = 0x01188298 जहां 0x01188298 आपका प्रकार vtable का पता है। बस।

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

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