2016-09-05 8 views
20

Aşağıdaki gibi bir üye işlev girerken "bu" işaretçisini yazdırmak için windbg kullanmayı denedim.Neden VS ve Windbg "bu" işaretçisini hata ayıklama sürümünde bile "0xcccccccc" olarak yazdırıyor?

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) Ben VC2015 ayıklama sürümü (32 bit) ile derlenmiş

(2) Ben "DoIt" fonksiyonunda kırılma noktasını ayarlayın.

(3) Base-> FuncOne() öğesine bastığınızda, DerivedOne işlevine girmek için "F11" tuşlarına bastım.

Şimdi görebildiğim çağrı yığını şu şekildedir:

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 

Ama "dv" komutu beklenmeyen bir sonuç

0:000> dv 
     this = 0xcccccccc 

bu neden verdi? Program iyi çalışıyor, hata ayıklama sürümü hiçbir şey optimize etmiyor, her şey yolunda görünüyor. Ama neden "bu" işaretçi geçersiz?

VC'nin kendi IDE'sini hata ayıklamada ve aynı gözlemde kullandım. Ama neden?

+4

'' bu 'Doit' işlevinde tanımlanmadı: sınıflarınızın hiçbiri üyesi değil. –

+2

"1" i ayrı bir satıra koyarsanız, orada geçerli bir "bu" görürsünüz. – rustyx

+0

RustyX'in dediği gibi, yığın boyunca bir işlev çağrısı olmadıkça bir satır işlevinin içine giremezsiniz. En azından Visual Studio ile değil. İfadeleri ayrı satırlara koyun. – UmNyobe

cevap

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

Bu soruna neden olan kodlama stilinizdir. İşlev gövdesini işlev tanımıyla aynı satırda yazdığınız için, kesme noktası işlev başlangıcında değil, işlev gövdesinin başlangıcında ayarlanır. Bu noktada, işlevin prologu henüz yürütülmemiştir. Yığın çerçevesini oluşturan ve işlevin argümanlarını alan kod. Gizli bu argümanı bunlardan biridir, fonksiyonun ilk argümanı olarak geçilir.

Sadece bu kodunu, ilgili prolog kodu yürütüldükten sonra uygun değere sahip olarak gözlemleyebilirsiniz. Hangi Debug> Windows> Disassembly kullanarak gerektirir, böylece mov dword ptr [this],ecx sonra yönergeye kadar, tüm prologue kodu geçebilirsiniz. Çok garip.

Bunu şöyle yazarken bu sorunu olmaz: Eğer

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

Veya ne olursa olsun ayracı tarzı tercih ediyorum. Şimdi kesme noktasının ayarlanması, işlevin prologunun gerçekleştirilmesini ve 'un bu'un beklenen değere sahip olmasını sağlar. Ya da hata ayıklamaya değecek bir şey yapmadığından fonksiyona adım atmanın sadece ilginç olmadığını bilerek çözebilirsiniz. Bunu yazmanın temel sebebi. Bunun yerine Debug> Step Over'ı kullanın. Yanlışlıkla böyle bir işleve girdiyseniz, hata ayıklama yapmak istediğiniz kodu hızlıca geri almak için Hata Ayıkla> Step Out'ı kullanın.

+13

Bu çok komik. :) –

+0

Ama neden "Step Into", FuncOne'a girmiyor ve "return 1" de durmuyor? – rustyx

+8

Hata ayıklama bilgisi, satır numarasına dayalıdır. VS tarafından desteklenen diğer diller de sütun numarasını dikkate alabilir.Ön işlemciden dolayı C ve C++ 'da mahvolmuş olan derleyici, kodlandıktan sonra kodu görüyor. Ah bu ön işlemcisi. Bu komik değil btw. –

İlgili konular