Debugging Your Btrieve Application
This chapter provides information that may be helpful in debugging your Btrieve application. It contains the following sections:
Trace Files
The MicroKernel's Trace Operations configuration option allows you to trace each Btrieve API call and save the results to a file. This is helpful in debugging applications. The following shows a sample trace file.
MicroKernel Trace File of a BUTIL STAT Call
MicroKernel Database Engine [Server Edition] for Windows NT trace file
Created : Wed Dec 17 18:19:09
<In> 0198 Opcode : 0026 Crs ID : 0xffffffff Db Length : 00005 Keynum :
ff Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: 00 00 00 00 00 - .....
KBuf: ?? - .
<Out>0198 Status : 0000 Crs ID : 0xffffffff Db Length : 00005 Keynum :
ff Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: 07 00 00 00 54 - ....T
KBuf: ?? - .
--------------------------------------------------------------------
<In> 0199 Opcode : 0000 Crs ID : 0xffffffff Db Length : 00001 Keynum :
fe Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: 4e 4f 54 53 48 4f 57 4e - 00 NOTSHOWN.
KBuf: 5c 5c 4e 54 34 53 52 56 - 2d 4a 55 44 49 54 5c 43 \\NT4SRV-JUDIT\C
24 5c 64 65 6d 6f 64 61 - 74 61 5c 74 75 69 74 69 $\demodata\tuiti
<Out>0199 Status : 0000 Crs ID : 0x00000002 Db Length : 00001 Keynum :
fe Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: 4e 4f 54 53 48 4f 57 4e - 00 NOTSHOWN.
KBuf: 5c 5c 4e 54 34 53 52 56 - 2d 4a 55 44 49 54 5c 43 \\NT4SRV-JUDIT\C
24 5c 64 65 6d 6f 64 61 - 74 61 5c 74 75 69 74 69 $\demodata\tuiti
--------------------------------------------------------------------
<In> 0200 Opcode : 0015 Crs ID : 0x00000002 Db Length : 00028 Keynum :
fe Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: 00 00 00 00 00 01 07 00 - 00 00 00 00 00 00 00 03 ................
c3 3f 00 10 00 00 00 00 - b4 fe 36 03 .?........6.
KBuf: 00 00 00 00 1c 00 00 00 - da fe 36 03 00 00 00 00 .........6.....
00 01 07 00 00 00 00 00 - 00 00 00 03 c3 3f 00 10.............?..
<Out>0200 Status : 0000 Crs ID : 0x00000002 Db Length : 00007 Keynum :
fe Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: 03 00 0e 00 04 05 01 - .......
KBuf: 00 00 00 00 07 00 00 00 - da fe 36 03 03 00 0e 00 ..........6.....
04 05 01 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
--------------------------------------------------------------------
<In> 0201 Opcode : 0015 Crs ID : 0x00000002 Db Length : 33455 Keynum : ff Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: 2b 00 cb ff ff ff ff ff - ff ff ff ff ff ff ff 00 +...............
00 0e 00 04 05 01 00 00 - 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 - 00 00 00 14 4e 54 34 53 ............NT4S
52 56 2d 4a 55 44 49 54 - 5c 75 6e 6b 6e 6f 77 6e RV-JUDIT\unknown
KBuf: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
<Out>0201 Status : 0000 Crs ID : 0x00000002 Db Length : 00064 Keynum :
ff Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: 0e 00 00 10 03 70 08 00 - 00 00 01 12 00 00 00 00 .....p..........
01 00 04 00 00 01 08 00 - 00 00 0f 00 00 00 00 00 ................
05 00 05 00 03 05 04 00 - 00 00 0a 00 00 00 01 00 ................
0a 00 01 00 03 01 02 00 - 00 00 00 00 00 00 02 00 ................
KBuf: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
--------------------------------------------------------------------
<In> 0202 Opcode : 0065 Crs ID : 0x00000002 Db Length : 00268 Keynum :
00 Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: 45 78 53 74 01 00 00 00 - 00 00 00 00 01 00 00 00 ExSt............
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 ................
KBuf: ?? - .
<Out>0202 Status : 0000 Crs ID : 0x00000002 Db Length : 00035 Keynum :
00 Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: 01 00 00 00 01 00 00 00 - 17 00 00 00 43 3a 5c 44 ............C:\D
45 4d 4f 44 41 54 41 5c - 54 55 49 54 49 4f 4e 2e EMODATA\TUITION.
4d 4b 44 - MKD
KBuf: ?? - .
--------------------------------------------------------------------
<In> 0203 Opcode : 0065 Crs ID : 0x00000002 Db Length : 00008 Keynum :
00 Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: 45 78 53 74 02 00 00 00 - ExSt....
KBuf: ?? - .
<Out>0203 Status : 0000 Crs ID : 0x00000002 Db Length : 00008 Keynum :
00 Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: 00 00 01 00 00 00 07 00 - ........
KBuf: ?? - .
--------------------------------------------------------------------
<In> 0204 Opcode : 0001 Crs ID : 0x00000002 Db Length : 00000 Keynum :
00 Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: ?? - .
KBuf: ?? - .
<Out>0204 Status : 0000 Crs ID : 0x00000000 Db Length : 00000 Keynum :
00 Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: ?? - .
KBuf: ?? - .
---------------------------------------------------------------------
<In> 0205 Opcode : 0028 Crs ID : 0xffbc000c Db Length : 00000 Keynum :
00 Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: -
KBuf: -
<Out>0205 Status : 0000 Crs ID : 0xffbc000c Db Length : 00000 Keynum :
00 Clnt ID : 00 00 00 00 00 00 00 00 00 00 85 00 50 55 00 00
DBuf: -
KBuf: -
--------------------------------------------------------------------
Each operation shows values passed in to and returned by the MicroKernel. Input values are marked by <In> and output values are marked by <Out>; each is followed by a number that indicates the sequence in which the operations were processed, so that <Out> 0016 is the result of <In> 0016. The Opcode field shows the operation code performed; the Status field shows the returned status code.
Crs ID is the cursor ID, or handle, that the MicroKernel assigned to the request. This information can be helpful in debugging applications that support multiple clients or that support single clients with multiple cursors.
Db Length reflects the Data Buffer Length. Keynum reflects the Key Number. Clnt ID reflects the Client ID parameter used by the BTRVID and BTRCALLID functions. DBuf reflects the Data Buffer contents. KBuf reflects the Key Buffer contents. The trace file truncates the Data Buffer and Key Buffer contents, depending on the MicroKernel configuration.
Note: To avoid a degradation in performance, only turn the Trace File setting on for short periods of time so that you can determine what operations are being handled by the MicroKernel.
Indirect Chunk Operations in Client-Server Environments
When attempting a Get Direct/Chunk (23) operation, your application may receive a status code 62. You may find that your application is specifying the Indirect Random Descriptor option (Subfunction 0x80000001), but with tracing enabled, you can see that the MicroKernel is actually receiving a Direct Random Descriptor option (Subfunction 0x80000000).
The indirect chunk option allows an application to specify a pointer to a data address in the application's memory block where the data should be stored after it is retrieved, rather than having the data returned in the actual Data Buffer parameter of the Btrieve call. However, since the application is running in an environment in which the MicroKernel does not have direct access to the application's memory, the Btrieve client Requester must convert indirect chunk requests into direct chunk requests before sending the request to the MicroKernel.
All applications always use interprocess communication (IPC) to communicate between the application and the MicroKernel. Since IPC is required, the MicroKernel has no access to the application's memory, so the client Requester must allocate a single contiguous block of memory and adjust all data pointers to point into that memory block. On return from the MicroKernel, the Requester converts the Data Buffer back into the appropriate format for the indirect option and moves the returned data chunk into the designated, indirect address in the application's memory block.
Engine Shutdowns and Connection Resets
If you are developing a multithreaded console application targeting either Windows 9x or Windows NT, you must set up a control handler routine to handle a potential Ctrl-C keystroke. In this control handler routine, you must clean up all of your Btrieve clients by issuing either a Reset (28) or Stop (25) operation. The cleanup process must complete before your application passes the Ctrl-C event on to the operating system.
If your application still has active clients when the system terminates the threads, the MicroKernel cannot clean up its connection with the application and is forced to allocate more system resources. This causes performance degradation and significantly increases the time needed for the engine to shut down. For more information about control handler routines, see the Microsoft documentation.
Reducing Wasted Space in Files
The MicroKernel allocates disk space as needed. If there is not enough room in the file when your application inserts new records, the MicroKernel dynamically allocates additional data and index pages to the file. The size of each allocated page is the same as the page size with which the file was created. The MicroKernel also updates directory structures to reflect the new file size.
Once the MicroKernel allocates space to a file, that space remains allocated as long as the file exists.
To reduce the space required for a file from which numerous records have been deleted, you can use the Maintenance utility as follows
1. Create a new file with the same characteristics as the original file.
In the interactive Maintenance utility, the commands are Open and Create As from the File menu. In the command-line based Maintenance utility, the command is CLONE.
2. Insert records into the new file using one of the following methods:
• Write a small application that reads the records from the original file and inserts them into the new file.
• In the command-line Maintenance utility, use the SAVE command and then the LOAD command. Alternatively, you can use the COPY command.
• In the interactive Maintenance utility, use the Save command and then the Load command from the Data menu. Alternatively, you can use the Copy command from the Data menu.
3. Rename the new file and then delete the original file from the disk.