Little memdump

Derek Parnell derek at nomail.afraid.org
Tue Mar 13 19:34:16 PDT 2007


On Tue, 13 Mar 2007 22:37:55 -0300, Tom wrote:

> David L.Davis escribió:
>> Tom Wrote:
>> 
>>> Hi people,
>>>
>>>    I just wanted to share with you a *very-humble* memdump procedure 
>>> that has been very helpful to me in my tedious D-debugging nights.
>>>
>>> Kind regards,
>>> --
>>> Tom;
>>>
>> 
>> Hi Tom,
>> 
>>     Thanks for sharing your useful code...hope you don't mind that I've replaced the 'C' printf()s with 'D' writef()s functions, and added some test data to it.
> 
> I'm glad you found it useful.
> Please, feel free to enhance it (or whatever). I wrote it in 10 minutes 
> so... ;) (it has been very useful to me for a long time now, though).

I once wrote something very similar, but not as compact as yours <g>.

import std.cstream;

// Displays a formatted memory dump.
// pFrom is the starting address
// pLength is the number of bytes to display
// pTitle is an optional Title for the display
// pDest is the destination: Either std.cstream.dout or std.cstream.derr
(default)

void format_mem(void*  pFrom, 
                uint   pLength, 
                char[] pTitle = "", 
                CFile  pDest = derr)
{
    void* lEnd;
    void* lAddr;
    void* lRow;
    uint  lDispCnt;

    // Calc last byte address + 1
    lEnd    = cast(ubyte *)pFrom + pLength;
    // Calc starting address for display purposes.
    lAddr   = cast(void *)((cast(uint)pFrom) & 0xFFFFFFF0);

    // Show any supplied title.
    if (pTitle.length > 0)
        pDest.writefln("%s", pTitle);

    // Show the header columns.
    pDest.writefln("Memory contents at address:%08X for %d bytes\n"
                    "           "
                    "+0+1+2+3 +4+5+6+7  +8+9+A+B +C+D+E+F  "
                    " |----------------|",
                    cast(int)pFrom, pLength);

    // Repeat for groups of 16 address locations.
    while (lAddr < lEnd)
    {
        // Show the address for this line.
        pDest.writef("  %08X ", cast(uint)lAddr);
        // Calc this line's end address
        lRow = cast(ubyte *)lAddr + 16;

        // One-off code to skip over possible leading addresses not used.
        while(cast(uint)lAddr < cast(uint)pFrom)
        {
            pDest.writef("  ");
            // Show padding if needed.
            if (((cast(uint)lAddr) & 3u) == 3u) pDest.writef(" ");
            if (((cast(uint)lAddr) & 7u) == 7u) pDest.writef(" ");
            lAddr += 1;
            lDispCnt++;
        }

        // Display each byte as a 2-digit hex value.
        while( lAddr < lRow)
        {
            if (lAddr < lEnd)
            {
                pDest.writef("%02X", cast(uint)(*cast(ubyte*)lAddr));
            }
            else
            {
                pDest.writef("  ");
            }
            // Show padding if needed.
            if (((cast(uint)lAddr) & 3u) == 3u) pDest.writef(" ");
            if (((cast(uint)lAddr) & 7u) == 7u) pDest.writef(" ");
            lAddr += 1;
        }

        // Begin the 'string' display part of the line.
        pDest.writef(" |");

        //  Skip over any leading addresses not actually used.
        while(lDispCnt > 0)
        {
            pDest.writef(" ");
            lDispCnt--;
        }

        // Display each byte as an ASCII char if possible else use a dot.
        while( cast(uint)pFrom < cast(uint)lAddr)
        {
            ubyte lChar;
            char[1] lStr;
            if (pFrom < lEnd)
            {
                lChar = *cast(ubyte*)pFrom;
                if (lChar < cast(ubyte)' ')
                    pDest.writef(".");
                else if (lChar > cast(ubyte)'~')
                    pDest.writef(".");
                else
                {
                    lStr[0] = cast(char)lChar;
                    pDest.writef("%s", lStr);
                }
            }
            else
                pDest.writef(" ");

            pFrom += 1;
        }
        // End of line.
        pDest.writefln("|");
    }

    // End of dump display.
    pDest.writefln("           "
                    "------------------------------------  "
                    " |----------------|"
                   );
}


// Just used to test this routine.
debug(format_mem)
{
void main(char[][] pArgs)
{
    foreach(char[] s; pArgs)
        format_mem(s.ptr, s.length * s[0].sizeof, s);
    format_mem(pArgs.ptr, pArgs.length * pArgs[0].sizeof, "pArgs");

    format_mem(cast(void *)&main, 100, "main()");
    format_mem(cast(void *)&format_mem, 100, "format_mem()");

    format_mem(cast(void *)new char[80], 100 );
}
}

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Justice for David Hicks!"
14/03/2007 1:32:03 PM



More information about the Digitalmars-d mailing list