blob: 03e0fc460c5470fb0a0d8bb5318489e06e7d3994 [file] [log] [blame]
drh666fb692017-10-30 23:25:06 +00001/*
2** A utility for printing content from the wal-index or "shm" file.
3*/
4#include <stdio.h>
5#include <ctype.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8#include <fcntl.h>
9#include <assert.h>
10
11#define ISDIGIT(X) isdigit((unsigned char)(X))
12#define ISPRINT(X) isprint((unsigned char)(X))
13
14#if !defined(_MSC_VER)
15#include <unistd.h>
16#include <sys/types.h>
17#else
18#include <io.h>
19#endif
20
21#include <stdlib.h>
22#include <string.h>
23
24static int fd = -1; /* The open SHM file */
25
26/* Report an out-of-memory error and die.
27*/
28static void out_of_memory(void){
29 fprintf(stderr,"Out of memory...\n");
30 exit(1);
31}
32
33/*
34** Read content from the file.
35**
36** Space to hold the content is obtained from malloc() and needs to be
37** freed by the caller.
38*/
39static unsigned char *getContent(int ofst, int nByte){
40 unsigned char *aData;
41 aData = malloc(nByte);
42 if( aData==0 ) out_of_memory();
43 lseek(fd, ofst, SEEK_SET);
44 read(fd, aData, nByte);
45 return aData;
46}
47
48/*
49** Flags values
50*/
51#define FG_HEX 1 /* Show as hex */
52#define FG_NBO 2 /* Native byte order */
53#define FG_PGSZ 4 /* Show as page-size */
54
55/* Print a line of decode output showing a 4-byte integer.
56*/
57static void print_decode_line(
58 unsigned char *aData, /* Content being decoded */
59 int ofst, int nByte, /* Start and size of decode */
60 unsigned flg, /* Display flags */
61 const char *zMsg /* Message to append */
62){
63 int i, j;
64 int val = aData[ofst];
65 char zBuf[100];
66 sprintf(zBuf, " %03x: %02x", ofst, aData[ofst]);
67 i = (int)strlen(zBuf);
68 for(j=1; j<4; j++){
69 if( j>=nByte ){
70 sprintf(&zBuf[i], " ");
71 }else{
72 sprintf(&zBuf[i], " %02x", aData[ofst+j]);
73 val = val*256 + aData[ofst+j];
74 }
75 i += (int)strlen(&zBuf[i]);
76 }
77 if( nByte==8 ){
78 for(j=4; j<8; j++){
79 sprintf(&zBuf[i], " %02x", aData[ofst+j]);
80 i += (int)strlen(&zBuf[i]);
81 }
82 }
83 if( flg & FG_NBO ){
84 assert( nByte==4 );
85 memcpy(&val, aData+ofst, 4);
86 }
87 sprintf(&zBuf[i], " ");
88 i += 12;
89 if( flg & FG_PGSZ ){
90 unsigned short sz;
91 memcpy(&sz, aData+ofst, 2);
92 sprintf(&zBuf[i], " %9d", sz==1 ? 65536 : sz);
93 }else if( flg & FG_HEX ){
94 sprintf(&zBuf[i], " 0x%08x", val);
95 }else if( nByte<8 ){
96 sprintf(&zBuf[i], " %9d", val);
97 }
98 printf("%s %s\n", zBuf, zMsg);
99}
100
101/*
102** Print an instance of the WalIndexHdr object. ix is either 0 or 1
103** to select which header to print.
104*/
105static void print_index_hdr(unsigned char *aData, int ix){
106 int i;
107 assert( ix==0 || ix==1 );
108 i = ix ? 48 : 0;
109 print_decode_line(aData, 0+i, 4, FG_NBO, "Wal-index version");
110 print_decode_line(aData, 4+i, 4, 0, "unused padding");
111 print_decode_line(aData, 8+i, 4, FG_NBO, "transaction counter");
112 print_decode_line(aData,12+i, 1, 0, "1 when initialized");
113 print_decode_line(aData,13+i, 1, 0, "true if WAL cksums are bigendian");
114 print_decode_line(aData,14+i, 2, FG_PGSZ, "database page size");
115 print_decode_line(aData,16+i, 4, FG_NBO, "mxFrame");
116 print_decode_line(aData,20+i, 4, FG_NBO, "Size of database in pages");
117 print_decode_line(aData,24+i, 8, 0, "Cksum of last frame in -wal");
118 print_decode_line(aData,32+i, 8, 0, "Salt values from the -wal");
119 print_decode_line(aData,40+i, 8, 0, "Cksum over all prior fields");
120}
121
122/*
123** Print the WalCkptInfo object
124*/
125static void print_ckpt_info(unsigned char *aData){
126 const int i = 96;
127 int j;
128 print_decode_line(aData, 0+i, 4, FG_NBO, "nBackfill");
129 for(j=0; j<5; j++){
130 char zLabel[100];
131 sprintf(zLabel, "aReadMark[%d]", j);
132 print_decode_line(aData, 4*j+4+i, 4, FG_NBO, zLabel);
133 }
134 print_decode_line(aData,24+i, 8, 0, "aLock");
135 print_decode_line(aData,32+i, 4, FG_NBO, "nBackfillAttempted");
136 print_decode_line(aData,36+i, 4, FG_NBO, "notUsed0");
137}
138
139
140int main(int argc, char **argv){
141 unsigned char *aData;
142 if( argc<2 ){
143 fprintf(stderr,"Usage: %s FILENAME\n", argv[0]);
144 exit(1);
145 }
146 fd = open(argv[1], O_RDONLY);
147 if( fd<0 ){
148 fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]);
149 exit(1);
150 }
151 aData = getContent(0, 136);
152 print_index_hdr(aData, 0);
153 print_index_hdr(aData, 1);
154 print_ckpt_info(aData);
155 free(aData);
156 close(fd);
157 return 0;
158}