Найти все объекты C ++ типа X в куче с помощью WinDbg - PullRequest
3 голосов
/ 26 июня 2010

Я пытаюсь найти все объекты типа module!SomeClass в куче.Я думал, что такая команда сработает:

> s -v 0 L?0xfffffff module!SomeClass

но, увы, это не так.Если бы я знал, как найти адрес виртуальной таблицы для этого класса, я мог бы искать в памяти ссылки на эту виртуальную таблицу, но мне тоже не повезло найти его.Как я могу это сделать?

Ответы [ 2 ]

10 голосов
/ 06 апреля 2011
0:000> x module!SomeClass*table*
0:000> !heap -srch 'address_of_vtable'
0 голосов
/ 08 апреля 2018
class Polygon {
protected:
    int width, height;
public:
    virtual int area()
    {
        return 0;
    }
};

class Rectangle : public Polygon {
public:
    int area()
    {
        return width * height;
    }
};

class Triangle : public Polygon {
public:
    int area()
    {
        return (width * height / 2);
    }
};


class RectangleTriangle : public Rectangle, Triangle //RectangleTriangle  <-- This class will have two Vtables for each base class
{
public:
    int area()
    {
        return (2* 3/ 2);
    }
};

int main() {
    RectangleTriangle *rect = new RectangleTriangle();
    Triangle trgl;
    Polygon poly;
    return 0;
}

Причина, по которой мы начинаем с vtables, заключается в том, что любой объект, который наследует виртуальную функцию, будет иметь указатель vtable, который в основном является статической переменной класса.Таким образом, каждый объект этого класса должен иметь ссылку на это местоположение vtable при создании объекта в куче.Таким образом, из указателя vtable мы в основном пытаемся получить сам объект.

0:000> x Win32Sample!RectangleTriangle*table*
00007ff7`81ed3288 Win32Sample!RectangleTriangle::`vftable' = <function> *[2] <-- one for each base class
00007ff7`81ed3278 Win32Sample!RectangleTriangle::`vftable' = <function> *[2] <-- one for each base class

0:000> !heap -srch 00007ff7`81ed3288  // <-- We are asking !heap "who owns a pointer to this vtable in the entire process heap"
    _HEAP @ 1e5ed710000
              HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
        000001e5ed716620 0006 0000  [00]   000001e5ed716630    00021 - (busy)
          Win32Sample!RectangleTriangle::`vftable'

0:000> !heap -srch 00007ff7`81ed3278 // <-- We are asking !heap "who owns a pointer to this vtable in the entire process heap"
    _HEAP @ 1e5ed710000
              HEAP_ENTRY Size Prev Flags            UserPtr UserSize - state
        000001e5ed716620 0006 0000  [00]   000001e5ed716630    00021 - (busy)
          Win32Sample!RectangleTriangle::`vftable'

UserPtr - это, по сути, начало блока памяти, возвращаемого менеджером кучи для нового оператора.Вот почему UserPtr не означает место в памяти, которое включает это значение, вместо этого оно является началом блока кучи, следовательно, в обеих таблицах значение одинаково 000001e5ed716630

0:000> dt Win32Sample!RectangleTriangle 000001e5ed716630
   +0x000 __VFN_table : 0x00007ff7`81ed3278 
   +0x008 width            : 0n0
   +0x00c height           : 0n0
   +0x010 __VFN_table : 0x00007ff7`81ed3288 
   +0x018 width            : 0n0
   +0x01c height           : 0n0

Мы не можем использовать команду s для поискауказатель vtable и объект в куче, потому что блоки кучи не являются смежными !!!

...