4. Viewing and Navigating To Code
5. Controlling Program Execution
6. Setting Breakpoints and Traces
8. Evaluating and Displaying Data
Capabilities of Runtime Checking
Turning On Memory Use and Memory Leak Checking
Turning On Memory Access Checking
Understanding the Memory Access Error Report
Understanding the Memory Leak Report
Limiting the Number of Errors Reported
Using Suppression to Manage Errors
Using Runtime Checking on a Child Process
Using Runtime Checking on an Attached Process
Using Fix and Continue With Runtime Checking
Runtime Checking Application Programming Interface
Using Runtime Checking in Batch Mode
Enabling Batch Mode Directly From dbx
Works Better With More Symbols and Debug Information
SIGSEGV and SIGALTSTACK Signals Are Restricted on x86 Platforms
Read From Array Out-of-Bounds (rob) Error
Read From Unallocated Memory (rua) Error
Read From Uninitialized Memory (rui) Error
Write to Array Out-of-Bounds Memory (wob) Error
Write to Read-Only Memory (wro) Error
Write to Unallocated Memory (wua) Error
Address in Register (air) Error
11. Debugging Multithreaded Applications
16. Debugging Fortran Using dbx
17. Debugging a Java Application With dbx
18. Debugging at the Machine-Instruction Level
19. Using dbx With the Korn Shell
To use runtime checking, enable the type of checking you want to use before you run the program.
To turn on memory use and memory leak checking, type:
(dbx) check -memuse
When memory use checking or memory leak checking is turned on, the showblock command shows the details about the heap block at a given address. The details include the location of the block’s allocation and its size. For more information, see showblock Command.
To turn on memory access checking only, type:
(dbx) check -access
To turn on memory leak, memory use, and memory access checking, type:
(dbx) check -all
For more information, see check Command.
To turn off runtime checking entirely, type:
(dbx) uncheck -all
For detailed information, see uncheck Command.
After turning on the types of runtime checking you want, run the program being tested, with or without breakpoints.
The program runs normally, but slowly because each memory access is checked for validity just before it occurs. If dbx detects invalid access, it displays the type and location of the error. Control returns to you (unless the dbx environment variable rtc_auto_continue is set to on (see Setting dbx Environment Variables.)
You can then issue dbx commands, such as where to get the current stack trace or print to examine variables. If the error is not a fatal error, you can continue execution of the program with the cont command. The program continues to the next error or breakpoint, whichever is detected first. For detailed information, see cont Command.
If the rtc_auto_continue environment variable is set to on, runtime checking continues to find errors, and keeps running automatically. It redirects errors to the file named by the dbx environment variable rtc_error_log_file_name. (See Setting dbx Environment Variables.) The default log file name is /tmp/dbx.errlog.uniqueid.
You can limit the reporting of runtime checking errors using the suppress command. For detailed information, see suppress Command.
Below is a simple example showing how to turn on memory access and memory use checking for a program called hello.c.
% cat -n hello.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 char *hello1, *hello2; 6 7 void 8 memory_use() 9 { 10 hello1 = (char *)malloc(32); 11 strcpy(hello1, "hello world"); 12 hello2 = (char *)malloc(strlen(hello1)+1); 13 strcpy(hello2, hello1); 14 } 15 16 void 17 memory_leak() 18 { 19 char *local; 20 local = (char *)malloc(32); 21 strcpy(local, "hello world"); 22 } 23 24 void 25 access_error() 26 { 27 int i,j; 28 29 i = j; 30 } 31 32 int 33 main() 34 { 35 memory_use(); 36 access_error(); 37 memory_leak(); 38 printf("%s\n", hello2); 39 return 0; 40 } % cc -g -o hello hello.c % dbx -C hello Reading ld.so.1 Reading librtc.so Reading libc.so.1 Reading libdl.so.1 (dbx) check -access access checking - ON (dbx) check -memuse memuse checking - ON (dbx) run Running: hello (process id 18306) Enabling Error Checking... done Read from uninitialized (rui): Attempting to read 4 bytes at address 0xeffff068 which is 96 bytes above the current stack pointer Variable is ’j’ Current function is access_error 29 i = j; (dbx) cont hello world Checking for memory leaks... Actual leaks report (actual leaks: 1 total size: 32 bytes) Total Num of Leaked Allocation call stack Size Blocks Block Address ========== ====== ========== ======================================= 32 1 0x21aa8 memory_leak < main Possible leaks report (possible leaks: 0 total size: 0 bytes) Checking for memory use... Blocks in use report (blocks in use: 2 total size: 44 bytes Total % of Num of Avg Allocation call stack Size All Blocks Size ========== ==== ====== ====== ======================================= 32 72% 1 32 memory_use < main 12 27% 1 12 memory_use < main execution completed, exit code is 0
The function access_error() reads variable j before it is initialized. Runtime checking reports this access error as a Read from uninitialized (rui).
The function memory_leak() does not free the variable local before it returns. When memory_leak() returns, this variable goes out of scope and the block allocated at line 20 becomes a leak.
The program uses global variables hello1 and hello2, which are in scope all the time. They both point to dynamically allocated memory, which is reported as Blocks in use (biu).