showshm.c 4.2 KB

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