How can I create objects based on dump file memory in a WinDbg extension?

后端 未结 4 1423
走了就别回头了
走了就别回头了 2021-02-06 13:55

I work on a large application, and frequently use WinDbg to diagnose issues based on a DMP file from a customer. I have written a few small extensions for WinDbg that have prov

相关标签:
4条回答
  • 2021-02-06 14:15

    I approached something similar when hacking a gdi leak tracer extension for windbg. I used an stl container for data storage in the client and needed a way to traverse the data from the extension. I ended up implementing the parts of the hash_map I needed directly on the extension side using ExtRemoteTyped which was satisfactory but took me awhile to figure out ;o) Here is the source code.

    0 讨论(0)
  • 2021-02-06 14:17

    Interesting idea, but this would have a hope of working only on the simplest of objects. For example, if the object contains pointers or references to other objects (or vtables), those won't copy very well over to a new address space.

    However, you might be able to get a 'proxy' object to work that when you call the proxy methods they make the appropriate calls to ReadMemory() to get the information. This sounds to be a fair bit of work, and I'd think it would have to be more or less a custom set of code for each class you wanted to proxy. There's probably a better way to go about this, but that's what came to me off the top of my head.

    0 讨论(0)
  • 2021-02-06 14:17

    I know getting memory dumps have always been the way to get information for diagnosing, but with ETW its lot more easy and you get a information along with call stacks which include information system calls and user code. MS has been doing this for all their products including Windows and VS.NET.

    It is a non-intrusive way of debugging. I have done same debugging for very long and now with ETW I am able to solve most of customer issues without spending lot of time inside the debugger. These are my two cents.

    0 讨论(0)
  • 2021-02-06 14:29

    I ended up just following my initial hunch, and copying over the data from the dmp file into a new object. I made this better by making remote wrapper objects like this:

    class SomeClassRemote : public SomeClass
    {
    protected:
        SomeClassRemote (void);
        SomeClassRemote (ULONG inRemoteAddress);
    
    public:
        static  SomeClassRemote *       New(ULONG inRemoteAddress);
        virtual ~SomeClassRemote (void);
    
    private:
    
        ULONG                   m_Address;
    
    };
    

    And in the implementation:

    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);
    }
    

    That is the basics, but then I add specific overrides in as necessary to grab more information from the dmp file. This technique allows me to pass these new remote objects back into our original source code for processing in various utility functions, cause they are derived from the original class.

    It sure SEEMS like I should be able to templatize this somehow... but there always seems to be SOME reason that each class is implemented SLIGHTLY differently, for example some of our more complicated objects have a couple vtables, both of which have to be skipped.

    0 讨论(0)
提交回复
热议问题