,1Berkeley DB: Debugging the LibraryIThe debug command to the dbtest utility provides assistanceFfor debugging the test suite. If you don't specify a parameter, e.g.:



Idebug causes dbtest to display a running count of the calls made into theGDB library. There is an optional argument to debug which is the numberFof the operation on which you want to stop. By using your debugger toKset a breakpoint in the function __db_loadme, you can obtain controlFof the tester immediately before a particular operation. For example:

KTo set a counter breakpoint from inside a debugger, set the global variableFdebug_test to the counter value at which you want to stop. ForJexample, you might first stop at operation 100, and then stop at operationL200 by initially setting a breakpoint in __db_loadme, issuing a debugI100 command and then setting debug_test to 200 in the debugger. (Some ofIthe trickier bugs in DB are best solved by binary search, looking for the2precise moment at which the page contents go bad.)

IIf you want to stop on each iteration, set the variable debug_stopto a non-zero value.




JThere are a number of routines to help you display page and tree contents.GThese routines live in the file ../db/db_pr.c. Some of the moreuseful ones are:





<Examples of calling these functions from gdb are as follows.




AThe __db_prpage function displays a page as specified by areference to a PAGE structure.EIn this case, cp references a CURSOR structure, which containsthe pointer to the page.



(gdb) whatis cptype = CURSOR *(gdb) whatis cp->page
type = PAGE *(gdb) print *cpG$1 = {dbc = 0x807e040, page = 0xc110400, pgno = 2, indx = 0, dpgno = 0,4  dindx = 0, lock = 0, mode = DB_LOCK_NG, flags = 0}$(gdb) print __db_prpage(cp->page, 1)page    2: (btree leaf)    lsn.file: 0 lsn.offset: 0>    prev:    0 next:    3 level:  1 entries:   28 offset:  136'    [000]  500 len:   6 data: aback0x00'    [001]  488 len:   6 data: aback0x00'    [002]  476 len:   6 data: abaft0x00'    [003]  464 len:   6 data: abaft0x00)    [004]  452 len:   8 data: abandon0x00)    [005]  440 len:   8 data: abandon0x00+    [006]  424 len:  10 data: abandoned0x00+    [007]  408 len:  10 data: abandoned0x00,    [008]  392 len:  11 data: abandoning0x00,    [009]  376 len:  11 data: abandoning0x00-    [010]  360 len:  12 data: abandonment0x00-    [011]  344 len:  12 data: abandonment0x00*    [012]  332 len:   9 data: abandons0x00*    [013]  320 len:   9 data: abandons0x00'    [014]  308 len:   6 data: abase0x00'    [015]  296 len:   6 data: abase0x00(    [016]  284 len:   7 data: abased0x00(    [017]  272 len:   7 data: abased0x00+    [018]  256 len:  10 data: abasement0x00+    [019]  240 len:  10 data: abasement0x00,    [020]  224 len:  11 data: abasements0x00,    [021]  208 len:  11 data: abasements0x00(    [022]  196 len:   7 data: abases0x00(    [023]  184 len:   7 data: abases0x00'    [024]  172 len:   6 data: abash0x00'    [025]  160 len:   6 data: abash0x00)    [026]  148 len:   8 data: abashed0x00)    [027]  136 len:   8 data: abashed0x00$2 = 0(gdb)



FThe __db_prnpage function displays any page in the database, as$specified by a page number argument.FThe dbp->mpf pointer references a DB_MPOOLFILE structure, which7is the per-process shared memory buffer pool structure.

(gdb) whatis dbp->mpftype = DB_MPOOLFILE *%(gdb) print __db_prnpage(dbp->mpf, 2)page    2: (btree leaf)    lsn.file: 0 lsn.offset: 0>    prev:    0 next:    3 level:  1 entries:   28 offset:  136'    [000]  500 len:   6 data: aback0x00'    [001]  488 len:   6 data: aback0x00'    [002]  476 len:   6 data: abaft0x00'    [003]  464 len:   6 data: abaft0x00)    [004]  452 len:   8 data: abandon0x00)    [005]  440 len:   8 data: abandon0x00+    [006]  424 len:  10 data: abandoned0x00+    [007]  408 len:  10 data: abandoned0x00,    [008]  392 len:  11 data: abandoning0x00,    [009]  376 len:  11 data: abandoning0x00-    [010]  360 len:  12 data: abandonment0x00-    [011]  344 len:  12 data: abandonment0x00*    [012]  332 len:   9 data: abandons0x00*    [013]  320 len:   9 data: abandons0x00'    [014]  308 len:   6 data: abase0x00'    [015]  296 len:   6 data: abase0x00(    [016]  284 len:   7 data: abased0x00(    [017]  272 len:   7 data: abased0x00+    [018]  256 len:  10 data: abasement0x00+    [019]  240 len:  10 data: abasement0x00,    [020]  224 len:  11 data: abasements0x00,    [021]  208 len:  11 data: abasements0x00(    [022]  196 len:   7 data: abases0x00(    [023]  184 len:   7 data: abases0x00'    [024]  172 len:   6 data: abash0x00'    [025]  160 len:   6 data: abash0x00)    [026]  148 len:   8 data: abashed0x00)    [027]  136 len:   8 data: abashed0x00$1 = 0(gdb)



BThe __db_dump function dumps the entire database to a file.EThe dbp pointer references a DB structure as might be returnedEby the db_open function. After this command has been run, theGfile /tmp/dump will have a copy of the entire database. This isEoften useful to compare all the changes in the database after runningGa single subroutine that may have split pages and/or otherwise modifiedmore than a single page.



(gdb) whatis dbptype = DB *(gdb) print *dbpG$3 = {mutexp = 0x0, type = DB_BTREE, dbenv = 0x807b000, mp_dbenv = 0x0,L  master = 0x807d000, internal = 0x807d100, mp = 0x807b080, mpf = 0x807e000,I  curs_queue = {tqh_first = 0x807e040, tqh_last = 0x807e048}, handleq = {H    lh_first = 0x807d000}, links = {le_next = 0x0, le_prev = 0x807d028},J  log_fileid = 0, txn = 0x0, locker = 0, lock_dbt = {data = 0x0, size = 0,?    ulen = 0, dlen = 0, doff = 0, flags = 0}, lock = {pgno = 0,Š    fileid = "\000\004\017\001\001 \000\a5\223ýÖ\000\000\000\000\000\000\000"}, pgsize = 512, db_malloc = 0, close = 0x804a810 ,D  cursor = 0x8064540 <__bam_cursor>, del = 0x8066554 <__bam_delete>,6  fd = 0x804aa60 , get = 0x80649b0 <__bam_get>,=  put = 0x8067b50 <__bam_put>, stat = 0x806c708 <__bam_stat>,,  sync = 0x8063f30 <__bam_sync>, flags = 80}*(gdb) print __db_dump(dbp, "/tmp/dump", 1)$4 = 0(gdb)B
reÿÿIThe debug command to the dbtest utility provides assistanceFfor debugging the test suite. If you don't specify a parameter, e.g.:



Idebug causes dbtest to display a running count of the calls made into theGDB library. There is an optional argument to debug which is the numberFof t