We need debug a C++ file, which read and analyze a binary file. We use gdb and xxd in this case. In tmux, split a window horizontally, run gdb in the upper bigger pane, and list file content in lower smaller pane.
$ tmux new -s basic
A-f,- // split window, I define <prefix> of tmux as A-f in ~/.tmux.conf: set -g prefix M-f
A-f,JJ // make upper pane larger
$ xxd -l 33 <input-binary-file>.dat // print first 32 bytes of this file
0000000: 202a 463b 862e d108 2100 ab55 8006 f407 *F;....!..U....
0000010: 0000 0000 0a0e 0401 0102 1800 5201 0501 ............R...
0000020: 15
A-f,k // jump to upper window
$ cat readfile.cc
#include <fstream>
#include <iterator>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef unsigned char BYTE;
BYTE *read_section(FILE *istream, int *length);
int main() {
string filename = "/home/chad/docs/eclipsews/MrParser/doc/ns-output/1296_2014_04_25_10_00_MR.dat";
char *fn = const_cast<char*>(filename.c_str());
FILE *rstream = fopen(fn, "rb"); // 打开.dat文件
BYTE *buffer = NULL;
int length = 0;
buffer = read_section(rstream, &length);
fclose(rstream);
printf("Read file length: %d\n", length);
return 0;
}
BYTE *read_section(FILE *istream, int *length) {
int count = 0;
size_t ret = 0;
BYTE buf[128];
BYTE *buffer = NULL;
ret = fread(buf, sizeof(char), 8, istream); if (8 != ret) return NULL;
ret = fread(buf, sizeof(char), 2, istream); if (2 != ret) return NULL;
*length = buf[1] * 256 + buf[0];
if ( 0 == *length) return NULL;
buffer = new BYTE[*length];
fseek(istream, -10, SEEK_CUR);
ret = fread(buffer, sizeof(char), *length, istream);
if (*length != ret) {
delete [] buffer;
return NULL;
}
return buffer;
}
$ g++ -g readfile.cc -o rr
$ gdb rr
l
// list source code, we want to probe the content of variable "buffer" after the "fread" operation. So we add a breakpoint after that line
b 37
r
(gdb) p/x *buffer@33
$1 = {0x20, 0x2a, 0x46, 0x3b, 0x86, 0x2e, 0xd1, 0x8, 0x21, 0x0, 0xab, 0x55, 0x80, 0x6, 0xf4, 0x7, 0x0, 0x0, 0x0, 0x0, 0xa, 0xe, 0x4, 0x1, 0x1,
0x2, 0x18, 0x0, 0x52, 0x1, 0x5, 0x1, 0x15}
p/x buffer[0]
$2 = 0x20
c
q
where l=list, r=run, p/x means "print value in hex format", c=continue, q=quit. You can see the bytes of "buffer" is exactly the same with the output of xxd command: 0x20, 0x2a, ..., 0x15.
The format of gdb's print see 8.4 Output formats for details.