xref: /sqlite-3.40.0/tool/showshm.c (revision 666fb691)
1 /*
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 
24 static int fd = -1;             /* The open SHM file */
25 
26 /* Report an out-of-memory error and die.
27 */
out_of_memory(void)28 static 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 */
getContent(int ofst,int nByte)39 static 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 */
print_decode_line(unsigned char * aData,int ofst,int nByte,unsigned flg,const char * zMsg)57 static 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 */
print_index_hdr(unsigned char * aData,int ix)105 static 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 */
print_ckpt_info(unsigned char * aData)125 static 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 
main(int argc,char ** argv)140 int 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 }
159