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