This chapter describes how to use Memory Advisor with your debugger to find and correct memory access errors in your programs. To familiarize you with Memory Advisor's features, you will use a sample program to find and correct memory access errors in your programs.
Dynamic Memory Access Error Detection
Memory Access Error Reporting
The Demonstration Program
Compiling and Running the Demonstration Program
Building the Processed Demonstration Program
Running the Processed Demonstration Program
Running the Demonstration Program Under a Debugger
Finding the First Error
Finding the Second Error
Finding the Third Error
Finding the Fourth Error
The Memory Leak and Open File Descriptor Reports
Dynamic Memory Access Error Detection
Your distribution package includes the source code for a demonstration program called search. This program demonstrates Memory Advisor's memory access error detection capabilities. It reads a text file as input, then reads your keyboard for text-string patterns, and searches for each pattern in the text read from the file. It then prints the location in the file at which it found the pattern, or it prints a message indicating that it did not find the pattern. The files for the search program are in the $MA_HOME/examples/tutorial directory. See the README file in that directory for information on each file. When you use the search program to experiment with Memory Advisor, you will:
`We' found at pos 3
'the' found at pos 7
'fubar' not found
'America' found at pos 352
'quit' not found
MemAdvise: Warning [AccOutOfBounds,14]: An attempt was made to access data beyond the end of an allocated data section. The program attempted to write 121 bytes to location 0x80F38. That address is at offset 0 in the 120 byte data area that starts at location 0x80F38 (there is only room to write 120 bytes).This error message is a warning, which reports an error but does not stop program execution. The error's mnemonic class and numeric code are inside the square brackets. In this case, the mnemonic class is AccOutOfBounds (access out of bounds), which applies to several different types of errors. The number 14 identifies the specific error code. A description of the error follows the error code. Chapter 11, Error Messages, contains the full list of error messages.
This problem was detected at the following location: strcpy() [string.o] main() [search.c:160] This problem is *probably* associated with a 120 byte data area allocated on the 5th call to malloc() which returned 0x80F38. The context of the call to malloc() was as follows: malloc() [intercept.o] main() [search.c:159]
Memory Advisor produces the following leak and open file descriptor reports:
MemAdvise: Info [Info,91]: Searching for leaks (this may take a while)...
****************** MemAdvise: List of Memory Leaks ******************
Data Which Number Total Data
Address Location Call Leaks Leaked
-------- --------------------------------- ------ ------ ----------
0x080F38 main( [search.c:159] 5th 1 120
0x080FD8 main() [search.c:164] 6th 2 600
0x081418 initnext() [search.c:40] 9th 5 21
search() [search.c:91]
main() [search.c:182]
************* MemAdvise: List of Open File Descriptors **************
FD: 5 "Preamble"
Opened by (the 1st call to) open()
Called from: main() [search.c:148]
(2) stop in MaStopNow you can run the program, using the same input file that you used before:
MemAdvise: Warning [AccOutOfBounds,14]: An attempt was made to access data beyond the end of an allocated data section. The program attempted to write 121 bytes to location 0x80F38. That address is at offset 0 in the 120 byte data area that starts at location 0x80F38 (there is only room to write 120 bytes). This problem was detected at the following location: strcpy() [string.o] main() [search.c:160] This problem is *probably* associated with a 120 byte data area allocated on the 5th call to malloc() which returned 0x80F38. The context of the call to malloc() was as follows: malloc() [intercept.o] main() [search.c:159] stopped in MaStop at 0x18700 MaStop: sethi %hi(0x68c00), %o0 Current function is main 160 strcpy(buf, line);
154 while( (len = read(fd, line, BUFLEN)) > 0 )
155 {
156 line[len] = '\0';
157 if( buf == (char *)NULL )
158 {
159 buf = (char *)malloc(strlen(line));
160 strcpy(buf, line);
161 }
162 else
163 {
164 p = (char *)malloc(strlen(buf)+strlen(line));
165 strcpy(p, buf);
166 strcat(p, line);
167 buf = p;
168 }
169 }
MemAdvise: Warning [AccOutOfBounds,14]: An attempt was made to access data beyond the end of an allocated data section. The program attempted to read 121 bytes from location 0x80F38. That address is at offset 0 in the 120 byte data area that starts at location 0x80F38 (there is only room to read 120 bytes). This problem was detected at the following location: strlen() [string.o] main() [search.c:164] This problem is *probably* associated with a 120 byte data area allocated on the 5th call to malloc() which returned 0x80F38. The context of the call to malloc() was as follows: malloc() [intercept.o] main() [search.c:159] stopped in MaStop at 0x18700 MaStop: sethi %hi(0x68c00), %o0 Current function is main 164 p = (char *)malloc(strlen(buf)+strlen(line));
MemAdvise: Warning [AccOutOfBounds,14]: An attempt was made to access data beyond the end of an allocated data section. The program attempted to write 241 bytes to location 0x97248. That address is at offset 0 in the 240 byte data area that starts at location 0x97248 (there is only room to write 240 bytes). This problem was detected at the following location: strcat() [string.o] main() [search.c:166] This problem is *probably* associated with a 240 byte data area allocated on the 6th call to malloc() which returned 0x97248. The context of the call to malloc() was as follows: malloc() [intercept.o] main() [search.c:164] stopped in MaStop at 0x47070 MaStop: sethi %hi(0x84800), %o0 Current function is main 166 strcat(p, line);
MemAdvise: Warning [AccOutOfBounds,14]: An attempt was made to access data beyond the end of an allocated data section. The program attempted to write 8 bytes to location 0x81430. That address is at offset 0 in the 2 byte data area that starts at location 0x81430 (there is only room to write 2 bytes). This problem was detected at the following location: memset() [memext.o] initnext() [search.c:41] search() [search.c:91] main() [search.c:182] This problem is *probably* associated with a 2 byte data area allocated on the 9th call to malloc() which returned 0x81430. The context of the call to malloc() was as follows: malloc() [intercept.o] initnext() [search.c:40] search() [search.c:91] main() [search.c:182] stopped in MaStop at 0x18708 MaStop: sethi %hi(0x68c00), %o0 Current function is initnext 41 memset(next, '\0', pat_len * sizeof(int));
MemAdvise: Warning [AccOutOfBounds,14]: An attempt was made to access data beyond the end of an allocated data section. The program attempted to write 4 bytes to location 0x81430. That address is at offset 0 in the 2 byte data area that starts at location 0x81430 (there is only room to write 2 bytes). This problem was detected at the following location: initnext() [search.c:46] search() [search.c:91] main() [search.c:182] This problem is *probably* associated with a 2 byte data area allocated on the 9th call to malloc() which returned 0x81430. The context of the call to malloc() was as follows: malloc() [intercept.o] initnext() [search.c:40] search() [search.c:91] main() [search.c:182] stopped in MaStop at 0x18708 MaStop: sethi %hi(0x68c00), %o0 Current function is initnext 46 next[0] = -1;
39 pat_len = strlen(pattern);
40 next = (int *)malloc(pat_len * sizeof(char));
41 memset(next, '\0', pat_len * sizeof(int));
42
43 /*
44 * Initialize locations, coalescing repeated characters
45 */
46 next[0] = -1;
47 for( i = 0, j = -1; i < pat_len; i++, j++ )
48 {
49 while( (j >= 0) && (pattern[i] != pattern[j]) )
50 {
51 j = next[j];
52 }
53 next[i] = j;
54 }
(2) stop in MaStop
Running: search.madv Preamble
'We' found at pos 3
...
MemAdvise: Warning [AccFreed,16]: An attempt was made to access data that has been freed. The program attempted to read 1 byte from location 0x81298. That address is located within the freed 362 byte data area that starts at location 0x81298. This problem was detected at the following location: strlen() [string.o] search() [search.c:85] main() [search.c:182] This problem is *probably* associated with a 362 byte data area allocated on the 8th call to malloc() which returned 0x81298. The context of the call to malloc() was as follows: malloc() [intercept.o] main() [search.c:164] This block was freed on the 4th call to free() in the following context: free() [intercept.o] main() [search.c:198] stopped in MaStop at 0x18700 MaStop: sethi %hi(0x68c00), %o0 Current function is search 85 buf_len = strlen(buffer);
71 search(pattern, buffer)
72 char * pattern;
73 char * buffer;
74 {
75 int buf_len;
76 int i;
77 int j;
78 int * next;
79 int pat_len;
80 int rtn = -1;
81
82 /*
83 * Get buffer and pattern sizes
84 */
85 buf_len = strlen(buffer);
86 pat_len = strlen(pattern);
171 while( (len = read(0, line, BUFLEN)) > 0 )
172 {
173 line[len-1] = '\0';
174 p = line;
175 while( p != (char *)NULL )
176 {
177 q = (char *)strchr(p, '\n');
178 if( q != (char *)NULL )
179 {
180 *q = '\0';
181 }
182 if( (ret = search(p, buf)) != -1 )
183 {
184 sprintf(out, "'%s' found at pos %d\n",
185 p, ret);
186 write(1, out, strlen(out));
187 }
188 else
189 {
190 sprintf(out, "'%s' not found\n", p);
191 write(1, out, strlen(out));
192 }
193 p = q;
194 if( p != (char *)NULL )
195 {
196 p++;
197 }
198 free(buf);
199 }
200 }
Running: search.madv Preamble
'We' found at pos 3
'the' found at pos 7
'fubar' not found
'America' found at pos 352
'quit' not found
MemAdvise: Info [Info,91]: Searching for leaks (this may take a while).....
Reading symbol table...Sun format...............................Done
****************** MemAdvise: List of Memory Leaks ******************
Data Which Number Total Data
Address Location Call Leaks Leaked
-------- --------------------------------- ------ ------ ----------
20001B18 malloc() 1st 1 120
main() [search.c:159]
20001BB8 malloc() 2nd 2 600
main() [search.c:164]
20002038 malloc() 6th 3 8
initnext() [search.c:40]
search() [search.c:91]
main() [search.c:182]
************* MemAdvise: List of Open File Descriptors **************
FD: 5 "Preamble"
Opened by (the 1st call to) open()
Called from: main() [search.c:148]
Copyright ©1996 PLATINUM technology, inc. All rights reserved.