티스토리 뷰

Application/Debug

디버깅 : Hex Dump

알 수 없는 사용자 2006. 6. 5. 11:00
어떤 파일을 hex dump 하고 싶을 때가 있습니다.

octal dump program인데 초기에는 8진수로만 제공되던 것이 hex 값도 출력할 수 있는 option을 지니게 되었지요.

가장 흔히 사용하는 방법은

od -tx1

입니다. type을 hex 로 하되 1 byte 씩 끊어서 출력하라는 것입니다.

1 을 여러가지로 바꾸어 시도해보세요.

이제 실시간 중에 memory 일부를 hex dump하고 싶을 때가 있는데,

사용하던 hex dump function을 소개하려고, 며칠간 틈틈이 수정하였습니다.

아래 소스를 보면 GL, GR 이런 말들이 나오는데, 이것은 charset을 정의할때

사용되는 말입니다. ksc5601 GR GL 등으로 검색해보세요.

보통 hexdump 옆에 print 된 내용을 덧붙이는데, 정말 전통적인 format입니다.

문제는 CL, CR 영역 (control code)에 있는 것을 잘 처리 해야하는 것과, 한글에 대한 것입니다. 나중에 더 소개할 일이 있겠지요...








코드:
#include
#includestatic int is_GR(unsigned char x) { return (x > 0xa0) && ( x < 0xff ); }
static int is_GL(unsigned char x) { return (x > 0x20) && ( x < 0x7f ); }
#define is_GRAPH(x) (is_GR(x) || is_GL(x))
#define HEXDUMP_BUFSIZE 512static void _hexdump( int page, const char * msg, const char * _src, int len )
{
static char print_chars[HEXDUMP_BUFSIZE+1];
static char text[5*HEXDUMP_BUFSIZE+1];
int textlength = 0;static char line[8+3*16+16+1]; /*pid, hex, charaters, null */
char * source = ( char * ) _src;
char * p = print_chars;
char * q;
char * print_chunk_end;
char * source_chunk_end;
int expectGR = 0;

memset( text, '-', 73 );
if( page == 0 )
{
textlength = sprintf( text, "(%-5d) [%p] %s ", getpid(), _src, msg );
}

while( textlength < 72 ) { text[textlength++] = '-'; }
text[textlength++] = 'n';
text[textlength] = ';

/*
// Character print rule (Google에서 KSC5601 GR GL 로 찾음)
// 1. 독립된 GL
// 2. 연이은 두개의 GR
// 그외의 것들은 모두 '.' 으로 표현함.
*/
memcpy( print_chars, source, len );
while( p < print_chars+len )
{
if( is_GR(*p) ) { expectGR = !expectGR; }
else
{
if( expectGR ) { *(p-1) = '.'; }
if( !is_GL(*p) ) { *p = '.'; }
expectGR = 0;
}
p++;
}
p = source_chunk_end = source;
q = print_chunk_end = print_chars;
while( p < source+len )
{
char * l = line + 8; /* after pid. */
memset( line, ' ', sizeof line );
line[sizeof line -1] = 0;
line[sprintf( line, "[%05x]", page*HEXDUMP_BUFSIZE + p-source)] = ' '; /* erase null character. */

/* Print hex data */
source_chunk_end += 16;
while( p < source+len && p < source_chunk_end )
{
l += sprintf( l, "%02X ", (unsigned char) *p );
p++;
}

/* Print printable charaters */
l = line + 8 + 3*16; /* after hex. */
print_chunk_end += 16;
while( q < print_chars+len && q < print_chunk_end )
{
*l++ = *q++;
}

line[8 + 7*3+2] = '-'; /* at the middle of hex */
line[sizeof line - 1] = 0;
textlength += sprintf( text+textlength, "%sn", line );
}
fputs( text, stderr );
}

/* void * _src can accept any types of pointer */
void hexdump( const char * msg, const void * _src, int len )
{
char * source = (char *) _src; /* make the pointing size as 1 byte. */
int chunk_count=0;
for( chunk_count = 0; chunk_count < len / HEXDUMP_BUFSIZE + 1; chunk_count ++ )
{
int chunk_length = HEXDUMP_BUFSIZE;
if( chunk_count == len / HEXDUMP_BUFSIZE )
{
chunk_length =len - chunk_count*HEXDUMP_BUFSIZE;
}
_hexdump( chunk_count, msg, source + chunk_count*HEXDUMP_BUFSIZE , chunk_length );
}
printf("n");
}

int main()
{
hexdump( "main function dump", main, 1028 );
return 0;
}