SQLite

Check-in [1070918e3b]
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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1070918e3b68c0ba5bfab11a97214b87c601f93c
User & Date: drh 2010-08-23 15:26:50.000
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: 255f1eefa3 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: 1070918e3b user: drh tags: trunk)
01:25
Version 3.7.1 (check-in: 3613b0695a user: drh tags: trunk, release)
Changes
Unified Diff Ignore Whitespace Patch
Changes to tool/showdb.c.
30
31
32
33
34
35
36







37
38
39
40
41
42
43
    v = (v<<7) + (z[i]&0x7f);
    if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
  }
  v = (v<<8) + (z[i]&0xff);
  *pVal = v;
  return 9;
}








/* Report an out-of-memory error and die.
*/
static void out_of_memory(void){
  fprintf(stderr,"Out of memory...\n");
  exit(1);
}







>
>
>
>
>
>
>







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    v = (v<<7) + (z[i]&0x7f);
    if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
  }
  v = (v<<8) + (z[i]&0xff);
  *pVal = v;
  return 9;
}

/*
** Extract a big-endian 32-bit integer
*/
static unsigned int decodeInt32(const unsigned char *z){
  return (z[0]<<24) + (z[1]<<16) + (z[2]<<8) + z[3];
}

/* Report an out-of-memory error and die.
*/
static void out_of_memory(void){
  fprintf(stderr,"Out of memory...\n");
  exit(1);
}
241
242
243
244
245
246
247
248





















































249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
    int cofst = iCellPtr + i*2;
    char *zDesc;
    cofst = a[cofst]*256 + a[cofst+1];
    describeCell(a[0], &a[cofst-hdrSize], &zDesc);
    printf(" %03x: cell[%d] %s\n", cofst, i, zDesc);
  }
}






















































int main(int argc, char **argv){
  struct stat sbuf;
  unsigned char zPgSz[2];
  if( argc<2 ){
    fprintf(stderr,"Usage: %s FILENAME ?PAGE? ...\n", argv[0]);
    exit(1);
  }
  db = open(argv[1], O_RDONLY);
  if( db<0 ){
    fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]);
    exit(1);
  }
  zPgSz[0] = 0;
  zPgSz[1] = 0;
  lseek(db, 16, SEEK_SET);
  read(db, zPgSz, 2);
  pagesize = zPgSz[0]*256 + zPgSz[1];
  if( pagesize==0 ) pagesize = 1024;
  printf("Pagesize: %d\n", pagesize);
  fstat(db, &sbuf);
  mxPage = sbuf.st_size/pagesize;
  printf("Available pages: 1..%d\n", mxPage);
  if( argc==2 ){
    int i;








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




|











|







248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
    int cofst = iCellPtr + i*2;
    char *zDesc;
    cofst = a[cofst]*256 + a[cofst+1];
    describeCell(a[0], &a[cofst-hdrSize], &zDesc);
    printf(" %03x: cell[%d] %s\n", cofst, i, zDesc);
  }
}

/*
** Decode a freelist trunk page.
*/
static void decode_trunk_page(
  int pgno,             /* The page number */
  int pagesize,         /* Size of each page */
  int detail,           /* Show leaf pages if true */
  int recursive         /* Follow the trunk change if true */
){
  int n, i, k;
  unsigned char *a;
  while( pgno>0 ){
    a = getContent((pgno-1)*pagesize, pagesize);
    printf("Decode of freelist trunk page %d:\n", pgno);
    print_decode_line(a, 0, 4, "Next freelist trunk page");
    print_decode_line(a, 4, 4, "Number of entries on this page");
    if( detail ){
      n = (int)decodeInt32(&a[4]);
      for(i=0; i<n; i++){
        unsigned int x = decodeInt32(&a[8+4*i]);
        char zIdx[10];
        sprintf(zIdx, "[%d]", i);
        printf("  %5s %7u", zIdx, x);
        if( i%5==4 ) printf("\n");
      }
      if( i%5!=0 ) printf("\n");
    }
    if( !recursive ){
      pgno = 0;
    }else{
      pgno = (int)decodeInt32(&a[0]);
    }
    free(a);
  }
}

/*
** Print a usage comment
*/
static void usage(const char *argv0){
  fprintf(stderr, "Usage %s FILENAME ?args...?\n\n", argv0);
  fprintf(stderr,
    "args:\n"
    "    dbheader        Show database header\n"
    "    NNN..MMM        Show hex of pages NNN through MMM\n"
    "    NNN..end        Show hex of pages NNN through end of file\n"
    "    NNNb            Decode btree page NNN\n"
    "    NNNt            Decode freelist trunk page NNN\n"
    "    NNNtd           Show leave freelist pages on the decode\n"
    "    NNNtr           Recurisvely decode freelist starting at NNN\n"
  );
}

int main(int argc, char **argv){
  struct stat sbuf;
  unsigned char zPgSz[2];
  if( argc<2 ){
    usage(argv[0]);
    exit(1);
  }
  db = open(argv[1], O_RDONLY);
  if( db<0 ){
    fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]);
    exit(1);
  }
  zPgSz[0] = 0;
  zPgSz[1] = 0;
  lseek(db, 16, SEEK_SET);
  read(db, zPgSz, 2);
  pagesize = zPgSz[0]*256 + zPgSz[1]*65536;
  if( pagesize==0 ) pagesize = 1024;
  printf("Pagesize: %d\n", pagesize);
  fstat(db, &sbuf);
  mxPage = sbuf.st_size/pagesize;
  printf("Available pages: 1..%d\n", mxPage);
  if( argc==2 ){
    int i;
300
301
302
303
304
305
306











307
308
309
310
311
312
313
          ofst = (iStart-1)*pagesize;
          nByte = pagesize;
        }
        a = getContent(ofst, nByte);
        decode_btree_page(a, iStart, hdrSize);
        free(a);
        continue;











      }else{
        iEnd = iStart;
      }
      if( iStart<1 || iEnd<iStart || iEnd>mxPage ){
        fprintf(stderr,
          "Page argument should be LOWER?..UPPER?.  Range 1 to %d\n",
          mxPage);







>
>
>
>
>
>
>
>
>
>
>







360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
          ofst = (iStart-1)*pagesize;
          nByte = pagesize;
        }
        a = getContent(ofst, nByte);
        decode_btree_page(a, iStart, hdrSize);
        free(a);
        continue;
      }else if( zLeft && zLeft[0]=='t' ){
        unsigned char *a;
        int detail = 0;
        int recursive = 0;
        int i;
        for(i=1; zLeft[i]; i++){
          if( zLeft[i]=='r' ) recursive = 1;
          if( zLeft[i]=='d' ) detail = 1;
        }
        decode_trunk_page(iStart, pagesize, detail, recursive);
        continue;
      }else{
        iEnd = iStart;
      }
      if( iStart<1 || iEnd<iStart || iEnd>mxPage ){
        fprintf(stderr,
          "Page argument should be LOWER?..UPPER?.  Range 1 to %d\n",
          mxPage);