To use runtime checking, enable the type of checking you want to use.
To turn on the desired checking mode, start dbx with the -C option:
% dbx [-C] program_name
The -C flag forces early loading of the RTC library. When you start dbx without the -C option and then enable checking, the RTC library is loaded when you issue the next run command; that may cause reloading of the shared libraries needed by the program. Using the -C flag initially allows you to avoid reloading.
You must turn on the type of checking you want before you run the program.
To turn on memory use and memory leak checking:
(dbx) check -memuse
To turn on memory access checking only:
(dbx) check -access
To turn on memory leak, memory use, and memory access checking:
(dbx) check -all
(dbx) uncheck -all
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 dbxenv variable rtc_auto_continue is set to on). 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.
If rtc_auto_continue is set to on, RTC continues to find errors, and keeps running automatically. It redirects errors to the value of the dbxenv variable rtc_error_log_file_name.
You can limit the reporting of RTC errors using the suppress command. The program continues to the next error or breakpoint, whichever is detected first.
You can perform any of the usual debugging activities, such as setting breakpoints and examining variables. The cont command runs the program until another error or breakpoint is encountered or until the program terminates.
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 symbolic information for hello Reading symbolic information for rtld /usr/lib/ld.so.1 Reading symbolic information for librtc.so Reading symbolic information for libc.so.1 Reading symbolic information for 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. RTC reports this access error as a Read from uninitialized (rui).
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).