summaryrefslogtreecommitdiffstats
path: root/tool/showshm.c
blob: 03e0fc460c5470fb0a0d8bb5318489e06e7d3994 (plain)
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;
}