Re: memory leaks from calls to opendir and fopen
"Saurabh Desai" <[email protected]> Wed, 24 Jul 2002 18:17:30 -0600
| Newsgroups | gmane.linux.ngpt.user |
|---|---|
| Message-ID | <[email protected]> |
The pthread mutex created by certain glibc functions didn't get freed properly by ngpt and that causes memory leaks. Here is a patch for ngpt-2.0.0 release to fix this problem. Thank you for providing a testcase and reporting this bug. (See attached file: ngpt-2.0.0-1.diff) Thanks, - - - - - Saurabh Desai POSIX Threading for Linux IBM Linux Technology Center e-mail: [email protected] OR [email protected] phone: 512-838-2655, T/L: 678-2655 http://oss.software.ibm.com/developerworks/opensource/pthreads Nathan Falk/Poughkeepsie/IBM@[email protected] on 07/24/2002 10:29:49 AM Sent by: [email protected] To: [email protected] cc: Subject: [pthreads-users] memory leaks from calls to opendir and fopen I noticed considerable growth in a daemon (so much that the system ran out of virtual memory after the daemon was running for about a day and a half), and tried to track it down. I didn't have much like finding memory tools that would work with my app. I suspect that's partly due to ngpt. What I ended up doing was writing the get_vsize() function below to take snapshots of how much memory my process has allocated. I narrowed the leaks down to calls to opendir() and fopen() (there may be others). Thinking there might be a bug in glibc (but doubting it), I wrote a simple, stand-alone program to demonstrate the problem. I couldn't recreate it. Then I thought to link in pthreads, and that's when the test program exhibited the same behavior as my app. I brought the source over to a vanilla RH 7.2 system (2.4.7 kernel, LinuxThreads) and re-compiled it. No growth. I'm not sure where to go from here. It seems like ngpt is the culprit, and it seems to be from memory allocated when open() is called. Compiling and running the program below (be sure to use -lpthread) on a system with ngpt versus a system without ngpt will demonstrate the growth on the system with ngpt. #include <stdio.h> #include <fcntl.h> #include <dirent.h> #include <pthread.h> unsigned int get_vsize() { int procfile; char path_to_procfile[16]; /* just has to hold "/proc/nnnnn/stat" */ char stat_buffer[256]; /* should be enough */ int my_pid = getpid(); int vsize_pos = 22; /* the field we want is 22nd */ int ndx; unsigned int vsize; char *ptr = NULL; sprintf(path_to_procfile, "/proc/%d/stat", my_pid); procfile = open(path_to_procfile, O_RDONLY); if (!procfile) return(0); ndx = read(procfile, stat_buffer, sizeof(stat_buffer)-1); stat_buffer[ndx] = '\0'; close(procfile); ptr = &stat_buffer[0]; printf("%s\n", stat_buffer); while (vsize_pos > 0) { ptr = strchr(ptr, ' '); ptr++; if (!ptr) return(0); /* printf("%d: %s\n", vsize_pos, ptr); */ vsize_pos--; } sscanf(ptr, "%u", &vsize); /* printf("%u\n", vsize); */ return vsize; } int main() { unsigned int vsize; DIR *dirp = NULL; int count = 20; while(count > 0) { vsize = get_vsize(); printf("vsize (1) = %u\n", vsize); dirp = opendir("/proc"); if (!dirp) return(0); vsize = get_vsize(); printf("vsize (2)= %u\n", vsize); closedir(dirp); vsize = get_vsize(); printf("vsize (3) = %u\n", vsize); sleep(15); count--; } /* end while */ } Thanks, Nate Falk RS/6000 SP Workload Management/LoadLeveler 845-433-8162 (T/L: 293-8162) _______________________________________________ pthreads-users mailing list [email protected] http://www-124.ibm.com/developerworks/oss/mailman/listinfo/pthreads-users
ngpt-2.0.0-1.diff
(application/octet-stream, 870 B)
diff -Naur ngpt-2.0.0/pthread.c ngpt-2.0.0-destroy/pthread.c
--- ngpt-2.0.0/pthread.c Fri Jun 21 12:18:32 2002
+++ ngpt-2.0.0-destroy/pthread.c Wed Jul 24 16:50:43 2002
@@ -979,10 +979,15 @@
return EINVAL;
pth_acquire_lock(&((pth_mutex_t *)*mutex)->mx_lock);
if (((pth_mutex_t *)*mutex)->mx_state & PTH_MUTEX_LOCKED) {
+ if (((pth_mutex_t *)*mutex)->mx_owner == pth_get_current()) {
+ pth_release_lock(&((pth_mutex_t *)*mutex)->mx_lock);
+ pthread_mutex_unlock(mutex);
+ } else {
+ pth_release_lock(&((pth_mutex_t *)*mutex)->mx_lock);
+ return EBUSY;
+ }
+ } else
pth_release_lock(&((pth_mutex_t *)*mutex)->mx_lock);
- return EBUSY;
- }
- pth_release_lock(&((pth_mutex_t *)*mutex)->mx_lock);
for (i = 0; i < mutex_index + 1; i++) {
if ((pth_mutex_t *)*mutex == (pth_mutex_t *)&(init_mutex[i]))
return OK;