This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
RFC: procfs file descriptor leak patch
- From: Tom Tromey <tromey at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 28 Oct 2008 14:20:38 -0600
- Subject: RFC: procfs file descriptor leak patch
- Reply-to: tromey at redhat dot com
Here's the final file descriptor leak patch.
This one only touches procfs.c.
This does the usual cleanup transform, but it also corrects a number
of erroneous assumptions about the result of calls to open. In
particular, the result can be 0 on success. Of course, that would be
extremely weird in gdb, probably impossible -- but code like this is
confusing even if it can't be triggered. Also, there is one case
where the result of open is compared "== 0" and apparently this is
taken to mean an error occurred. This also fixes a potential memory
leak in load_syscalls.
I am sending this for completeness' sake. I don't have whatever
machines this patch might apply to. I just noticed these oddities
when reading the code, and thought I would point them out in patch
form.
Tom
2008-10-28 Tom Tromey <tromey@redhat.com>
* procfs.c (load_syscalls): Make a cleanup.
(open_procinfo_files): fd==0 is ok.
diff --git a/gdb/procfs.c b/gdb/procfs.c
index 248dd3a..d7b823f 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -627,7 +627,7 @@ open_procinfo_files (procinfo *pi, int which)
else
strcat (tmp, "/ctl");
fd = open_with_retry (tmp, O_WRONLY);
- if (fd <= 0)
+ if (fd < 0)
return 0; /* fail */
pi->ctl_fd = fd;
break;
@@ -636,7 +636,7 @@ open_procinfo_files (procinfo *pi, int which)
return 0; /* there is no 'as' file descriptor for an lwp */
strcat (tmp, "/as");
fd = open_with_retry (tmp, O_RDWR);
- if (fd <= 0)
+ if (fd < 0)
return 0; /* fail */
pi->as_fd = fd;
break;
@@ -646,7 +646,7 @@ open_procinfo_files (procinfo *pi, int which)
else
strcat (tmp, "/status");
fd = open_with_retry (tmp, O_RDONLY);
- if (fd <= 0)
+ if (fd < 0)
return 0; /* fail */
pi->status_fd = fd;
break;
@@ -670,13 +670,13 @@ open_procinfo_files (procinfo *pi, int which)
#ifdef PIOCTSTATUS /* OSF */
/* Only one FD; just open it. */
- if ((fd = open_with_retry (pi->pathname, O_RDWR)) == 0)
+ if ((fd = open_with_retry (pi->pathname, O_RDWR)) < 0)
return 0;
#else /* Sol 2.5, Irix, other? */
if (pi->tid == 0) /* Master procinfo for the process */
{
fd = open_with_retry (pi->pathname, O_RDWR);
- if (fd <= 0)
+ if (fd < 0)
return 0; /* fail */
}
else /* LWP thread procinfo */
@@ -690,7 +690,7 @@ open_procinfo_files (procinfo *pi, int which)
return 0; /* fail */
/* Now obtain the file descriptor for the LWP. */
- if ((fd = ioctl (process->ctl_fd, PIOCOPENLWP, &lwpid)) <= 0)
+ if ((fd = ioctl (process->ctl_fd, PIOCOPENLWP, &lwpid)) < 0)
return 0; /* fail */
#else /* Irix, other? */
return 0; /* Don't know how to open threads */
@@ -926,6 +926,7 @@ load_syscalls (procinfo *pi)
prsysent_t header;
prsyscall_t *syscalls;
int i, size, maxcall;
+ struct cleanup *cleanups;
pi->num_syscalls = 0;
pi->syscall_names = 0;
@@ -937,6 +938,7 @@ load_syscalls (procinfo *pi)
{
error (_("load_syscalls: Can't open /proc/%d/sysent"), pi->pid);
}
+ cleanups = make_cleanup_close (sysent_fd);
size = sizeof header - sizeof (prsyscall_t);
if (read (sysent_fd, &header, size) != size)
@@ -951,12 +953,10 @@ load_syscalls (procinfo *pi)
size = header.pr_nsyscalls * sizeof (prsyscall_t);
syscalls = xmalloc (size);
+ make_cleanup (free_current_contents, &syscalls);
if (read (sysent_fd, syscalls, size) != size)
- {
- xfree (syscalls);
- error (_("load_syscalls: Error reading /proc/%d/sysent"), pi->pid);
- }
+ error (_("load_syscalls: Error reading /proc/%d/sysent"), pi->pid);
/* Find maximum syscall number. This may not be the same as
pr_nsyscalls since that value refers to the number of entries
@@ -1010,8 +1010,7 @@ load_syscalls (procinfo *pi)
pi->syscall_names[callnum][size-1] = '\0';
}
- close (sysent_fd);
- xfree (syscalls);
+ do_cleanups (cleanups);
}
/* Function: free_syscalls