/ Check-in [1070918e]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Update the "showdb" debug utility to handle 64K pages and with extra options to decode the freelist structure.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1070918e3b68c0ba5bfab11a97214b87c601f93c
User & Date: drh 2010-08-23 15:26:50
Original Comment: Update the "showdb" debug utility to handle 64K page database and with extra options to decode the freelist structure.
Context
2010-08-23
15:41
Fix for ticket [5e10420e8d]. check-in: 255f1eef user: dan tags: trunk
15:26
Update the "showdb" debug utility to handle 64K pages and with extra options to decode the freelist structure. check-in: 1070918e user: drh tags: trunk
01:25
Version 3.7.1 check-in: 3613b069 user: drh tags: trunk, release
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to tool/showdb.c.

    30     30       v = (v<<7) + (z[i]&0x7f);
    31     31       if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
    32     32     }
    33     33     v = (v<<8) + (z[i]&0xff);
    34     34     *pVal = v;
    35     35     return 9;
    36     36   }
           37  +
           38  +/*
           39  +** Extract a big-endian 32-bit integer
           40  +*/
           41  +static unsigned int decodeInt32(const unsigned char *z){
           42  +  return (z[0]<<24) + (z[1]<<16) + (z[2]<<8) + z[3];
           43  +}
    37     44   
    38     45   /* Report an out-of-memory error and die.
    39     46   */
    40     47   static void out_of_memory(void){
    41     48     fprintf(stderr,"Out of memory...\n");
    42     49     exit(1);
    43     50   }
................................................................................
   241    248       int cofst = iCellPtr + i*2;
   242    249       char *zDesc;
   243    250       cofst = a[cofst]*256 + a[cofst+1];
   244    251       describeCell(a[0], &a[cofst-hdrSize], &zDesc);
   245    252       printf(" %03x: cell[%d] %s\n", cofst, i, zDesc);
   246    253     }
   247    254   }
          255  +
          256  +/*
          257  +** Decode a freelist trunk page.
          258  +*/
          259  +static void decode_trunk_page(
          260  +  int pgno,             /* The page number */
          261  +  int pagesize,         /* Size of each page */
          262  +  int detail,           /* Show leaf pages if true */
          263  +  int recursive         /* Follow the trunk change if true */
          264  +){
          265  +  int n, i, k;
          266  +  unsigned char *a;
          267  +  while( pgno>0 ){
          268  +    a = getContent((pgno-1)*pagesize, pagesize);
          269  +    printf("Decode of freelist trunk page %d:\n", pgno);
          270  +    print_decode_line(a, 0, 4, "Next freelist trunk page");
          271  +    print_decode_line(a, 4, 4, "Number of entries on this page");
          272  +    if( detail ){
          273  +      n = (int)decodeInt32(&a[4]);
          274  +      for(i=0; i<n; i++){
          275  +        unsigned int x = decodeInt32(&a[8+4*i]);
          276  +        char zIdx[10];
          277  +        sprintf(zIdx, "[%d]", i);
          278  +        printf("  %5s %7u", zIdx, x);
          279  +        if( i%5==4 ) printf("\n");
          280  +      }
          281  +      if( i%5!=0 ) printf("\n");
          282  +    }
          283  +    if( !recursive ){
          284  +      pgno = 0;
          285  +    }else{
          286  +      pgno = (int)decodeInt32(&a[0]);
          287  +    }
          288  +    free(a);
          289  +  }
          290  +}
          291  +
          292  +/*
          293  +** Print a usage comment
          294  +*/
          295  +static void usage(const char *argv0){
          296  +  fprintf(stderr, "Usage %s FILENAME ?args...?\n\n", argv0);
          297  +  fprintf(stderr,
          298  +    "args:\n"
          299  +    "    dbheader        Show database header\n"
          300  +    "    NNN..MMM        Show hex of pages NNN through MMM\n"
          301  +    "    NNN..end        Show hex of pages NNN through end of file\n"
          302  +    "    NNNb            Decode btree page NNN\n"
          303  +    "    NNNt            Decode freelist trunk page NNN\n"
          304  +    "    NNNtd           Show leave freelist pages on the decode\n"
          305  +    "    NNNtr           Recurisvely decode freelist starting at NNN\n"
          306  +  );
          307  +}
   248    308   
   249    309   int main(int argc, char **argv){
   250    310     struct stat sbuf;
   251    311     unsigned char zPgSz[2];
   252    312     if( argc<2 ){
   253         -    fprintf(stderr,"Usage: %s FILENAME ?PAGE? ...\n", argv[0]);
          313  +    usage(argv[0]);
   254    314       exit(1);
   255    315     }
   256    316     db = open(argv[1], O_RDONLY);
   257    317     if( db<0 ){
   258    318       fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]);
   259    319       exit(1);
   260    320     }
   261    321     zPgSz[0] = 0;
   262    322     zPgSz[1] = 0;
   263    323     lseek(db, 16, SEEK_SET);
   264    324     read(db, zPgSz, 2);
   265         -  pagesize = zPgSz[0]*256 + zPgSz[1];
          325  +  pagesize = zPgSz[0]*256 + zPgSz[1]*65536;
   266    326     if( pagesize==0 ) pagesize = 1024;
   267    327     printf("Pagesize: %d\n", pagesize);
   268    328     fstat(db, &sbuf);
   269    329     mxPage = sbuf.st_size/pagesize;
   270    330     printf("Available pages: 1..%d\n", mxPage);
   271    331     if( argc==2 ){
   272    332       int i;
................................................................................
   300    360             ofst = (iStart-1)*pagesize;
   301    361             nByte = pagesize;
   302    362           }
   303    363           a = getContent(ofst, nByte);
   304    364           decode_btree_page(a, iStart, hdrSize);
   305    365           free(a);
   306    366           continue;
          367  +      }else if( zLeft && zLeft[0]=='t' ){
          368  +        unsigned char *a;
          369  +        int detail = 0;
          370  +        int recursive = 0;
          371  +        int i;
          372  +        for(i=1; zLeft[i]; i++){
          373  +          if( zLeft[i]=='r' ) recursive = 1;
          374  +          if( zLeft[i]=='d' ) detail = 1;
          375  +        }
          376  +        decode_trunk_page(iStart, pagesize, detail, recursive);
          377  +        continue;
   307    378         }else{
   308    379           iEnd = iStart;
   309    380         }
   310    381         if( iStart<1 || iEnd<iStart || iEnd>mxPage ){
   311    382           fprintf(stderr,
   312    383             "Page argument should be LOWER?..UPPER?.  Range 1 to %d\n",
   313    384             mxPage);