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
Turning On All Runtime 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 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 on a child process, you must have the dbx environment variable rtc_inherit set to on. By default, it is set to off. (See Setting dbx Environment Variables.)
dbx supports runtime checking of a child process if runtime checking is enabled for the parent and the dbx environment variable follow_fork_mode is set to child (see Setting dbx Environment Variables).
When a fork happens, dbx automatically performs runtime checking on the child. If the program calls exec(), the runtime checking settings of the program calling exec() are passed on to the program.
At any given time, only one process can be under runtime checking control. The following is an example.
% cat -n program1.c
1 #include <sys/types.h>
2 #include <unistd.h>
3 #include <stdio.h>
4
5 int
6 main()
7 {
8 pid_t child_pid;
9 int parent_i, parent_j;
10
11 parent_i = parent_j;
12
13 child_pid = fork();
14
15 if (child_pid == -1) {
16 printf("parent: Fork failed\n");
17 return 1;
18 } else if (child_pid == 0) {
19 int child_i, child_j;
20
21 printf("child: In child\n");
22 child_i = child_j;
23 if (execl("./program2", NULL) == -1) {
24 printf("child: exec of program2 failed\n");
25 exit(1);
26 }
27 } else {
28 printf("parent: child’s pid = %d\n", child_pid);
29 }
30 return 0;
31 } % cat -n program2.c
1
2 #include <stdio.h>
3
4 main()
5 {
6 int program2_i, program2_j;
7
8 printf ("program2: pid = %d\n", getpid());
9 program2_i = program2_j;
10
11 malloc(8);
12
13 return 0;
14 }
% % cc -g -o program1 program1.c
% cc -g -o program2 program2.c
% dbx -C program1
Reading symbolic information for program1
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
Reading symbolic information for libc_psr.so.1
(dbx) check -all
access checking - ON
memuse checking - ON
(dbx) dbxenv rtc_inherit on
(dbx) dbxenv follow_fork_mode child
(dbx) run
Running: program1
(process id 3885)
Enabling Error Checking... done
RTC reports first error in the parent, program1
Read from uninitialized (rui):
Attempting to read 4 bytes at address 0xeffff110
which is 104 bytes above the current stack pointer
Variable is ’parent_j’
Current function is main
11 parent_i = parent_j;
(dbx) cont
dbx: warning: Fork occurred; error checking disabled in parent
detaching from process 3885
Attached to process 3886
Because follow_fork_mode is set to child, when the fork occurs error checking is switched from the parent
to the child process
stopped in _fork at 0xef6b6040
0xef6b6040: _fork+0x0008: bgeu _fork+0x30
Current function is main
13 child_pid = fork();
parent: child’s pid = 3886
(dbx) cont
child: In child
Read from uninitialized (rui):
Attempting to read 4 bytes at address 0xeffff108
which is 96 bytes above the current stack pointer
RTC reports an error in the child
Variable is ’child_j’
Current function is main
22 child_i = child_j;
(dbx) cont
dbx: process 3886 about to exec("./program2")
dbx: program "./program2" just exec’ed
dbx: to go back to the original program use "debug $oprog"
Reading symbolic information for program2
Skipping ld.so.1, already read
Skipping librtc.so, already read
Skipping libc.so.1, already read
Skipping libdl.so.1, already read
Skipping libc_psr.so.1, already read
When the exec of program2 occurs, the RTC settings are inherited by program2 so access and memory use checking
are enabled for that process
Enabling Error Checking... done
stopped in main at line 8 in file "program2.c"
8 printf ("program2: pid = %d\n", getpid());
(dbx) cont
program2: pid = 3886
Read from uninitialized (rui):
Attempting to read 4 bytes at address 0xeffff13c
which is 100 bytes above the current stack pointer
RTC reports an access error in the executed program, program2
Variable is ’program2_j’
Current function is main
9 program2_i = program2_j;
(dbx) cont
Checking for memory leaks...
RTC prints a memory use and memory leak report for the process that exited while under RTC control, program2
Actual leaks report (actual leaks: 1 total size: 8
bytes)
Total Num of Leaked Allocation call stack
Size Blocks Block
Address
========== ====== ========== ====================================
8 1 0x20c50 main
Possible leaks report (possible leaks: 0 total size: 0
bytes)
execution completed, exit code is 0