 <p>A hex dump for Android, should be suitable for other platforms as well.</p> <p><code>LOGD()</code>, same as <code>DLOG()</code>, plays the role of <code>printf()</code> because <code>printf()</code> does not work in Android. For platforms other than Android, you may <code>#define DLOG printf</code>.</p> <p><em>dlog.h:</em></p> <pre><code>// Android logging #include &lt;android/log.h&gt; #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , "~~~~~~", __VA_ARGS__) #define DLOG(...) __android_log_print(ANDROID_LOG_DEBUG , "~~~~~~", __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , "~~~~~~", __VA_ARGS__) #define ELOG(...) __android_log_print(ANDROID_LOG_ERROR , "~~~~~~", __VA_ARGS__) #ifdef __cplusplus extern "C" { #endif void log_dump(const void*addr,int len,int linelen); void log_dumpf(const char*fmt,const void*addr,int len,int linelen); #ifdef __cplusplus } #endif </code></pre> <p><em>dump.cpp:</em></p> <pre><code>#include &lt;dlog.h&gt; //#include &lt;alloca.h&gt; inline char hdigit(int n){return "0123456789abcdef"[n&amp;0xf];}; #define LEN_LIMIT 8 #define SUBSTITUTE_CHAR '`' static const char* dumpline(char*dest, int linelen, const char*src, const char*srcend) { if(src&gt;=srcend) { return 0; } int i; unsigned long s = (unsigned long)src; for(i=0; i&lt;8; i++) { dest[i] = hdigit(s&gt;&gt;(28-i*4)); } dest[8] = ' '; dest += 9; for(i=0; i&lt;linelen/4 ; i++) { if(src+i&lt;srcend) { dest[i*3] = hdigit(src[i]&gt;&gt;4); dest[i*3+1] = hdigit(src[i]); dest[i*3+2] = ' '; dest[linelen/4*3+i] = src[i] &gt;= ' ' &amp;&amp; src[i] &lt; 0x7f ? src[i] : SUBSTITUTE_CHAR; }else{ dest[i*3] = dest[i*3+1] = dest[i*3+2] = dest[linelen/4*3+i] = ' '; } } return src+i; } void log_dumpf(const char*fmt,const void*addr,int len,int linelen) { #if LEN_LIMIT if(len&gt;linelen*LEN_LIMIT) { len=linelen*LEN_LIMIT; } #endif linelen *= 4; static char _buf[4096]; char*buf = _buf;//(char*)alloca(linelen+1); // alloca() causes the initialization to fail!!!! buf[linelen]=0; const char*start = (char*)addr; const char*cur = start; const char*end = start+len; while(!!(cur = dumpline(buf,linelen,cur,start+len))){DLOG(fmt,buf);} } void log_dump(const void*addr,int len,int linelen) { log_dumpf("%s\n",addr,len,linelen); } </code></pre> <p>Usage example:</p> <pre><code>log_dumpf("args: %s\n", &amp;p, 0x20, 0x10); </code></pre> <p>Output:</p> <pre><code>args: 61efadc4 00 3c 17 01 6d bc 59 61 02 00 00 00 80 ae ef 61 `&lt;``m`Ya```````a args: 61efadd4 00 3c 17 01 00 00 00 00 31 a5 59 61 80 ae ef 61 `&lt;``````1`Ya```a </code></pre> <p><strong>UPDATE:</strong> see <a href="https://github.com/18446744073709551615/reDroid/blob/master/jni/reDroid/dump.cpp" rel="nofollow">dump.cpp</a> and <a href="https://github.com/18446744073709551615/reDroid/blob/master/jni/re_dump.h" rel="nofollow">re_dump.h</a> in <a href="https://github.com/18446744073709551615/reDroid/tree/master/jni" rel="nofollow">reDroid (github)</a>, it includes a recursive dump that checks if a pointer is valid.</p>