## Debugging and Testing

We have imported the debugging system from the old test suite into the new interface to aid in debugging problems. There are several variables that are available both in gdb as globals to the C code, and variables in Tcl that the user can set. These variables are linked together so that changes in one venue are reflected in the other. The names of the variables have been modified a bit to reduce the likelihood
of namespace trampling. We have added a double underscore to all the names.

The variables are all initialized to zero (0) thus resulting in debugging being turned off. The purpose of the debugging, fundamentally, is to allow the user to set a breakpoint prior to making a DB call. This breakpoint is set in the __db_loadme() function. The user may selectively turn on various debugging areas each controlled by a separate variable (note they all have two (2) underscores prepended to the name):

- __debug_on - Turns on the debugging system. This must be on for any debugging to occur
- __debug_print - Turns on printing a debug count statement on each call
- __debug_test - Hits the breakpoint in __db_loadme on the specific iteration
- __debug_stop - Hits the breakpoint in __db_loadme on every (or the next) iteration

Note to developers: Anyone extending this interface must place a call to _debug_check() (no arguments) before every call into the DB library.

There is also a command available that will force a call to the _debug_check function.

> berkdb debug_check

For testing purposes we have added several hooks into the DB library and a small interface into the environment and/or database commands to manipulate the hooks. This command interface and the hooks and everything that goes with it is only enabled when the test option is configured into DB.

> <env> test copy location
> <db> test copy location
> <env> test abort location
> <db> test abort location

In order to test recovery we need to be able to abort the creation or deletion process at various points. Also we want to invoke a copy function to copy the database file(s) at various points as well so that we can obtain before/after snapshots of the databases. The interface provides the test command to specify a location where we wish to invoke a copy or an abort. The command is available from either the environment or the database for convenience. The location can be one of the following:

- none - Clears the location
- preopen - Sets the location prior to the __os_open call in the creation process
- postopen - Sets the location to immediately following the __os_open call in creation
- postlogmeta - Sets the location to immediately following the __db_log_page call to log the meta data in creation. Only valid for Btree.
- postlog - Sets the location to immediately following the last (or only) __db_log_page call in creation.
- postsync - Sets the location to immediately following the sync of the log page in creation.
- prerename - Sets the location prior to the __os_rename call in the deletion process.
- postrename - Sets the location to immediately following the __os_rename call in deletion

> <env> mutex mode nitems

This command creates a mutex region for testing. It sets the mode of the region to mode and sets up for nitems number of mutex entries. After we successfully get a handle to a mutex we create a command of the form $env.mutexX, where X is an integer starting at 0 (e.g. $env.mutex0, $env.mutex1, etc). We use the Tcl_CreateObjCommand() to create the top level mutex function. It is through this handle that the user can access all of the commands described below. Internally, the mutex handle is sent as the ClientData portion of the new command set so that all future mutex calls access the appropriate handle.

> <mutex> close

This command closes the mutex and renders the handle invalid. This command directly translates to the __db_r_detach function call. It returns either a 0 (for success), or it throws a Tcl error with a system message.

Additionally, since the handle is no longer valid, we will call Tcl_DeleteCommand() so that further uses of the handle will be dealt with properly by Tcl itself.

> <mutex> get id

This command locks the mutex identified by id. It returns either a 0 (for success), or it throws a Tcl error with a system message.

> <mutex> release id

This command releases the mutex identified by id. It returns either a 0 (for success), or it throws a Tcl error with a system message.

> <mutex> getval id

This command gets the value stored for the mutex identified by id. It returns either the value, or it throws a Tcl error with a system message.

> <mutex> setval id val

This command sets the value stored for the mutex identified by id to val. It returns either a 0 (for success), or it throws a Tcl error with a system message.