Pourquoi VS et Windbg impriment " ce "pointeur comme" 0xcccccccc " même en version de débogage?

j'ai essayé d'utiliser windbg pour imprimer pointeur "this" lors de la saisie d'une fonction membre, comme ci-dessous.

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) j'ai compilé avec VC2015 version de débogage(32 bits)

(2) j'ai défini le point de rupture dans la fonction "DoIt".

(3) Quand j'ai appuyé sur Base->FuncOne (), j'ai appuyé sur "F11" pour entrer la fonction de DerivedOne.

Maintenant, je peux voir la pile d'appel est comme ceci:

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

mais la commande "dv" a donné un résultat inattendu résultat

0:000> dv
       this = 0xcccccccc

Pourquoi est-ce? Le programme fonctionne bien, la version de débogage n'optimise rien, semble que tout va bien. Mais pourquoi" ce " pointeur est invalide?

j'ai utilisé L'IDE de VC pour déboguer, même observation. Mais pourquoi?

20
demandé sur Jolta 2016-09-05 11:49:03

1 réponses

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

c'est votre style de codage qui cause ce problème. Puisque vous avez écrit le corps de la fonction dans la même ligne que la définition de la fonction, le point de rupture est défini au début de la fonction, et non au début du corps de la fonction. À ce point, le prologue de la fonction n'a pas encore été exécutés. Le code qui définit le cadre de la pile et récupère les arguments de la fonction. Cachés argument est l'un d'entre eux, il est passé comme premier argument de la fonction.

Vous ne pouvez observer avoir la valeur appropriée après l'exécution du prologue. Ce qui nécessite L'utilisation de Debug > Windows > désassemblage afin que vous puissiez passer le Code prologue, tout le chemin jusqu'à l'instruction après mov dword ptr [this],ecx. Très à l'aise.

Vous n'aurez pas ce problème lorsqu'il l'écrire comme ceci:

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

ou n'importe quel style de Corset que vous préférez. Maintenant, le réglage du point d'arrêt garantit que le prologue de la fonction exécuté et a la valeur attendue.

ou s'y attaquer en sachant que passer à travers la fonction n'est tout simplement pas intéressant car il ne fait rien qui vaille la peine d'être débuggé. La raison fondamentale pour laquelle tu l'as écrit comme ça. Utilisez Debug > Step Over à la place. Si vous avez accidentellement marché dans une telle fonction puis utiliser Debug > Step Out pour revenir rapidement dans le code que vous voulez réellement déboguer.

41
répondu Hans Passant 2016-09-05 09:28:17