2016-09-05 8 views
20

मैंने नीचे दिए गए सदस्य फ़ंक्शन में प्रवेश करते समय "यह" पॉइंटर प्रिंट करने के लिए विंडबग का उपयोग करने का प्रयास किया।क्यों वीएस और विंडबग "यह" पॉइंटर को "0xcccccccc" के रूप में डिबग संस्करण में प्रिंट करते हैं?

class IBase { 
    int m_i; 
public: 
    IBase() :m_i(23) {} 
    virtual int FuncOne(void) = 0; 
    virtual int FuncTwo(void) = 0; 
}; 
class DerivedOne : public IBase { 
public: 
    virtual int FuncOne(void) { return 1; };//set break point here. 
    virtual int FuncTwo(void) { return 2; }; 
}; 
class DerivedTwo : public IBase { 
public: 
    virtual int FuncOne(void) { return 101; }; 
    virtual int FuncTwo(void) { return 102; }; 
}; 
void DoIt(IBase* Base) 
{ 
    int i=Base->FuncOne();//break point here 
} 
int main(int argc, char *argv[]) 
{ 
    DerivedOne d1; 
    DerivedTwo d2; 
    DoIt(&d1); 
    DoIt(&d2); 
    return 0; 
} 

(1) मैं इसे VC2015 डिबग संस्करण (32 बिट) के साथ संकलित

(2) मैं "छदाम" समारोह में तोड़ बिंदु निर्धारित।

(3) बेस-> FuncOne() को मारा, मैंने DerivedOne के फ़ंक्शन को दर्ज करने के लिए "F11" दबाया।

अब मैं देख सकता हूँ कॉल स्टैक इस तरह है:

0:000> k 
# ChildEBP RetAddr 
00 0041f654 0022157c ConsoleApplication1!DerivedOne::FuncOne [d:\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1.cpp @ 13] 
01 0041f734 0022173c ConsoleApplication1!DoIt+0x2c [d:\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1.cpp @ 23] 
02 0041f850 00221dc9 ConsoleApplication1!main+0x7c [d:\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1.cpp @ 36] 
03 0041f8a0 00221fbd ConsoleApplication1!__tmainCRTStartup+0x199 [f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c @ 626] 
04 0041f8a8 75b9338a ConsoleApplication1!mainCRTStartup+0xd [f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c @ 466] 
05 0041f8b4 77529902 kernel32!BaseThreadInitThunk+0xe 
06 0041f8f4 775298d5 ntdll!__RtlUserThreadStart+0x70 
07 0041f90c 00000000 ntdll!_RtlUserThreadStart+0x1b 

लेकिन "DV" कमांड अप्रत्याशित परिणाम

0:000> dv 
     this = 0xcccccccc 

ऐसा क्यों है दे दी है? कार्यक्रम अच्छी तरह से चलता है, डीबग संस्करण कुछ भी अनुकूलित नहीं करता है, ऐसा लगता है कि सबकुछ ठीक है। लेकिन क्यों "यह" सूचक अवैध है?

मैंने वीसी के स्वयं के आईडीई का उपयोग डीबग करने के लिए किया, उसी अवलोकन। पर क्यों?

+4

'यह'' Doit' फ़ंक्शन में परिभाषित नहीं है: यह आपकी किसी भी कक्षा का सदस्य नहीं है। –

+2

यदि आप एक अलग लाइन पर 'वापसी 1' डालते हैं, तो आपको वहां' वैध 'दिखाई देगा। – rustyx

+0

RustyX की तरह कहा, आप एक लाइन फ़ंक्शन के अंदर कदम नहीं उठा सकते हैं जब तक कि स्टैक को फ़ंक्शन कॉल न किया जाए। कम से कम दृश्य स्टूडियो के साथ नहीं। अलग लाइनों पर बयान रखो। – UmNyobe

उत्तर

40
virtual int FuncOne(void) { return 1; };//set break point here. 

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

आप केवल देख सकते हैं कि यह है जो उस प्रस्ताव कोड के निष्पादन के बाद उचित मूल्य रखता है। जिसके लिए डीबग> विंडोज> डिस्सेप्लर का उपयोग करने की आवश्यकता है ताकि आप mov dword ptr [this],ecx के बाद निर्देश के लिए सभी तरह से प्रस्तावना कोड को पीछे छोड़ सकें। बहुत अजीब

इस समस्या के लिए नहीं होगा, जब यह इस तरह इसे लिखने:

virtual int FuncOne(void) 
{ return 1; };//set break point here. 

या जो कुछ भी ब्रेस शैली आप पसंद करते हैं। अब ब्रेकपॉइंट सेट करना सुनिश्चित करता है कि फ़ंक्शन का प्रस्तावन निष्पादित किया गया था और यह अपेक्षित मान है।

या यह जानकर इसे निपटाना कि फ़ंक्शन के माध्यम से कदम उठाना सिर्फ दिलचस्प नहीं है क्योंकि यह डीबगिंग के लायक कुछ भी नहीं करता है। मूल कारण आपने इसे लिखा है। इसके बजाय डीबग> चरण का उपयोग करें। यदि आप गलती से इस तरह के फ़ंक्शन में कदम रखते हैं तो डीबग> चरण आउट का उपयोग उस कोड में वापस पाने के लिए करें जिसे आप वास्तव में डीबग करना चाहते हैं।

+13

यह उल्लसित है। :) –

+0

लेकिन क्यों नहीं "चरण में" FuncOne में जाते हैं और 'वापसी 1' पर रोकते हैं ?? – rustyx

+8

डीबगिंग जानकारी लाइन-नंबर आधारित है। वीएस द्वारा समर्थित अन्य भाषाएं कॉलम नंबर का भी विवरण ले सकती हैं।प्रीप्रोसेसर की वजह से सी और सी ++ में बर्बाद हो गया, संकलक केवल उलझन के बाद कोड देखता है। ओह कि preprocessor darned। वह मजेदार बीटीडब्ल्यू नहीं है। –

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