要使用运行时检查,请在运行程序前启用要使用的检查类型。
(dbx) check -memuse |
启用了内存使用检查或内存泄漏检查时,showblock 命令将显示有关指定地址处堆块的详细信息。这些详细信息包括块分配的位置及其大小。有关更多信息,请参见showblock 命令。
(dbx) check -access |
(dbx) check -all |
有关更多信息,请参见check 命令。
(dbx) uncheck -all |
有关详细信息,请参见uncheck 命令。
在启用了所需类型的运行时检查之后,可运行所测试的程序(是否使用断点均可)。
程序正常运行,但速度很慢,因为每次进行内存访问前都要检查其有效性。如果 dbx 检测到无效访问,便会显示错误的类型和位置。控制权将交还给您(除非 dbx 环境变量 rtc_auto_continue 设置为 on,请参见设置 dbx 环境变量。)
然后便可发出 dbx 命令,例如执行 where 获取当前栈跟踪,或执行 print 检查变量。如果命令不是致命错误,可以使用 cont 命令继续执行程序。程序继续执行,直至遇到下一个错误或断点(无论先检测到哪一个)。有关详细信息,请参见cont 命令。
如果 rtc_auto_continue 环境变量设置为 on,则运行时检查会继续查找错误,并自动保持运行。它会将错误重定向到通过 dbx 环境变量 rtc_error_log_file_name 指定的文件。(请参见设置 dbx 环境变量。)缺省的日志文件名为 /tmp/dbx.errlog.uniqueid。
可以使用 suppress 命令限制报告运行时检查错误。有关详细信息,请参见suppress 命令。
下面的简单示例说明了如何对名为 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 |
函数 access_error() 在变量 j 被初始化前便读取它。运行时检查将此访问错误报告为从尚未初始化项读取 (rui)。
函数 memory_leak() 在其返回前没有释放变量 local。memory_leak() 返回时,此变量超出作用域,在第 20 行分配的块变为泄漏。
程序使用全局变量 hello1 和 hello2,这两个变量始终处于作用域内。它们都指向动态分配的内存,这种情况报告为使用的块 (biu)。