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