Frage

Hier einige code, den ich habe:

MyClass* MyClass::getInstance()
{
   static MyClass instance;
   return &instance;
}

Ich will in diese anzusehen singleton ' s die aktuellen Werte.Aber ich bin gerade angehalten, drei Stunden in der Ausführung, und der Grund, warum ich angehalten wurde, ist, dass ich aus der Erinnerung.So ich kann nicht setzen Sie einen Haltepunkt in diese Methode, es zu sehen, was das Wert ist.

Meine Frage ist dann, wie bitte dieses instance Variablen von einem globalen Rahmen.Ich habe versucht, darauf zu verweisen, wie MyClass::getInstance::instance aber das funktioniert nicht.Ich vermute, getInstance muss geschmückt werden, irgendwie.Wer weiß, wie?

Dies ist in Visual Studio 2008.

War es hilfreich?

Lösung

Gut, die Funktions-Bereich in statische instance variable nicht zeigen, bis in ein .map - Datei generiert cl.exe /Fm, und es nicht zeigen, bis, wenn ich x programname!*MyClass* in WinDbg, so dass der verstümmelte name scheint nicht zu enthalten MyClass an alle.

Option 1:Zerlegen MyClass::getInstance

Dieser Ansatz scheint einfacher:

0:000> uf programname!MyClass::getInstance
programname!MyClass::getInstance [programname.cpp @ 14]:
   14 00401050 55              push    ebp
   14 00401051 8bec            mov     ebp,esp
   15 00401053 a160b34200      mov     eax,dword ptr [programname!$S1 (0042b360)]
   15 00401058 83e001          and     eax,1
   15 0040105b 7526            jne     funcstat!MyClass::getInstance+0x33 (00401083)

programname!MyClass::getInstance+0xd [programname.cpp @ 15]:
   15 0040105d 8b0d60b34200    mov     ecx,dword ptr [programname!$S1 (0042b360)]
   15 00401063 83c901          or      ecx,1
   15 00401066 890d60b34200    mov     dword ptr [programname!$S1 (0042b360)],ecx
   15 0040106c b9b0be4200      mov     ecx,offset programname!instance (0042beb0)
   15 00401071 e88fffffff      call    programname!ILT+0(??0MyClassQAEXZ) (00401005)
   15 00401076 68e03e4200      push    offset programname!`MyClass::getInstance'::`2'::`dynamic atexit destructor for 'instance'' (00423ee0)
   15 0040107b e8f3010000      call    programname!atexit (00401273)
   15 00401080 83c404          add     esp,4

programname!MyClass::getInstance+0x33 [programname.cpp @ 16]:
   16 00401083 b8b0be4200      mov     eax,offset programname!instance (0042beb0)
   17 00401088 5d              pop     ebp
   17 00401089 c3              ret

Aus diesem können wir sagen, dass der compiler aufgerufen, das Objekt $S1.Natürlich kann dieser name wird davon abhängen, wie viele Funktions-Bereich in statische Variablen, die Ihrem Programm hat.

Option 2:Suche Speicher für das Objekt

Erweitern @gbjbaanb Vorschlag, wenn MyClass hat virtuelle Funktionen, könnten Sie in der Lage sein zu finden, seine Lage auf dem harten Weg:

  • Stellen Sie ein vollständiges Speicherabbild des Prozesses.
  • Laden Sie die vollständige Speicher dump in WinDbg.
  • Verwenden Sie die x Befehl, um die Adresse von MyClass ' s vtable:
    0:000> x programname!MyClass::`vftable'
    00425c64 programname!MyClass::`vftable' = 
  • Verwenden Sie die s Befehl zum suchen des Prozesses, der virtuelle Adressraum (in diesem Beispiel 0-2GB) für Zeiger, MyClass, die vtable:
    0:000> s -d 0 L?7fffffff 00425c64
    004010dc  00425c64 c35de58b cccccccc cccccccc  d\B...].........
    0040113c  00425c64 8bfc458b ccc35de5 cccccccc  d\B..E...]......
    0042b360  00425c64 00000000 00000000 00000000  d\B.............
  • Verwenden Sie die dt Befehl, um die Klasse zu finden, die vtable-offset, und subtrahieren Sie diese von zurückgegebenen Adressen von der Suche.Dies sind die möglichen Adressen für das Objekt.
    0:000> dt programname!MyClass
       +0x000 __VFN_table      : Ptr32 
       +0x008 x                : Int4B
       +0x010 y                : Float
  • Verwenden dt programname!MyClass 0042b360 zum untersuchen des Objekts member-Variablen, die Hypothese geprüft, dass das Objekt befindet sich in 0042b360 (oder eine andere Adresse).Sie werden wahrscheinlich einige false positives, wie ich oben, sondern durch Einsicht in die member-Variablen können Sie in der Lage sein, um herauszufinden, welche Ihre singleton.

Dies ist eine Allgemeine Technik, die für die Suche nach C++ - Objekte, und ist eine Art overkill, wenn Sie nur könnten zerlegen MyClass::getInstance.

Andere Tipps

In gdb, können Sie einen Beobachtungspunkt auf der verstümmelte name der variable.

Zum Beispiel mit dieser Funktion:

int f() {
    static int xyz = 0;
    ++xyz;

    return xyz;
}

Ich kann sehen _ZZ1fvE3xyz (wie entstellt von gcc-3.2.3-oder gcc 4.0.1).

Dass code, der sieht nur so gefährlich...:-)

Aber wie auch immer, Ihre entstellten Namen wird abhängen auf Ihre Aufruf-Konvention Also, bevor Sie Ihre mangle-Namen müssen Sie wissen, was Ihre build-Umgebung wie die Aufruf-Konvention.MSDN hat eine Menge mehr Informationen über die Aufruf-Konvention.

Neben dieser, ein Weg, um herauszufinden, alle Informationen über Ihre Klasse zu überprüfen Sie Ihre VTable, die sich in den ersten 4 bytes des Objekts.Ein raffinierter trick, reversers verwenden ist eine versteckte VC++ Flag reportSingleClassLayout druckt die Klassenstruktur in eine ASCII-Kunst Weise.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top