digitalmars.D - Little memdump
- Tom (42/42) Mar 12 2007 Hi people,
- David L.Davis (92/101) Mar 13 2007 Hi Tom,
- Tom (6/21) Mar 13 2007 I'm glad you found it useful.
-
Derek Parnell
(122/142)
Mar 13 2007
I once wrote something very similar, but not as compact as yours
. - Tom (6/28) Mar 13 2007 Nice. I can see why it isn't that compact, it's closer to hexdump than
- Jeff McGlynn (39/45) Mar 15 2007 Here is the code that I use:
- Bill Baxter (4/53) Mar 15 2007 Just curious -- what are you guys doing that you have to dump memory so
- Jeff McGlynn (6/54) Mar 15 2007 I recently wrote a FastCGI server, which uses a binary protocol. Using
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; void memdump(void* from, uint length) { uint plen= 0; ubyte* adr(uint i) { return cast(ubyte*)from+i+plen; } char chr(uint i) { return cast(char)*(cast(ubyte*)from+i+plen); } ubyte byt(uint i) { return cast(ubyte)*(cast(ubyte*)from+i+plen); } while (length>0) { printf("+-----------+-----------+-----------+-----------+\n|"); for (uint i=0; i<16; i+=4) { printf("0x%08X |", adr(i)); } printf("\n|"); for (uint i=0, j=0; i<16; i++, j=(j+1)%4) { if (i < length) { if (chr(i) < 14) printf(" "); else printf(" %c", chr(i)); } else printf(" "); if (j==3) printf("|"); else printf(" "); } printf("\n|"); for (uint i=0, j=0; i<16; i++, j=(j+1)%4) { if (i < length) printf("%02X", byt(i)); else printf(" "); if (j==3) printf("|"); else printf(" "); } printf("\n"); if (length > 16) length-= 16; else length= 0; plen+= 16; } printf("+-----------+-----------+-----------+-----------+\n"); }
Mar 12 2007
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. // To compile the test example: dmd memdump.d -version=memdump // To compile: dmd MySource.d memdump.d private import io = std.stdio; void memdump(void* from, uint length) { uint plen = 0; ubyte* adr(uint i) { return cast(ubyte*)from + i + plen; } char chr(uint i) { return cast(char)*(cast(ubyte*)from + i + plen); } ubyte byt(uint i) { return cast(ubyte)*(cast(ubyte*)from + i + plen); } char c = '\0'; while (length > 0) { io.writef("+-----------+-----------+-----------+-----------+\n|"); for (uint i = 0; i < 16; i += 4) io.writef("0x%0.8X |", adr(i)); io.writef("\n|"); for (uint i = 0, j = 0; i < 16; i++, j = (j + 1) % 4) { if (i < length) { c = chr(i); if (c < 14 || c > 127) io.writef(" "); else io.writef(" %s", chr(i)); } else io.writef(" "); if (j == 3) io.writef("|"); else io.writef(" "); } io.writef("\n|"); for (uint i = 0, j = 0; i < 16; i++, j = (j + 1) % 4) { if (i < length) io.writef("%0.2X", byt(i)); else io.writef(" "); if (j == 3) io.writef("|"); else io.writef(" "); } io.writef("\n"); if (length > 16) length -= 16; else length = 0; plen += 16; } io.writef("+-----------+-----------+-----------+-----------+\n"); } version(memdump) { void main() { char[] s = "This is a text message for memdump to use as test data."; ubyte[] b = [0x4D, 0x5A, 0x60, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x20, 0x57, 0x69, 0x6E, 0x33, 0x32, 0x00, 0x00]; io.writefln("dump string data..."); memdump(cast(void*)s, s.length); io.writefln(); io.writefln("dump binary data..."); memdump(cast(void*)b, b.length); } } Take Care, David L.
Mar 13 2007
David L.Davis escribió:Tom Wrote: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). -- Tom;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.
Mar 13 2007
On Tue, 13 Mar 2007 22:37:55 -0300, Tom wrote:David L.Davis escribió: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 PMTom Wrote: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).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.
Mar 13 2007
Derek Parnell escribió:On Tue, 13 Mar 2007 22:37:55 -0300, Tom wrote:Nice. I can see why it isn't that compact, it's closer to hexdump than mine :P Regards, -- Tom;David L.Davis escribió:I once wrote something very similar, but not as compact as yours <g>.Tom Wrote: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).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.
Mar 13 2007
On 2007-03-12 17:40:16 -0700, Tom <tom nospam.com> said: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,Here is the code that I use: import std.stdio; import std.ctype; void debug_dump(ubyte[] data) { uint len = data.length; writefln("=== GOT %d BYTES:", len); for(uint offset = 0; offset < len; offset += 20) { uint end = offset + 20; if (end > len) end = len; for(uint ix = offset; ix < end; ++ix) { writef("%02X ", data[ix]); } if (offset + 20 > len) { char[] space = new char[3 * (offset + 20 - len)]; space[] = ' '; writef(space); } writef("| "); for(uint ix = offset; ix < end; ++ix) { if (isprint(data[ix])) { writef("%s", cast(char) data[ix]); } else { writef("."); } } writefln(); } writefln(); } -- Jeff McGlynn
Mar 15 2007
Jeff McGlynn wrote:On 2007-03-12 17:40:16 -0700, Tom <tom nospam.com> said:Just curious -- what are you guys doing that you have to dump memory so often? --bbHi 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,Here is the code that I use: import std.stdio; import std.ctype; void debug_dump(ubyte[] data) { uint len = data.length; writefln("=== GOT %d BYTES:", len); for(uint offset = 0; offset < len; offset += 20) { uint end = offset + 20; if (end > len) end = len; for(uint ix = offset; ix < end; ++ix) { writef("%02X ", data[ix]); } if (offset + 20 > len) { char[] space = new char[3 * (offset + 20 - len)]; space[] = ' '; writef(space); } writef("| "); for(uint ix = offset; ix < end; ++ix) { if (isprint(data[ix])) { writef("%s", cast(char) data[ix]); } else { writef("."); } } writefln(); } writefln(); }
Mar 15 2007
On 2007-03-15 02:03:44 -0700, Bill Baxter <dnewsgroup billbaxter.com> said:Jeff McGlynn wrote:I recently wrote a FastCGI server, which uses a binary protocol. Using this allowed me to debug protocol errors without adding new code each time. -- Jeff McGlynnOn 2007-03-12 17:40:16 -0700, Tom <tom nospam.com> said:Just curious -- what are you guys doing that you have to dump memory so often? --bbHi 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,Here is the code that I use: import std.stdio; import std.ctype; void debug_dump(ubyte[] data) { uint len = data.length; writefln("=== GOT %d BYTES:", len); for(uint offset = 0; offset < len; offset += 20) { uint end = offset + 20; if (end > len) end = len; for(uint ix = offset; ix < end; ++ix) { writef("%02X ", data[ix]); } if (offset + 20 > len) { char[] space = new char[3 * (offset + 20 - len)]; space[] = ' '; writef(space); } writef("| "); for(uint ix = offset; ix < end; ++ix) { if (isprint(data[ix])) { writef("%s", cast(char) data[ix]); } else { writef("."); } } writefln(); } writefln(); }
Mar 15 2007