Pregunta

Yo trabajo en una aplicación de gran tamaño, y con frecuencia el uso de WinDbg para diagnosticar problemas basada en un archivo DMP de un cliente.He escrito un par de pequeñas extensiones de WinDbg que han demostrado ser muy útil para extraer los bits de información de archivos DMP.En mi código de extensión me encuentro eliminar la referencia de c++ clase de objetos de la misma manera, una y otra mano.Por ejemplo:

Address = GetExpression("somemodule!somesymbol");
ReadMemory(Address, &addressOfPtr, sizeof(addressOfPtr), &cb);

// get the actual address
ReadMemory(addressOfObj, &addressOfObj, sizeof(addressOfObj), &cb);

ULONG offset;
ULONG addressOfField;

GetFieldOffset("somemodule!somesymbolclass", "somefield", &offset);
ReadMemory(addressOfObj+offset, &addressOfField, sizeof(addressOfField), &cb);

Que funciona bien, pero como he escrito más extensiones, con una mayor funcionalidad (y acceder a más objetos complicados en nuestras aplicaciones DMP archivos), he deseado una mejor solución.Tengo acceso a la fuente de la propia aplicación de curso, así que me imagino no debe ser una manera de copiar un objeto de un archivo DMP y el uso que de memoria para crear un objeto real en la extensión del depurador de que yo pueda llamar a las funciones en (mediante la vinculación en archivos dll desde nuestra aplicación).Esto me ahorrará la molestia de tirar las cosas de la DMP con la mano.

Esto es incluso posible?Traté de cosas obvias, como la creación de un nuevo objeto en la extensión, luego sobrescribir con una gran ReadMemory directamente desde el archivo DMP.Esto parecía poner los datos en el derecho campos, pero se asustó cuando traté de llamar a una función.Me imagino que me falta algo...tal vez c++ hace algunas vtable funky-ness, que yo no sé?Mi código similar a este:

SomeClass* thisClass = SomeClass::New();
ReadMemory(addressOfObj, &(*thisClass), sizeof(*thisClass), &cb);

SEGUIMIENTO:Parece que POSIBLEMENTE ExtRemoteTyped de EngExtCpp es lo que quiero?Alguien ha utilizado con éxito este?Necesito a google hasta el código de ejemplo, pero no estoy teniendo mucha suerte.

SEGUIMIENTO 2:Estoy siguiendo dos rutas diferentes de investigación.
1) estoy buscando en ExtRemoteTyped, pero parece que esta clase es realmente sólo un auxiliar para el ReadMemory/GetFieldOffset llamadas.Sí, sería ayudar a acelerar las cosas MUCHO, pero realmente no ayuda cuando se trata de recrear un objeto a partir de un archivo DMP.Aunque la documentación es escasa, por lo que podría ser malentendido algo.2) yo también estoy buscando tratando de usar ReadMemory para sobrescribir un objeto creado en mi extensión con datos desde el archivo DMP.Sin embargo, en lugar de usar sizeof(*thisClass) como en el anterior, yo estaba pensando que me gustaría destacar sólo los elementos de datos, y dejar las vtables virgen.

¿Fue útil?

Solución

Interesante idea, pero con la esperanza de trabajar sólo en el más simple de los objetos.Por ejemplo, si el objeto contiene punteros o referencias a otros objetos (o vtables), los que no copia muy bien a un nuevo espacio de direcciones.

Sin embargo, usted puede ser capaz de obtener un 'proxy' objeto de trabajo que cuando se llama a los métodos del proxy que hacer las llamadas apropiadas a ReadMemory() para obtener la información.Esto suena a ser un poco justo de trabajo, y me gustaría pensar que tendría que ser más o menos un conjunto personalizado de código para cada clase que quería proxy.Probablemente hay una mejor manera de ir sobre esto, pero lo que vino a mí la parte superior de mi cabeza.

Otros consejos

Terminé justo después de mi primera corazonada, y copiar los datos desde el archivo dmp en un nuevo objeto.He hecho esta mejor, haciendo remoto de contenedor de objetos como este:

class SomeClassRemote : public SomeClass
{
protected:
    SomeClassRemote (void);
    SomeClassRemote (ULONG inRemoteAddress);

public:
    static  SomeClassRemote *       New(ULONG inRemoteAddress);
    virtual ~SomeClassRemote (void);

private:

    ULONG                   m_Address;

};

Y en la aplicación:

SomeClassRemote::SomeClassRemote (ULONG inRemoteAddress)
{
    ULONG cb;

    m_Address = inRemoteAddress;

    // copy in all the data to the new object, skipping the virtual function tables
    ReadMemory(inRemoteAddress + 0x4, (PVOID) ((ULONG)&(*this) +0x4), sizeof(SomeClass) - 4, &cb);
}

SomeClassRemote::SomeClassRemote(void)
{
}

SomeClassRemote::~SomeClassRemote(void)
{
}

SomeClassRemote* SomeClassRemote::New(ULONG inRemoteAddress)
{
    SomeClassRemote*x = new SomeClassRemote(inRemoteAddress);

    return (x);
}

Que es lo básico, pero luego me añada reemplaza en la medida necesaria para captar más la información desde el archivo dmp.Esta técnica me permite pasar estos nuevos objetos remotos en nuestro código fuente original para su procesamiento en las diversas funciones de utilidad, la causa de los que se derivan de la clase original.

Seguro que PARECE que debería ser capaz de templatize esto de alguna manera...pero parece que siempre hay ALGUNA razón por la que cada clase se implementa de forma LIGERAMENTE diferente, por ejemplo, algunos de nuestros más complicado objetos tienen un par vtables, ambos de los cuales tienen que ser omitidos.

Sé llegar volcados de memoria han sido siempre la manera de obtener información para el diagnóstico, pero con ETW su mucho más fácil y obtener una información junto con la pila de llamadas que incluyen el sistema de información de llamadas y el código de usuario.MS ha estado haciendo esto para todos sus productos, incluyendo Windows y VS.NET.

Es un no-intrusiva de depuración.He hecho mismo de depuración por mucho tiempo y ahora con ETW soy capaz de resolver la mayoría de problemas de los clientes sin tener que gastar mucho tiempo en el interior del depurador.Estas son mis dos centavos.

Me acerqué a algo similar al hacking de un gdi de fugas trazador extensión de windbg.He utilizado un contenedor stl para el almacenamiento de datos en el cliente y necesitaba una manera de atravesar los datos de la extensión.Terminé la aplicación de las partes de la hash_map necesitaba directamente en la extensión de lado el uso de ExtRemoteTyped que fue satisfactoria, pero me tomó un tiempo para averiguar ;o) Aquí es el código fuente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top