디버깅 : Hex Dump

어떤 파일을 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, “%s\n”, 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;
}

Linux에 게시됨. Leave a Comment »

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중

%d 블로거가 이것을 좋아합니다: